diff --git a/src/backend/vector/avx2/constants.rs b/src/backend/vector/avx2/constants.rs index ab1103639..c5177ba7e 100644 --- a/src/backend/vector/avx2/constants.rs +++ b/src/backend/vector/avx2/constants.rs @@ -1186,3 +1186,1095 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf ), ])), ]); + +/// Odd multiples of `[2^128]B`. +pub(crate) static B_SHL_128_ODD_LOOKUP_TABLE: NafLookupTable8 = NafLookupTable8([ + CachedPoint(FieldElement2625x4([ + u32x8::new( + 1202713, 23511963, 26450367, 2075944, 12480538, 51064074, 24051012, 3139797, + ), + u32x8::new( + 676325, 60800292, 22738320, 18667793, 50389667, 24163489, 25823490, 10883811, + ), + u32x8::new( + 40000904, 15263588, 33286424, 6452826, 37318261, 16677611, 5442535, 33234239, + ), + u32x8::new( + 52558315, 63939157, 22867448, 21136749, 3499555, 4212004, 20445650, 43815, + ), + u32x8::new( + 47440487, 36697860, 28401748, 33362633, 50861846, 41313226, 33355406, 30189395, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 45224205, 20339827, 12646048, 25485820, 666643, 16188805, 18030487, 14373716, + ), + u32x8::new( + 5965700, 8577142, 29369776, 5950524, 60103074, 48146224, 19895908, 12868833, + ), + u32x8::new( + 14677192, 1786906, 5574650, 20854042, 63606665, 47203407, 4006978, 13876579, + ), + u32x8::new( + 45434162, 42137902, 5650755, 11800777, 30943004, 8723487, 1745306, 29857150, + ), + u32x8::new( + 29123252, 4201817, 15241100, 15325161, 22515105, 20637010, 31156446, 33520525, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 17638802, 54689176, 795416, 15174319, 47950790, 49879249, 6261594, 1439118, + ), + u32x8::new( + 51387039, 44816447, 13137195, 18136438, 36898231, 25714100, 32738093, 19696286, + ), + u32x8::new( + 31432290, 3982387, 18938092, 27132863, 61439065, 25380757, 17167783, 6575799, + ), + u32x8::new( + 8656109, 24600455, 2926958, 6859212, 55574299, 56858561, 12966, 30900971, + ), + u32x8::new( + 901833, 36201180, 22257782, 17956623, 25773927, 10569302, 10611293, 2054237, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 36608031, 40108309, 3655472, 11234953, 44550414, 25744615, 18793244, 24443833, + ), + u32x8::new( + 55540921, 14197700, 5980621, 21001838, 43440222, 56398833, 9709702, 23238411, + ), + u32x8::new( + 13280439, 35189624, 3564956, 12738464, 54128426, 54086778, 17390035, 27749654, + ), + u32x8::new( + 49297913, 34806031, 22169195, 27639569, 58231879, 62694749, 12706395, 29395098, + ), + u32x8::new( + 34564717, 21315454, 559952, 6325166, 13675875, 54497732, 16822697, 17492982, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 30096178, 27657595, 24851243, 19159578, 3644699, 22841495, 1168495, 15222978, + ), + u32x8::new( + 37457236, 44696233, 2228119, 13920914, 1048762, 41748619, 25967453, 2157477, + ), + u32x8::new( + 31527418, 48070261, 21957065, 18305308, 30965400, 37678864, 22934935, 8897856, + ), + u32x8::new( + 23718919, 51622490, 18677567, 31717632, 30158313, 61256017, 21322895, 16831447, + ), + u32x8::new( + 34458636, 50196710, 7015968, 1734334, 60299148, 44876204, 33087525, 14734786, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 7240644, 18561144, 12513685, 26058393, 48846226, 56496844, 22261080, 11956695, + ), + u32x8::new( + 9659209, 64825873, 17671582, 11630474, 271845, 17469690, 20087719, 26569118, + ), + u32x8::new( + 48493387, 62609320, 27253290, 14181566, 2062456, 42231632, 29932516, 21859944, + ), + u32x8::new( + 20963120, 5053097, 7646437, 19974189, 30068660, 15108197, 28809617, 32005012, + ), + u32x8::new( + 43696126, 24073908, 3312233, 33141414, 22062707, 45016066, 19911181, 500237, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 45279218, 52470214, 9064232, 26448567, 36956377, 4348204, 1798830, 10323464, + ), + u32x8::new( + 42597556, 19859656, 13299659, 4003171, 23362776, 37040149, 19550467, 4541745, + ), + u32x8::new( + 27765953, 7517094, 16788509, 17338660, 16846937, 5731194, 31563368, 26546870, + ), + u32x8::new( + 32665684, 11810011, 13221325, 15695521, 46951134, 23450266, 9906037, 10279382, + ), + u32x8::new( + 5629635, 27001813, 17493056, 18500771, 36625330, 2598618, 20212729, 10735886, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 20761558, 58414834, 6367797, 28056472, 41924109, 65490118, 9561685, 1010468, + ), + u32x8::new( + 36070622, 2280331, 32580867, 5980502, 11794534, 19696376, 3769661, 14349455, + ), + u32x8::new( + 33344559, 30509923, 7919614, 29944924, 47432191, 17992458, 2377051, 25464402, + ), + u32x8::new( + 42169869, 59471245, 31055110, 19315125, 20279140, 6525075, 27858332, 23025697, + ), + u32x8::new( + 36212645, 4340821, 30683405, 16816365, 65230998, 45239624, 8567501, 33389781, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 24980036, 60524959, 12388909, 9551041, 51303941, 63991903, 26053055, 1636609, + ), + u32x8::new( + 33505857, 52007289, 20602842, 13985017, 63663983, 64719335, 7759238, 9810995, + ), + u32x8::new( + 390111, 46009991, 29410788, 2106086, 55207616, 10852165, 17698640, 19977761, + ), + u32x8::new( + 46951576, 35974808, 1551813, 13136335, 29226352, 1151181, 6767790, 11750838, + ), + u32x8::new( + 32837000, 60964112, 32301252, 14462335, 61581797, 62451716, 19639704, 23625444, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 34212149, 54588726, 24133457, 4005064, 48175145, 30542840, 7896924, 32908545, + ), + u32x8::new( + 18307576, 33480121, 28124199, 27929181, 40407028, 9247148, 9271042, 3270299, + ), + u32x8::new( + 33106625, 44123705, 28130557, 14865700, 34048473, 16795889, 13308170, 2332251, + ), + u32x8::new( + 50743801, 62020198, 9199092, 25834479, 46616746, 55573461, 13862884, 27557579, + ), + u32x8::new( + 8476107, 18667216, 4784729, 13797427, 14713885, 58009223, 27123991, 13939913, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 33497526, 27682970, 10729828, 17739505, 42771659, 61265808, 6967011, 6586749, + ), + u32x8::new( + 53817549, 60317071, 16861473, 3313466, 8033381, 13978456, 17247109, 7523745, + ), + u32x8::new( + 18877028, 2664571, 32245277, 16894215, 23932946, 23681448, 7729307, 21030441, + ), + u32x8::new( + 17005352, 35455121, 14627178, 17175787, 46883465, 8448726, 21168588, 2532457, + ), + u32x8::new( + 32701115, 27016564, 4340846, 20732782, 31547112, 17353261, 11627350, 32838935, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 1417179, 14655146, 20541992, 4380187, 27712579, 65209749, 2672221, 16655039, + ), + u32x8::new( + 63734525, 38904168, 768336, 18679881, 16570237, 54755617, 22479368, 28140024, + ), + u32x8::new( + 45754947, 10233197, 123257, 15158650, 271852, 12159559, 1260608, 11589332, + ), + u32x8::new( + 38824250, 8906338, 6194167, 18461303, 25122865, 48340531, 10803061, 31935635, + ), + u32x8::new( + 59665789, 11244968, 2179709, 32997220, 15749599, 60912606, 18162392, 23568703, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 28379921, 11380886, 25319719, 16502966, 21394384, 40722839, 30197998, 33117987, + ), + u32x8::new( + 10192109, 268787, 31162995, 29686366, 55981678, 5876270, 17725904, 18499617, + ), + u32x8::new( + 35459261, 41203074, 2024306, 24666516, 62332715, 9570084, 18198683, 32269884, + ), + u32x8::new( + 3762477, 56229320, 19264596, 3154423, 28529044, 3195243, 23350447, 20396906, + ), + u32x8::new( + 37814853, 4683952, 27787932, 10255539, 14292596, 30981550, 24397040, 19844972, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 33740083, 57599876, 24145876, 19738875, 46094452, 64497096, 28402184, 9651029, + ), + u32x8::new( + 10358954, 8392849, 17235237, 28983188, 28470300, 8548909, 15823647, 2771893, + ), + u32x8::new( + 24001310, 20422382, 588983, 27243301, 63465532, 1403482, 36033, 6841885, + ), + u32x8::new( + 1870546, 36351175, 16074757, 21386007, 23060755, 19814302, 16411956, 24418438, + ), + u32x8::new( + 30631851, 16765945, 3822791, 30162475, 34581963, 56548616, 3231408, 22411556, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 30507776, 60118185, 10678608, 2899266, 66201641, 61108283, 17122188, 8795603, + ), + u32x8::new( + 60955380, 52059736, 23755436, 27373682, 27588269, 10698961, 21191079, 10315293, + ), + u32x8::new( + 29768152, 30023400, 8070660, 14111281, 61473605, 34166073, 24717429, 7059216, + ), + u32x8::new( + 55898448, 49573341, 19994621, 3280757, 20045600, 28073089, 19650384, 25463315, + ), + u32x8::new( + 60018397, 2763924, 31285808, 22985478, 53325517, 66857464, 32291910, 30673777, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 63245842, 54636441, 21534524, 15818811, 56014082, 62626353, 17515134, 21475665, + ), + u32x8::new( + 13098799, 20303125, 32125599, 12258626, 2562646, 64463150, 25034353, 11318659, + ), + u32x8::new( + 13964511, 3467590, 22431142, 26670424, 56657760, 56692600, 18554627, 3394559, + ), + u32x8::new( + 60616579, 42562542, 19361411, 6661674, 41753812, 18721086, 24261265, 8041236, + ), + u32x8::new( + 30169485, 13863019, 17762237, 953352, 4078138, 17082901, 13065655, 29784599, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 31096991, 19266978, 17121040, 18533911, 4984137, 11507570, 30162567, 31829749, + ), + u32x8::new( + 31337701, 51682068, 8821948, 2438000, 36533102, 19875200, 13842500, 10228547, + ), + u32x8::new( + 48090742, 26014556, 7042561, 11130045, 41024425, 4955043, 22591033, 24502117, + ), + u32x8::new( + 14458003, 56123827, 8848341, 28179365, 59979625, 49732164, 4362099, 5881604, + ), + u32x8::new( + 65557712, 38779293, 27803865, 24697374, 22273186, 54455665, 32568162, 2587260, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 11789100, 8551018, 19578432, 9660837, 18920686, 7272934, 28901216, 2048842, + ), + u32x8::new( + 48114573, 45319557, 22691970, 33267816, 64444395, 38766810, 21338247, 30803744, + ), + u32x8::new( + 58012037, 32318692, 1911908, 25445398, 38157371, 7599412, 32342450, 17721941, + ), + u32x8::new( + 9252418, 25321940, 18940434, 29521369, 14527465, 7300518, 1012262, 11234387, + ), + u32x8::new( + 63019959, 26703121, 6750343, 25780754, 27136459, 54614709, 21503346, 15926894, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 9656744, 46803029, 17955074, 7884583, 22071622, 60565706, 24356824, 3323962, + ), + u32x8::new( + 40828643, 57978119, 19368048, 9076816, 35876208, 36834943, 22685076, 19975920, + ), + u32x8::new( + 58365030, 25786155, 14165157, 1004548, 9437136, 17225497, 23033301, 22901949, + ), + u32x8::new( + 46884807, 61092443, 29390058, 25910857, 21389494, 6156033, 24013804, 19150436, + ), + u32x8::new( + 57445249, 8889973, 22224933, 22279223, 8259946, 64401320, 24636631, 1697840, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 45171065, 18004063, 14398385, 32775153, 56158196, 49316204, 15500891, 9714992, + ), + u32x8::new( + 59749529, 63086740, 27690399, 15503332, 40292804, 4743302, 3159313, 20164580, + ), + u32x8::new( + 4385700, 36693025, 9080329, 4049984, 38514725, 26030330, 980455, 31756365, + ), + u32x8::new( + 28969025, 47478750, 23928096, 18094385, 23454607, 41907220, 33142384, 24546186, + ), + u32x8::new( + 37414323, 2224499, 16386069, 30435885, 48340249, 21267971, 5905788, 32606574, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 2447047, 5857524, 27687945, 4446528, 25389100, 34563313, 5771556, 21911515, + ), + u32x8::new( + 48870626, 66708318, 29736178, 947884, 38822986, 54223450, 14554319, 29579507, + ), + u32x8::new( + 19481829, 32339152, 25981493, 18293708, 61905770, 17808980, 25627410, 28645320, + ), + u32x8::new( + 64718914, 57838337, 18737779, 27461009, 20179202, 37984113, 12394396, 11239684, + ), + u32x8::new( + 60530226, 20680440, 20084439, 28896529, 21796112, 11884034, 5587545, 13891457, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 11173706, 47600681, 4058764, 30788398, 23459691, 42965986, 2545437, 5453358, + ), + u32x8::new( + 51146695, 35771488, 31752434, 6445177, 64053828, 37108760, 17875681, 4379392, + ), + u32x8::new( + 8036991, 30113569, 9845482, 19701229, 22550342, 58892450, 32810201, 2514611, + ), + u32x8::new( + 23012936, 23541517, 4292755, 18082419, 27186336, 29645371, 24421192, 27346185, + ), + u32x8::new( + 20796537, 13327774, 18213752, 2117497, 51321843, 58843185, 11028401, 26548634, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 49174899, 45204811, 7927243, 895782, 39011852, 65721303, 11218296, 15442529, + ), + u32x8::new( + 12360383, 61573791, 24403116, 10788944, 26885663, 18744098, 33452170, 22915303, + ), + u32x8::new( + 44417297, 49571529, 25662854, 21632722, 2925678, 37117284, 4191160, 13255144, + ), + u32x8::new( + 49099911, 47697197, 17460889, 32530041, 29005127, 34586394, 29648208, 3731289, + ), + u32x8::new( + 52279203, 33040767, 21368154, 5625970, 24444273, 55229780, 6059524, 13177754, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 17135300, 6757241, 16935358, 28368630, 63229132, 44652060, 27612398, 1848188, + ), + u32x8::new( + 30075704, 32738984, 23014830, 19399546, 26408665, 11891930, 13026846, 26739780, + ), + u32x8::new( + 4264513, 26436592, 9634678, 13880850, 9399291, 49894263, 30732912, 24042553, + ), + u32x8::new( + 2207933, 45979740, 28836001, 9846618, 17454599, 47600463, 26020153, 3916668, + ), + u32x8::new( + 48013041, 64234858, 21851586, 23776914, 7625493, 45832009, 18105844, 25333285, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 20525017, 61432182, 14925850, 13623149, 29080267, 42876031, 24133048, 7203134, + ), + u32x8::new( + 55157939, 28643575, 14688135, 21313147, 47199286, 6205142, 30605439, 10109355, + ), + u32x8::new( + 6567469, 36228723, 528227, 23628904, 5509672, 10614740, 26446582, 19358942, + ), + u32x8::new( + 63491985, 65392756, 24258722, 29170161, 39496288, 6546742, 2816398, 13155706, + ), + u32x8::new( + 41802008, 62385585, 14027656, 12392821, 36364440, 46296646, 9482451, 30947729, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 59561040, 4944439, 24816969, 21459119, 55854979, 59193943, 611577, 19083758, + ), + u32x8::new( + 60592827, 14952435, 28632778, 30328798, 28801735, 41312928, 32332051, 31110407, + ), + u32x8::new( + 55523473, 45922574, 11661673, 18377319, 54263659, 43508867, 29240284, 11863593, + ), + u32x8::new( + 44110262, 60674813, 3778889, 32652598, 45377952, 55932104, 13990777, 31615617, + ), + u32x8::new( + 739231, 52703625, 4589280, 19050887, 21038508, 57672950, 17194427, 32255155, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 51921763, 5303556, 18681671, 14862672, 27607095, 45234399, 8931487, 944835, + ), + u32x8::new( + 58012063, 41667319, 13440179, 32368940, 66872717, 8917965, 15584781, 2613579, + ), + u32x8::new( + 10576998, 42267788, 2415005, 12022604, 9148296, 42810037, 21528343, 16976235, + ), + u32x8::new( + 15964384, 9905761, 6785089, 25449430, 56538094, 58391413, 18118178, 7906376, + ), + u32x8::new( + 32611857, 45998038, 33046657, 26980584, 57104656, 43721295, 16705783, 15212552, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 27530550, 47750443, 1795958, 26919198, 57497448, 45692311, 25338778, 9666234, + ), + u32x8::new( + 4607779, 12252323, 6570122, 1852831, 10337928, 66465345, 5664707, 5868691, + ), + u32x8::new( + 65249507, 31519072, 26054049, 6788251, 19581824, 23868278, 225039, 28208105, + ), + u32x8::new( + 22167241, 12754068, 10733234, 5020175, 52224123, 56448942, 4504996, 14812381, + ), + u32x8::new( + 50004252, 58406077, 14129554, 27711982, 23125304, 62767417, 21098030, 16677065, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 23044467, 7603380, 12803491, 29961173, 64233593, 26164559, 27401459, 22051837, + ), + u32x8::new( + 65302518, 11153943, 1719742, 22254644, 62259947, 48470343, 15132758, 1097717, + ), + u32x8::new( + 39848880, 36642881, 28712046, 6534533, 39409625, 56747059, 10570178, 3741215, + ), + u32x8::new( + 19888330, 66483608, 25485605, 31092810, 27172806, 28912297, 2147913, 12654314, + ), + u32x8::new( + 45731897, 19675312, 2814889, 11293692, 392195, 58199359, 8708142, 28335712, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 25327590, 52438663, 25343325, 11991833, 63530238, 2514287, 8935401, 16124535, + ), + u32x8::new( + 61847470, 17619740, 17841558, 31201219, 34690247, 53765260, 30575405, 14771832, + ), + u32x8::new( + 45638294, 63198269, 1392698, 26737796, 9983384, 50156368, 17640934, 19731986, + ), + u32x8::new( + 30833685, 54820606, 19267198, 26899524, 60524836, 47024277, 27043084, 8105737, + ), + u32x8::new( + 58034751, 65627774, 3796221, 5810803, 65427572, 16799484, 20624166, 33153105, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 17123334, 26412533, 19089608, 776674, 48448877, 35254919, 343027, 740283, + ), + u32x8::new( + 38954162, 50544360, 11603312, 15644081, 53071340, 12367875, 23878835, 31976957, + ), + u32x8::new( + 7069276, 58925511, 28024740, 33375805, 3936816, 27064665, 22102426, 15586423, + ), + u32x8::new( + 40718524, 61798484, 23791208, 13773286, 8059995, 31204878, 28074211, 6527596, + ), + u32x8::new( + 60021034, 4675402, 12928400, 17397560, 40210729, 15996099, 8703535, 10754253, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 9163289, 39486883, 29992449, 26089016, 43186192, 3307127, 21124047, 7966269, + ), + u32x8::new( + 34147939, 38447583, 17094069, 19414441, 14764423, 34204698, 5105868, 5246, + ), + u32x8::new( + 12334437, 30864922, 28744897, 6996149, 643292, 10792190, 3097720, 1323346, + ), + u32x8::new( + 47671504, 42530504, 9828619, 25069925, 24980076, 35374119, 22360548, 18672418, + ), + u32x8::new( + 1379213, 2299607, 19994595, 29040289, 48308861, 58487476, 17465321, 16736338, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 24214680, 50071178, 13093683, 730433, 38265243, 3420411, 25648763, 9985252, + ), + u32x8::new( + 22961595, 1307554, 22828628, 31024851, 59513558, 45026959, 885650, 19148710, + ), + u32x8::new( + 20853832, 23367804, 2611440, 12857920, 26206370, 833304, 1101863, 10986572, + ), + u32x8::new( + 13316369, 41402894, 28258933, 9727894, 45554697, 46854412, 31178785, 12072382, + ), + u32x8::new( + 32116537, 18554757, 6507312, 13640082, 19985017, 23313173, 3109934, 18254583, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 63075358, 35241782, 1826753, 6400177, 2305846, 19412727, 13567689, 21710580, + ), + u32x8::new( + 23263749, 53199794, 7691190, 16300730, 40289899, 55526259, 19935951, 32637368, + ), + u32x8::new( + 17352933, 38814185, 15317980, 15934407, 62102845, 32264093, 24579435, 2865475, + ), + u32x8::new( + 36029370, 56742253, 12001541, 20112695, 53020168, 22523780, 2354718, 24202781, + ), + u32x8::new( + 47783192, 33094336, 13868478, 12575123, 33505449, 44073012, 25573922, 4463374, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 43150962, 42998782, 25865522, 16374810, 36183007, 9332631, 24935933, 26622515, + ), + u32x8::new( + 32849309, 66829255, 28406299, 23890371, 13119795, 18473582, 22092527, 26093417, + ), + u32x8::new( + 22291646, 24752811, 19168332, 19341261, 5639303, 45291762, 2780405, 20167530, + ), + u32x8::new( + 11418897, 29058216, 25946282, 15146797, 36621751, 29929764, 2646958, 23504075, + ), + u32x8::new( + 63011265, 36735183, 27154309, 33272122, 38480028, 38620004, 12007539, 16529832, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 42018926, 29015701, 11979286, 1497143, 50233849, 5274635, 30276858, 28629554, + ), + u32x8::new( + 57937145, 65517439, 29889325, 550310, 62255008, 45513490, 10133169, 16222557, + ), + u32x8::new( + 2909509, 59047540, 3946439, 6103810, 65014997, 53458142, 27739369, 19673804, + ), + u32x8::new( + 5395188, 53142908, 2495428, 1429913, 21844627, 11119458, 789604, 1802320, + ), + u32x8::new( + 53551821, 55406303, 17294511, 29158297, 47367534, 22469567, 11196075, 14290676, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 61340834, 33622672, 6255716, 15580455, 51157990, 13805974, 27628968, 17669226, + ), + u32x8::new( + 15257526, 5954759, 19014142, 9846394, 33513899, 29281364, 26200029, 30969813, + ), + u32x8::new( + 15707637, 53629705, 4181826, 19904627, 5442821, 51540352, 10521021, 18666569, + ), + u32x8::new( + 12629931, 30329078, 24788750, 19086902, 65581843, 28820526, 32691823, 5993796, + ), + u32x8::new( + 26764052, 8049597, 6421682, 1881853, 50546821, 59120823, 11465157, 13751530, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 18196218, 47760675, 20788011, 17038428, 30337607, 40247917, 23118677, 28819749, + ), + u32x8::new( + 62688424, 64216625, 9549723, 32697152, 6868442, 20058580, 7345801, 861526, + ), + u32x8::new( + 2630983, 16779097, 23427897, 24961950, 4163362, 34026572, 30599780, 7845495, + ), + u32x8::new( + 60502934, 26002777, 6086439, 11658729, 4505433, 12119750, 21950458, 10576888, + ), + u32x8::new( + 57816473, 56985743, 1967671, 28392403, 47398127, 17117967, 25773361, 5969381, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 66731766, 35440184, 23240508, 12578955, 23813578, 11932658, 28524354, 4410390, + ), + u32x8::new( + 35029396, 42045935, 13583624, 30545302, 18072349, 60251757, 26909604, 3168485, + ), + u32x8::new( + 52593586, 8272016, 23476821, 27793245, 59450809, 43235010, 19158043, 13900973, + ), + u32x8::new( + 3380693, 10076059, 21309515, 7486427, 54763106, 60672077, 23935029, 4919292, + ), + u32x8::new( + 29038627, 47758745, 31614994, 7613432, 60524545, 22183797, 8942240, 17940854, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 39393392, 10391092, 1663950, 17764784, 52174436, 58522742, 14610190, 33003774, + ), + u32x8::new( + 18792864, 23237327, 29851527, 20099347, 33497823, 47822029, 26183237, 18897916, + ), + u32x8::new( + 4925601, 57266003, 17049968, 24968517, 29206022, 49724079, 26913223, 31283328, + ), + u32x8::new( + 9489771, 63067837, 15983728, 13200086, 3218678, 36652882, 10403363, 5100681, + ), + u32x8::new( + 56042662, 24110740, 20694167, 10094988, 23975807, 52565202, 23909379, 26655765, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 48349462, 54311721, 26561149, 2733194, 44527354, 50861280, 12671324, 31958244, + ), + u32x8::new( + 32982621, 65605689, 23289360, 18089302, 54624918, 17589133, 10972829, 32590647, + ), + u32x8::new( + 6816690, 7628472, 23754522, 24288235, 8369748, 18041309, 25046519, 23767159, + ), + u32x8::new( + 27321898, 7786690, 16691255, 12854903, 2662801, 18123339, 22782363, 19050381, + ), + u32x8::new( + 15631304, 40480691, 21556580, 17428730, 40792643, 14025214, 19228208, 23270873, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 35283625, 11728480, 16525129, 21254122, 41264490, 12780085, 12425291, 25574480, + ), + u32x8::new( + 3976942, 25758372, 16354786, 2802171, 48683356, 58643111, 20347428, 5557372, + ), + u32x8::new( + 37282889, 40844952, 31816804, 5307805, 49995034, 43032209, 195179, 20967661, + ), + u32x8::new( + 65160506, 41684913, 22915935, 23273464, 47878154, 29250563, 26585711, 15598167, + ), + u32x8::new( + 58310114, 28135654, 30006385, 26759512, 55700371, 10682560, 16895493, 11956640, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 8739959, 6441677, 20071820, 6260925, 12135272, 35602206, 19354997, 3828824, + ), + u32x8::new( + 30453696, 19064155, 26225492, 24399500, 51186398, 38748122, 7795201, 4192133, + ), + u32x8::new( + 50252721, 33452338, 763721, 19503574, 14658194, 22910363, 28050437, 28538699, + ), + u32x8::new( + 63811524, 5331685, 3231512, 8214656, 37355183, 53148282, 27097861, 12919119, + ), + u32x8::new( + 65209274, 24012503, 6146632, 2455398, 25965494, 48166106, 28064467, 12852626, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 18255245, 10830823, 29219906, 17790138, 65273593, 48249041, 16033189, 6372863, + ), + u32x8::new( + 19532224, 60662360, 31759043, 32872917, 58875600, 15194711, 19219994, 19920176, + ), + u32x8::new( + 26867610, 20523625, 32005845, 21160874, 492466, 7701656, 2252867, 20148622, + ), + u32x8::new( + 46376157, 47055317, 20275649, 30870862, 62729625, 34059121, 25399810, 32573022, + ), + u32x8::new( + 28544962, 52764783, 31358243, 24059505, 33165224, 27217897, 24778226, 27389346, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 17058015, 25670499, 24440049, 7203596, 60922354, 55821560, 9603660, 16378211, + ), + u32x8::new( + 553548, 46336261, 25350958, 16485317, 64929979, 7948163, 28984880, 17599742, + ), + u32x8::new( + 58474356, 25584115, 23664362, 31328518, 51764502, 53328389, 31469481, 19046459, + ), + u32x8::new( + 13937813, 26848456, 12659705, 33342922, 35224437, 62653913, 9092695, 30391740, + ), + u32x8::new( + 28804094, 10162477, 21048934, 17519554, 14492263, 63229531, 4816933, 32038404, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 64495754, 7606601, 30768871, 11324901, 38730381, 356545, 9072896, 3657156, + ), + u32x8::new( + 37126487, 27478134, 10840119, 30993714, 6074712, 12520527, 28407165, 10171396, + ), + u32x8::new( + 54995662, 282682, 27111396, 1017727, 58061730, 66917337, 26579751, 11335204, + ), + u32x8::new( + 37192254, 65880650, 22734367, 11851343, 38926276, 37479106, 26991998, 27971287, + ), + u32x8::new( + 38316048, 12449738, 29786209, 6735786, 50954311, 59758441, 11012532, 2828766, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 54746292, 3351301, 4865142, 16071423, 11192041, 921498, 13420952, 737759, + ), + u32x8::new( + 3201237, 53553995, 16392356, 25107953, 48869590, 44368895, 8293121, 10904381, + ), + u32x8::new( + 39210876, 64893642, 7259317, 3779423, 63887492, 63189787, 2079291, 7951436, + ), + u32x8::new( + 18203445, 19031102, 5686425, 24287423, 48630897, 26782504, 3980127, 6203320, + ), + u32x8::new( + 14153223, 44826005, 2080274, 17064506, 49731061, 11600063, 21521384, 5700012, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 26039234, 57740291, 17450926, 21618166, 35027367, 53770447, 25104427, 4534630, + ), + u32x8::new( + 58199854, 4048432, 19725485, 8676380, 4496796, 32112973, 14527153, 31886365, + ), + u32x8::new( + 46510029, 60410999, 1049165, 88395, 35900083, 4680075, 14117252, 19073823, + ), + u32x8::new( + 14834140, 34398960, 3099842, 1418852, 41491302, 3329253, 9894880, 31414407, + ), + u32x8::new( + 61867728, 33916193, 20659987, 9787272, 65689301, 24395594, 7149768, 16974183, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 38592675, 64874378, 17049178, 9325147, 54576251, 50526986, 2008071, 12959825, + ), + u32x8::new( + 21615826, 31815525, 24704895, 25718380, 17073202, 40869839, 19001238, 24480818, + ), + u32x8::new( + 3038387, 40705806, 23038331, 26775421, 19876700, 65765058, 10450975, 23214025, + ), + u32x8::new( + 24729052, 32137803, 22273211, 5820961, 59555176, 41807251, 6436190, 17343685, + ), + u32x8::new( + 50468260, 64071930, 23025204, 2932954, 55243923, 42920856, 23230990, 8989658, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 38681972, 20910541, 2032735, 13060003, 24467744, 39947783, 10974405, 18726178, + ), + u32x8::new( + 46422005, 7294324, 1352924, 3070447, 10109254, 56348432, 31418865, 13982194, + ), + u32x8::new( + 1879105, 67024066, 8943520, 2177572, 7052099, 49106981, 19381931, 22827220, + ), + u32x8::new( + 27035999, 44678277, 19999615, 31394693, 49519912, 47783891, 21514111, 3058426, + ), + u32x8::new( + 20380943, 46523227, 16939292, 31759883, 45013387, 42615050, 21567789, 24465077, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 24758872, 48093278, 12054808, 19982875, 16601536, 20679201, 17320246, 12049903, + ), + u32x8::new( + 10732195, 37514464, 15100866, 13262184, 5693490, 35026762, 27996909, 23321095, + ), + u32x8::new( + 49547127, 59290299, 9251588, 10424803, 61482643, 56252492, 27189162, 1114153, + ), + u32x8::new( + 49235158, 66497026, 14643123, 7545747, 3154536, 49436807, 8495962, 6928326, + ), + u32x8::new( + 24195811, 64209685, 32621195, 19651962, 63557398, 26731249, 9215913, 15000271, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 39362355, 30615963, 29492631, 17757350, 65464634, 2196595, 25384200, 1025966, + ), + u32x8::new( + 37391798, 218196, 10777783, 9721580, 29410767, 28236356, 19198383, 15192509, + ), + u32x8::new( + 54391785, 9329005, 24545668, 32067203, 25585768, 54310251, 27384012, 11980453, + ), + u32x8::new( + 17100783, 12759283, 17875986, 3214265, 19855781, 65528748, 18242774, 26388597, + ), + u32x8::new( + 39553752, 5566423, 11463364, 105938, 55915861, 41853238, 30256182, 30862425, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 10851498, 49488408, 3570772, 20957916, 6350678, 29213790, 25532542, 18446629, + ), + u32x8::new( + 35822904, 33386907, 14799416, 28832032, 46517945, 40067145, 3920828, 26711338, + ), + u32x8::new( + 11784440, 34057397, 16363942, 21917723, 11777673, 31709679, 17374835, 29320296, + ), + u32x8::new( + 20055448, 55343985, 426939, 11506514, 3425142, 11780273, 4126957, 9674899, + ), + u32x8::new( + 52658368, 57538147, 22996684, 16887355, 9137437, 53019167, 26859576, 5857918, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 17124073, 28608585, 17204038, 30317038, 13526226, 12798491, 9070322, 29064022, + ), + u32x8::new( + 53579310, 48557174, 5763436, 27071406, 19468517, 18165058, 29666364, 14811434, + ), + u32x8::new( + 4858631, 42450577, 18478896, 20495063, 44264997, 44779689, 24809973, 8041411, + ), + u32x8::new( + 28924003, 42437006, 9765195, 25266761, 29931744, 43535313, 13389753, 8976199, + ), + u32x8::new( + 36750994, 47899326, 6521999, 1779471, 48276964, 1011466, 24875426, 32792174, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 23916733, 33408500, 24983936, 29513864, 48796532, 2522248, 22441323, 18387669, + ), + u32x8::new( + 56199088, 56667386, 20303419, 11894504, 57566613, 5838923, 17158244, 6287953, + ), + u32x8::new( + 50587518, 33647537, 14158002, 11603669, 6909921, 36409615, 23881461, 28394959, + ), + u32x8::new( + 24294672, 55554682, 13142342, 26695416, 8228969, 54820198, 22158021, 1984332, + ), + u32x8::new( + 61550032, 55987900, 18734977, 19718454, 38981101, 49145851, 31135319, 18242837, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 63271352, 3345554, 8806163, 30410965, 58835400, 44143591, 14307494, 30519587, + ), + u32x8::new( + 61671026, 20406686, 19954294, 12955263, 24996752, 47788485, 32966873, 24815214, + ), + u32x8::new( + 35108777, 20779231, 23122248, 2741995, 16567296, 39737537, 21067930, 27135650, + ), + u32x8::new( + 54379057, 66238772, 2095510, 10813501, 28479653, 6016965, 18105295, 22118545, + ), + u32x8::new( + 40756239, 19381930, 97062, 21373713, 45676920, 5737483, 31568996, 24547179, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 54084073, 61771673, 3357543, 22550514, 46174518, 48774614, 15044165, 10600086, + ), + u32x8::new( + 44515422, 12398335, 4889691, 20836719, 20852631, 55618838, 21729331, 19949350, + ), + u32x8::new( + 6577749, 59005054, 30870256, 18617312, 18984404, 13905890, 33062168, 2159226, + ), + u32x8::new( + 53826979, 30281813, 13460463, 13683579, 65783993, 10036586, 28250665, 13193685, + ), + u32x8::new( + 54570039, 55540006, 25205201, 21169710, 47347388, 56958486, 10170935, 25885607, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 54952811, 34289643, 28618484, 29640332, 23228831, 32699232, 6932116, 33118171, + ), + u32x8::new( + 31396880, 42559968, 5914854, 20035896, 32490433, 37898205, 24001928, 7004846, + ), + u32x8::new( + 4873000, 25549466, 4520179, 26816019, 4189494, 8620065, 16981281, 22331201, + ), + u32x8::new( + 1513745, 60529244, 26764171, 28197759, 8451942, 6462677, 742930, 7635875, + ), + u32x8::new( + 42592860, 5474664, 13601149, 18175741, 45972230, 63064023, 14315909, 5065788, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 44769963, 14159123, 2921805, 16527841, 44757513, 25541510, 31322159, 32261013, + ), + u32x8::new( + 46474847, 26897441, 4547657, 5707849, 37373879, 27828399, 18951228, 15792531, + ), + u32x8::new( + 45513101, 31095299, 33289913, 20361747, 18881497, 42084136, 23020437, 16623296, + ), + u32x8::new( + 43855935, 33749927, 1612825, 2098085, 13042557, 21361892, 30423213, 6709525, + ), + u32x8::new( + 54627378, 20168178, 22703373, 889488, 44903505, 35521237, 26851998, 31723778, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 1395524, 6055713, 7470570, 5022318, 11737259, 25424763, 28637966, 11052352, + ), + u32x8::new( + 16904966, 16058449, 32470437, 15169914, 19222959, 53679810, 3713461, 3131701, + ), + u32x8::new( + 33029015, 44312124, 12432517, 16910617, 62389517, 767341, 11221827, 12834556, + ), + u32x8::new( + 22660475, 36183363, 7652076, 30118306, 48226338, 40121804, 3257920, 22042761, + ), + u32x8::new( + 32949607, 15936733, 23258108, 19820138, 38606143, 13443115, 17596808, 14901855, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 30453826, 47167213, 24825986, 264583, 53093075, 3164329, 33512141, 20109482, + ), + u32x8::new( + 37561382, 53622773, 6534928, 2872288, 57936987, 60933661, 6981415, 17672550, + ), + u32x8::new( + 66303228, 24325217, 24000286, 21078791, 33706720, 35806819, 26560795, 19466721, + ), + u32x8::new( + 4057585, 48336034, 3731529, 5715697, 3512281, 13722216, 30690758, 33513686, + ), + u32x8::new( + 21461545, 62891446, 24137762, 10967411, 64804869, 52956533, 289337, 5307926, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 58181741, 19561590, 2003183, 8073939, 16549729, 4804271, 7180120, 13280200, + ), + u32x8::new( + 2904751, 11653754, 10963004, 2778896, 19890316, 9775041, 28375774, 2102377, + ), + u32x8::new( + 14875277, 63509811, 21594387, 1446100, 27518070, 35361654, 15070533, 17910540, + ), + u32x8::new( + 30450863, 21511636, 10175854, 11459716, 5008103, 20405915, 22918575, 22257479, + ), + u32x8::new( + 27152739, 6232375, 7731886, 27266048, 49260862, 1274533, 16731053, 19801711, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 7228572, 8188034, 32245072, 13164166, 61557866, 27090288, 29715978, 793096, + ), + u32x8::new( + 21954847, 16377712, 14995929, 13581712, 27064072, 17025527, 8380465, 6858807, + ), + u32x8::new( + 42937487, 35819059, 9600283, 5969557, 54811763, 42986590, 26116792, 16388822, + ), + u32x8::new( + 9909112, 47486917, 18338518, 32187177, 45760178, 55923935, 4339290, 1323251, + ), + u32x8::new( + 26018644, 7085833, 19316410, 29532175, 50740522, 11566212, 32026988, 23819030, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new( + 48139170, 64071957, 11014660, 31869023, 14892716, 4695548, 28902027, 25435873, + ), + u32x8::new( + 21091331, 12606917, 11263458, 7789299, 45929544, 29249832, 26181297, 44752, + ), + u32x8::new( + 8517290, 35025424, 15205374, 4207525, 7912466, 51919918, 7920166, 19775672, + ), + u32x8::new( + 65388567, 66295729, 700694, 1529704, 368119, 31962316, 11707051, 12313120, + ), + u32x8::new( + 34650649, 16866178, 19228474, 1489351, 26761664, 3981409, 30102836, 8791421, + ), + ])), +]); diff --git a/src/backend/vector/mod.rs b/src/backend/vector/mod.rs index 1f3a40cff..a280bb244 100644 --- a/src/backend/vector/mod.rs +++ b/src/backend/vector/mod.rs @@ -24,7 +24,9 @@ pub mod avx2; all(docsrs, target_arch = "x86_64") ))] pub(crate) use self::avx2::{ - constants::BASEPOINT_ODD_LOOKUP_TABLE, edwards::CachedPoint, edwards::ExtendedPoint, + constants::{BASEPOINT_ODD_LOOKUP_TABLE, B_SHL_128_ODD_LOOKUP_TABLE}, + edwards::CachedPoint, + edwards::ExtendedPoint, }; #[cfg(any(target_feature = "avx512ifma", all(docsrs, target_arch = "x86_64")))] diff --git a/src/backend/vector/scalar_mul/abglsv_pornin.rs b/src/backend/vector/scalar_mul/abglsv_pornin.rs new file mode 100644 index 000000000..7b5470c7e --- /dev/null +++ b/src/backend/vector/scalar_mul/abglsv_pornin.rs @@ -0,0 +1,172 @@ +// -*- mode: rust; -*- +// +// This file is part of curve25519-dalek. +// Copyright (c) 2020 Jack Grigg +// See LICENSE for licensing information. +// +// Author: +// Jack Grigg +#![allow(non_snake_case)] + +use crate::{ + backend::vector::{ + CachedPoint, ExtendedPoint, BASEPOINT_ODD_LOOKUP_TABLE, B_SHL_128_ODD_LOOKUP_TABLE, + }, + 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.abs() as u128); + let d_1 = Scalar::from(d_1.abs() as u128); + + // 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); + let e_0_naf = e_0.non_adjacent_form(8); + let e_1_naf = e_1.non_adjacent_form(8); + 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); + let table_B = BASEPOINT_ODD_LOOKUP_TABLE; + let table_B_SHL_128 = B_SHL_128_ODD_LOOKUP_TABLE; + let table_negC = NafLookupTable5::::from(&negC); + + let mut Q = ExtendedPoint::identity(); + + loop { + Q = Q.double(); + + if d_0_naf[i] > 0 { + Q = &Q + &table_A.select(d_0_naf[i] as usize); + } else if d_0_naf[i] < 0 { + Q = &Q - &table_A.select(-d_0_naf[i] as usize); + } + + if e_0_naf[i] > 0 { + Q = &Q + &table_B.select(e_0_naf[i] as usize); + } else if e_0_naf[i] < 0 { + Q = &Q - &table_B.select(-e_0_naf[i] as usize); + } + + if e_1_naf[i] > 0 { + Q = &Q + &table_B_SHL_128.select(e_1_naf[i] as usize); + } else if e_1_naf[i] < 0 { + Q = &Q - &table_B_SHL_128.select(-e_1_naf[i] as usize); + } + + if d_1_naf[i] > 0 { + Q = &Q + &table_negC.select(d_1_naf[i] as usize); + } else if d_1_naf[i] < 0 { + Q = &Q - &table_negC.select(-d_1_naf[i] as usize); + } + + if i == 0 { + break; + } + i -= 1; + } + + Q.into() +} + +#[cfg(test)] +mod tests { + use super::mul; + use crate::{ + constants::{ED25519_BASEPOINT_POINT, ED25519_BASEPOINT_TABLE}, + 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_TABLE; + 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_TABLE; + assert!(!mul(&a, &A, &b, &C).is_identity()); + } + } +} diff --git a/src/backend/vector/scalar_mul/mod.rs b/src/backend/vector/scalar_mul/mod.rs index 36a7047a2..1be700d5b 100644 --- a/src/backend/vector/scalar_mul/mod.rs +++ b/src/backend/vector/scalar_mul/mod.rs @@ -9,6 +9,8 @@ // - isis agora lovecruft // - Henry de Valence +pub mod abglsv_pornin; + pub mod variable_base; pub mod vartime_double_base;