12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674 |
- /* mceliece6688128f.c - Classic McEliece for libgcrypt
- * Copyright (C) 2023-2024 Simon Josefsson <simon@josefsson.org>
- *
- * This file is part of Libgcrypt.
- *
- * Libgcrypt is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * Libgcrypt is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, see <https://www.gnu.org/licenses/>.
- * SPDX-License-Identifier: LGPL-2.1-or-later
- *
- */
- /* This file is extracted from libmceliece. */
- /*
- * libmceliece is hereby placed into the public domain.
- *
- * [SPDX-License-Identifier](https://spdx.dev/ids/):
- * [LicenseRef-PD-hp](https://cr.yp.to/spdx.html)
- * OR
- * [CC0-1.0](https://spdx.org/licenses/CC0-1.0.html)
- * OR
- * [0BSD](https://spdx.org/licenses/0BSD.html)
- * OR
- * [MIT-0](https://spdx.org/licenses/MIT-0.html)
- * OR
- * [MIT](https://spdx.org/licenses/MIT.html)
- *
- * libmceliece is based on the official Classic McEliece software, which
- * was written by Tung Chou. See the following papers for the major
- * algorithms used for speed inside that software:
- *
- * * Daniel J. Bernstein, Tung Chou, Peter Schwabe. "McBits: fast
- * constant-time code-based cryptography." CHES 2013.
- * [https://tungchou.github.io/papers/mcbits.pdf](https://tungchou.github.io/papers/mcbits.pdf)
- *
- * * Tung Chou. "McBits revisited." CHES 2017.
- * [https://tungchou.github.io/papers/mcbits_revisited.pdf](https://tungchou.github.io/papers/mcbits_revisited.pdf)
- *
- * The official Classic McEliece software includes `ref`, `vec`, `sse`, and
- * `avx` implementations; libmceliece includes only `vec` and `avx`.
- *
- * The following components of libmceliece are from Daniel J. Bernstein:
- *
- * * Small [changes](download.html#changelog)
- * for namespacing, portability, etc.
- *
- * * Software to compute control bits (also used in the official software).
- * See the following paper: Daniel J. Bernstein. "Verified fast formulas
- * for control bits for permutation networks." 2020.
- * [https://cr.yp.to/papers.html#controlbits](https://cr.yp.to/papers.html#controlbits)
- *
- * * `crypto_sort/int32`. See [https://sorting.cr.yp.to](https://sorting.cr.yp.to).
- *
- * * Infrastructure to build a library with automatic run-time selection of
- * implementations based on the run-time CPU and a database of
- * benchmarks. This infrastructure was introduced in
- * [`lib25519`](https://lib25519.cr.yp.to), with some extensions and
- * adaptations in libmceliece.
- *
- * * Various software for tests and benchmarks. This is based on
- * public-domain code in the SUPERCOP benchmarking framework.
- *
- * This file is generated by mceliece6688128f.sh from these files:
- *
- * libmceliece-20230612/include-build/crypto_declassify.h
- * libmceliece-20230612/crypto_kem/6688128f/vec/params.h
- * libmceliece-20230612/inttypes/crypto_intN.h
- * libmceliece-20230612/inttypes/crypto_intN.h
- * libmceliece-20230612/inttypes/crypto_intN.h
- * libmceliece-20230612/inttypes/crypto_uintN.h
- * libmceliece-20230612/inttypes/crypto_uintN.h
- * libmceliece-20230612/inttypes/crypto_uintN.h
- * libmceliece-20230612/crypto_kem/6688128f/vec/vec.h
- * libmceliece-20230612/crypto_kem/6688128f/vec/benes.h
- * libmceliece-20230612/crypto_kem/6688128f/vec/bm.h
- * libmceliece-20230612/crypto_kem/6688128f/vec/controlbits.h
- * libmceliece-20230612/crypto_kem/6688128f/vec/decrypt.h
- * libmceliece-20230612/crypto_kem/6688128f/vec/encrypt.h
- * libmceliece-20230612/crypto_kem/6688128f/vec/fft_consts.h
- * libmceliece-20230612/crypto_kem/6688128f/vec/fft.h
- * libmceliece-20230612/crypto_kem/6688128f/vec/fft_powers.h
- * libmceliece-20230612/crypto_kem/6688128f/vec/fft_scalars_2x.h
- * libmceliece-20230612/crypto_kem/6688128f/vec/fft_scalars_4x.h
- * libmceliece-20230612/crypto_kem/6688128f/vec/fft_tr.h
- * libmceliece-20230612/crypto_kem/6688128f/vec/gf.h
- * libmceliece-20230612/crypto_kem/6688128f/vec/hash.h
- * libmceliece-20230612/crypto_kem/6688128f/vec/int32_sort.h
- * libmceliece-20230612/crypto_kem/6688128f/vec/operations.h
- * libmceliece-20230612/crypto_kem/6688128f/vec/pk_gen.h
- * libmceliece-20230612/crypto_kem/6688128f/vec/sk_gen.h
- * libmceliece-20230612/crypto_kem/6688128f/vec/transpose.h
- * libmceliece-20230612/crypto_kem/6688128f/vec/uint16_sort.h
- * libmceliece-20230612/crypto_kem/6688128f/vec/uint64_sort.h
- * libmceliece-20230612/crypto_kem/6688128f/vec/util.h
- * libmceliece-20230612/crypto_kem/6688128f/vec/benes.c
- * libmceliece-20230612/crypto_kem/6688128f/vec/bm.c
- * libmceliece-20230612/crypto_kem/6688128f/vec/controlbits.c
- * libmceliece-20230612/crypto_kem/6688128f/vec/decrypt.c
- * libmceliece-20230612/crypto_kem/6688128f/vec/encrypt.c
- * libmceliece-20230612/crypto_kem/6688128f/vec/shared-fft_consts.c
- * libmceliece-20230612/crypto_kem/6688128f/vec/shared-fft_powers.c
- * libmceliece-20230612/crypto_kem/6688128f/vec/shared-fft_scalars_2x.c
- * libmceliece-20230612/crypto_kem/6688128f/vec/shared-fft_scalars_4x.c
- * libmceliece-20230612/crypto_kem/6688128f/vec/fft.c
- * libmceliece-20230612/crypto_kem/6688128f/vec/fft_tr.c
- * libmceliece-20230612/crypto_kem/6688128f/vec/gf.c
- * libmceliece-20230612/crypto_kem/6688128f/vec/kem_dec.c
- * libmceliece-20230612/crypto_kem/6688128f/vec/kem_enc.c
- * libmceliece-20230612/crypto_kem/6688128f/vec/kem_keypair.c
- * libmceliece-20230612/crypto_kem/6688128f/vec/pk_gen.c
- * libmceliece-20230612/crypto_kem/6688128f/vec/sk_gen.c
- * libmceliece-20230612/crypto_kem/6688128f/vec/vec.c
- * libmceliece-20230612/crypto_kem/6688128f/vec/wrap_dec.c
- * libmceliece-20230612/crypto_kem/6688128f/vec/wrap_enc.c
- * libmceliece-20230612/crypto_kem/6688128f/vec/wrap_keypair.c
- *
- */
- #ifdef HAVE_CONFIG_H
- #include <config.h>
- #endif
- #include "g10lib.h"
- #include "mceliece6688128f.h"
- #define int8 crypto_int8
- #define uint8 crypto_uint8
- #define int16 crypto_int16
- #define uint16 crypto_uint16
- #define int32 crypto_int32
- #define uint32 crypto_uint32
- #define int64 crypto_int64
- #define uint64 crypto_uint64
- static void
- randombytes (uint8_t *out, size_t outlen)
- {
- _gcry_randomize (out, outlen, GCRY_STRONG_RANDOM);
- }
- /* from libmceliece-20230612/include-build/crypto_declassify.h */
- #ifndef crypto_declassify_h
- #define crypto_declassify_h
- static void crypto_declassify(void *crypto_declassify_v,long long crypto_declassify_vlen) {
- (void) crypto_declassify_v;
- (void) crypto_declassify_vlen;
- }
- #endif
- /* from libmceliece-20230612/crypto_kem/6688128f/vec/params.h */
- #ifndef PARAMS_H
- #define PARAMS_H
- #define GFBITS 13
- #define SYS_N 6688
- #define SYS_T 128
- #define COND_BYTES ((1 << (GFBITS-4))*(2*GFBITS - 1))
- #define IRR_BYTES (SYS_T * 2)
- #define PK_NROWS (SYS_T*GFBITS)
- #define PK_NCOLS (SYS_N - PK_NROWS)
- #define PK_ROW_BYTES ((PK_NCOLS + 7)/8)
- #define SYND_BYTES ((PK_NROWS + 7)/8)
- #define GFMASK ((1 << GFBITS) - 1)
- #endif
- /* from libmceliece-20230612/inttypes/crypto_intN.h */
- #ifndef crypto_int64_h
- #define crypto_int64_h
- #define crypto_int64 int64_t
- GCC_ATTR_UNUSED
- static crypto_int64 crypto_int64_negative_mask(crypto_int64 crypto_int64_x)
- {
- return crypto_int64_x >> (64-1);
- }
- GCC_ATTR_UNUSED
- static crypto_int64 crypto_int64_nonzero_mask(crypto_int64 crypto_int64_x)
- {
- return crypto_int64_negative_mask(crypto_int64_x) | crypto_int64_negative_mask(-crypto_int64_x);
- }
- GCC_ATTR_UNUSED
- static crypto_int64 crypto_int64_zero_mask(crypto_int64 crypto_int64_x)
- {
- return ~crypto_int64_nonzero_mask(crypto_int64_x);
- }
- GCC_ATTR_UNUSED
- static crypto_int64 crypto_int64_positive_mask(crypto_int64 crypto_int64_x)
- {
- crypto_int64 crypto_int64_z = -crypto_int64_x;
- crypto_int64_z ^= crypto_int64_x & crypto_int64_z;
- return crypto_int64_negative_mask(crypto_int64_z);
- }
- GCC_ATTR_UNUSED
- static crypto_int64 crypto_int64_unequal_mask(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_y)
- {
- crypto_int64 crypto_int64_xy = crypto_int64_x ^ crypto_int64_y;
- return crypto_int64_nonzero_mask(crypto_int64_xy);
- }
- GCC_ATTR_UNUSED
- static crypto_int64 crypto_int64_equal_mask(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_y)
- {
- return ~crypto_int64_unequal_mask(crypto_int64_x,crypto_int64_y);
- }
- GCC_ATTR_UNUSED
- static crypto_int64 crypto_int64_smaller_mask(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_y)
- {
- crypto_int64 crypto_int64_xy = crypto_int64_x ^ crypto_int64_y;
- crypto_int64 crypto_int64_z = crypto_int64_x - crypto_int64_y;
- crypto_int64_z ^= crypto_int64_xy & (crypto_int64_z ^ crypto_int64_x);
- return crypto_int64_negative_mask(crypto_int64_z);
- }
- GCC_ATTR_UNUSED
- static crypto_int64 crypto_int64_min(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_y)
- {
- crypto_int64 crypto_int64_xy = crypto_int64_y ^ crypto_int64_x;
- crypto_int64 crypto_int64_z = crypto_int64_y - crypto_int64_x;
- crypto_int64_z ^= crypto_int64_xy & (crypto_int64_z ^ crypto_int64_y);
- crypto_int64_z = crypto_int64_negative_mask(crypto_int64_z);
- crypto_int64_z &= crypto_int64_xy;
- return crypto_int64_x ^ crypto_int64_z;
- }
- GCC_ATTR_UNUSED
- static crypto_int64 crypto_int64_max(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_y)
- {
- crypto_int64 crypto_int64_xy = crypto_int64_y ^ crypto_int64_x;
- crypto_int64 crypto_int64_z = crypto_int64_y - crypto_int64_x;
- crypto_int64_z ^= crypto_int64_xy & (crypto_int64_z ^ crypto_int64_y);
- crypto_int64_z = crypto_int64_negative_mask(crypto_int64_z);
- crypto_int64_z &= crypto_int64_xy;
- return crypto_int64_y ^ crypto_int64_z;
- }
- GCC_ATTR_UNUSED
- static void crypto_int64_minmax(crypto_int64 *crypto_int64_a,crypto_int64 *crypto_int64_b)
- {
- crypto_int64 crypto_int64_x = *crypto_int64_a;
- crypto_int64 crypto_int64_y = *crypto_int64_b;
- crypto_int64 crypto_int64_xy = crypto_int64_y ^ crypto_int64_x;
- crypto_int64 crypto_int64_z = crypto_int64_y - crypto_int64_x;
- crypto_int64_z ^= crypto_int64_xy & (crypto_int64_z ^ crypto_int64_y);
- crypto_int64_z = crypto_int64_negative_mask(crypto_int64_z);
- crypto_int64_z &= crypto_int64_xy;
- *crypto_int64_a = crypto_int64_x ^ crypto_int64_z;
- *crypto_int64_b = crypto_int64_y ^ crypto_int64_z;
- }
- #endif
- /* from libmceliece-20230612/inttypes/crypto_intN.h */
- #ifndef crypto_int16_h
- #define crypto_int16_h
- #define crypto_int16 int16_t
- GCC_ATTR_UNUSED
- static crypto_int16 crypto_int16_negative_mask(crypto_int16 crypto_int16_x)
- {
- return crypto_int16_x >> (16-1);
- }
- GCC_ATTR_UNUSED
- static crypto_int16 crypto_int16_nonzero_mask(crypto_int16 crypto_int16_x)
- {
- return crypto_int16_negative_mask(crypto_int16_x) | crypto_int16_negative_mask(-crypto_int16_x);
- }
- GCC_ATTR_UNUSED
- static crypto_int16 crypto_int16_zero_mask(crypto_int16 crypto_int16_x)
- {
- return ~crypto_int16_nonzero_mask(crypto_int16_x);
- }
- GCC_ATTR_UNUSED
- static crypto_int16 crypto_int16_positive_mask(crypto_int16 crypto_int16_x)
- {
- crypto_int16 crypto_int16_z = -crypto_int16_x;
- crypto_int16_z ^= crypto_int16_x & crypto_int16_z;
- return crypto_int16_negative_mask(crypto_int16_z);
- }
- GCC_ATTR_UNUSED
- static crypto_int16 crypto_int16_unequal_mask(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_y)
- {
- crypto_int16 crypto_int16_xy = crypto_int16_x ^ crypto_int16_y;
- return crypto_int16_nonzero_mask(crypto_int16_xy);
- }
- GCC_ATTR_UNUSED
- static crypto_int16 crypto_int16_equal_mask(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_y)
- {
- return ~crypto_int16_unequal_mask(crypto_int16_x,crypto_int16_y);
- }
- GCC_ATTR_UNUSED
- static crypto_int16 crypto_int16_smaller_mask(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_y)
- {
- crypto_int16 crypto_int16_xy = crypto_int16_x ^ crypto_int16_y;
- crypto_int16 crypto_int16_z = crypto_int16_x - crypto_int16_y;
- crypto_int16_z ^= crypto_int16_xy & (crypto_int16_z ^ crypto_int16_x);
- return crypto_int16_negative_mask(crypto_int16_z);
- }
- GCC_ATTR_UNUSED
- static crypto_int16 crypto_int16_min(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_y)
- {
- crypto_int16 crypto_int16_xy = crypto_int16_y ^ crypto_int16_x;
- crypto_int16 crypto_int16_z = crypto_int16_y - crypto_int16_x;
- crypto_int16_z ^= crypto_int16_xy & (crypto_int16_z ^ crypto_int16_y);
- crypto_int16_z = crypto_int16_negative_mask(crypto_int16_z);
- crypto_int16_z &= crypto_int16_xy;
- return crypto_int16_x ^ crypto_int16_z;
- }
- GCC_ATTR_UNUSED
- static crypto_int16 crypto_int16_max(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_y)
- {
- crypto_int16 crypto_int16_xy = crypto_int16_y ^ crypto_int16_x;
- crypto_int16 crypto_int16_z = crypto_int16_y - crypto_int16_x;
- crypto_int16_z ^= crypto_int16_xy & (crypto_int16_z ^ crypto_int16_y);
- crypto_int16_z = crypto_int16_negative_mask(crypto_int16_z);
- crypto_int16_z &= crypto_int16_xy;
- return crypto_int16_y ^ crypto_int16_z;
- }
- GCC_ATTR_UNUSED
- static void crypto_int16_minmax(crypto_int16 *crypto_int16_a,crypto_int16 *crypto_int16_b)
- {
- crypto_int16 crypto_int16_x = *crypto_int16_a;
- crypto_int16 crypto_int16_y = *crypto_int16_b;
- crypto_int16 crypto_int16_xy = crypto_int16_y ^ crypto_int16_x;
- crypto_int16 crypto_int16_z = crypto_int16_y - crypto_int16_x;
- crypto_int16_z ^= crypto_int16_xy & (crypto_int16_z ^ crypto_int16_y);
- crypto_int16_z = crypto_int16_negative_mask(crypto_int16_z);
- crypto_int16_z &= crypto_int16_xy;
- *crypto_int16_a = crypto_int16_x ^ crypto_int16_z;
- *crypto_int16_b = crypto_int16_y ^ crypto_int16_z;
- }
- #endif
- /* from libmceliece-20230612/inttypes/crypto_intN.h */
- #ifndef crypto_int32_h
- #define crypto_int32_h
- #define crypto_int32 int32_t
- GCC_ATTR_UNUSED
- static crypto_int32 crypto_int32_negative_mask(crypto_int32 crypto_int32_x)
- {
- return crypto_int32_x >> (32-1);
- }
- GCC_ATTR_UNUSED
- static crypto_int32 crypto_int32_nonzero_mask(crypto_int32 crypto_int32_x)
- {
- return crypto_int32_negative_mask(crypto_int32_x) | crypto_int32_negative_mask(-crypto_int32_x);
- }
- GCC_ATTR_UNUSED
- static crypto_int32 crypto_int32_zero_mask(crypto_int32 crypto_int32_x)
- {
- return ~crypto_int32_nonzero_mask(crypto_int32_x);
- }
- GCC_ATTR_UNUSED
- static crypto_int32 crypto_int32_positive_mask(crypto_int32 crypto_int32_x)
- {
- crypto_int32 crypto_int32_z = -crypto_int32_x;
- crypto_int32_z ^= crypto_int32_x & crypto_int32_z;
- return crypto_int32_negative_mask(crypto_int32_z);
- }
- GCC_ATTR_UNUSED
- static crypto_int32 crypto_int32_unequal_mask(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_y)
- {
- crypto_int32 crypto_int32_xy = crypto_int32_x ^ crypto_int32_y;
- return crypto_int32_nonzero_mask(crypto_int32_xy);
- }
- GCC_ATTR_UNUSED
- static crypto_int32 crypto_int32_equal_mask(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_y)
- {
- return ~crypto_int32_unequal_mask(crypto_int32_x,crypto_int32_y);
- }
- GCC_ATTR_UNUSED
- static crypto_int32 crypto_int32_smaller_mask(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_y)
- {
- crypto_int32 crypto_int32_xy = crypto_int32_x ^ crypto_int32_y;
- crypto_int32 crypto_int32_z = crypto_int32_x - crypto_int32_y;
- crypto_int32_z ^= crypto_int32_xy & (crypto_int32_z ^ crypto_int32_x);
- return crypto_int32_negative_mask(crypto_int32_z);
- }
- GCC_ATTR_UNUSED
- static crypto_int32 crypto_int32_min(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_y)
- {
- crypto_int32 crypto_int32_xy = crypto_int32_y ^ crypto_int32_x;
- crypto_int32 crypto_int32_z = crypto_int32_y - crypto_int32_x;
- crypto_int32_z ^= crypto_int32_xy & (crypto_int32_z ^ crypto_int32_y);
- crypto_int32_z = crypto_int32_negative_mask(crypto_int32_z);
- crypto_int32_z &= crypto_int32_xy;
- return crypto_int32_x ^ crypto_int32_z;
- }
- GCC_ATTR_UNUSED
- static crypto_int32 crypto_int32_max(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_y)
- {
- crypto_int32 crypto_int32_xy = crypto_int32_y ^ crypto_int32_x;
- crypto_int32 crypto_int32_z = crypto_int32_y - crypto_int32_x;
- crypto_int32_z ^= crypto_int32_xy & (crypto_int32_z ^ crypto_int32_y);
- crypto_int32_z = crypto_int32_negative_mask(crypto_int32_z);
- crypto_int32_z &= crypto_int32_xy;
- return crypto_int32_y ^ crypto_int32_z;
- }
- GCC_ATTR_UNUSED
- static void crypto_int32_minmax(crypto_int32 *crypto_int32_a,crypto_int32 *crypto_int32_b)
- {
- crypto_int32 crypto_int32_x = *crypto_int32_a;
- crypto_int32 crypto_int32_y = *crypto_int32_b;
- crypto_int32 crypto_int32_xy = crypto_int32_y ^ crypto_int32_x;
- crypto_int32 crypto_int32_z = crypto_int32_y - crypto_int32_x;
- crypto_int32_z ^= crypto_int32_xy & (crypto_int32_z ^ crypto_int32_y);
- crypto_int32_z = crypto_int32_negative_mask(crypto_int32_z);
- crypto_int32_z &= crypto_int32_xy;
- *crypto_int32_a = crypto_int32_x ^ crypto_int32_z;
- *crypto_int32_b = crypto_int32_y ^ crypto_int32_z;
- }
- #endif
- /* from libmceliece-20230612/inttypes/crypto_uintN.h */
- #ifndef crypto_uint64_h
- #define crypto_uint64_h
- #define crypto_uint64 uint64_t
- #define crypto_uint64_signed int64_t
- GCC_ATTR_UNUSED
- static crypto_uint64_signed crypto_uint64_signed_negative_mask(crypto_uint64_signed crypto_uint64_signed_x)
- {
- return crypto_uint64_signed_x >> (64-1);
- }
- GCC_ATTR_UNUSED
- static crypto_uint64 crypto_uint64_nonzero_mask(crypto_uint64 crypto_uint64_x)
- {
- return crypto_uint64_signed_negative_mask(crypto_uint64_x) | crypto_uint64_signed_negative_mask(-crypto_uint64_x);
- }
- GCC_ATTR_UNUSED
- static crypto_uint64 crypto_uint64_zero_mask(crypto_uint64 crypto_uint64_x)
- {
- return ~crypto_uint64_nonzero_mask(crypto_uint64_x);
- }
- GCC_ATTR_UNUSED
- static crypto_uint64 crypto_uint64_unequal_mask(crypto_uint64 crypto_uint64_x,crypto_uint64 crypto_uint64_y)
- {
- crypto_uint64 crypto_uint64_xy = crypto_uint64_x ^ crypto_uint64_y;
- return crypto_uint64_nonzero_mask(crypto_uint64_xy);
- }
- GCC_ATTR_UNUSED
- static crypto_uint64 crypto_uint64_equal_mask(crypto_uint64 crypto_uint64_x,crypto_uint64 crypto_uint64_y)
- {
- return ~crypto_uint64_unequal_mask(crypto_uint64_x,crypto_uint64_y);
- }
- GCC_ATTR_UNUSED
- static crypto_uint64 crypto_uint64_smaller_mask(crypto_uint64 crypto_uint64_x,crypto_uint64 crypto_uint64_y)
- {
- crypto_uint64 crypto_uint64_xy = crypto_uint64_x ^ crypto_uint64_y;
- crypto_uint64 crypto_uint64_z = crypto_uint64_x - crypto_uint64_y;
- crypto_uint64_z ^= crypto_uint64_xy & (crypto_uint64_z ^ crypto_uint64_x ^ (((crypto_uint64) 1) << (64-1)));
- return crypto_uint64_signed_negative_mask(crypto_uint64_z);
- }
- GCC_ATTR_UNUSED
- static crypto_uint64 crypto_uint64_min(crypto_uint64 crypto_uint64_x,crypto_uint64 crypto_uint64_y)
- {
- crypto_uint64 crypto_uint64_xy = crypto_uint64_y ^ crypto_uint64_x;
- crypto_uint64 crypto_uint64_z = crypto_uint64_y - crypto_uint64_x;
- crypto_uint64_z ^= crypto_uint64_xy & (crypto_uint64_z ^ crypto_uint64_y ^ (((crypto_uint64) 1) << (64-1)));
- crypto_uint64_z = crypto_uint64_signed_negative_mask(crypto_uint64_z);
- crypto_uint64_z &= crypto_uint64_xy;
- return crypto_uint64_x ^ crypto_uint64_z;
- }
- GCC_ATTR_UNUSED
- static crypto_uint64 crypto_uint64_max(crypto_uint64 crypto_uint64_x,crypto_uint64 crypto_uint64_y)
- {
- crypto_uint64 crypto_uint64_xy = crypto_uint64_y ^ crypto_uint64_x;
- crypto_uint64 crypto_uint64_z = crypto_uint64_y - crypto_uint64_x;
- crypto_uint64_z ^= crypto_uint64_xy & (crypto_uint64_z ^ crypto_uint64_y ^ (((crypto_uint64) 1) << (64-1)));
- crypto_uint64_z = crypto_uint64_signed_negative_mask(crypto_uint64_z);
- crypto_uint64_z &= crypto_uint64_xy;
- return crypto_uint64_y ^ crypto_uint64_z;
- }
- GCC_ATTR_UNUSED
- static void crypto_uint64_minmax(crypto_uint64 *crypto_uint64_a,crypto_uint64 *crypto_uint64_b)
- {
- crypto_uint64 crypto_uint64_x = *crypto_uint64_a;
- crypto_uint64 crypto_uint64_y = *crypto_uint64_b;
- crypto_uint64 crypto_uint64_xy = crypto_uint64_y ^ crypto_uint64_x;
- crypto_uint64 crypto_uint64_z = crypto_uint64_y - crypto_uint64_x;
- crypto_uint64_z ^= crypto_uint64_xy & (crypto_uint64_z ^ crypto_uint64_y ^ (((crypto_uint64) 1) << (64-1)));
- crypto_uint64_z = crypto_uint64_signed_negative_mask(crypto_uint64_z);
- crypto_uint64_z &= crypto_uint64_xy;
- *crypto_uint64_a = crypto_uint64_x ^ crypto_uint64_z;
- *crypto_uint64_b = crypto_uint64_y ^ crypto_uint64_z;
- }
- #endif
- /* from libmceliece-20230612/inttypes/crypto_uintN.h */
- #ifndef crypto_uint16_h
- #define crypto_uint16_h
- #define crypto_uint16 uint16_t
- #define crypto_uint16_signed int16_t
- GCC_ATTR_UNUSED
- static crypto_uint16_signed crypto_uint16_signed_negative_mask(crypto_uint16_signed crypto_uint16_signed_x)
- {
- return crypto_uint16_signed_x >> (16-1);
- }
- GCC_ATTR_UNUSED
- static crypto_uint16 crypto_uint16_nonzero_mask(crypto_uint16 crypto_uint16_x)
- {
- return crypto_uint16_signed_negative_mask(crypto_uint16_x) | crypto_uint16_signed_negative_mask(-crypto_uint16_x);
- }
- GCC_ATTR_UNUSED
- static crypto_uint16 crypto_uint16_zero_mask(crypto_uint16 crypto_uint16_x)
- {
- return ~crypto_uint16_nonzero_mask(crypto_uint16_x);
- }
- GCC_ATTR_UNUSED
- static crypto_uint16 crypto_uint16_unequal_mask(crypto_uint16 crypto_uint16_x,crypto_uint16 crypto_uint16_y)
- {
- crypto_uint16 crypto_uint16_xy = crypto_uint16_x ^ crypto_uint16_y;
- return crypto_uint16_nonzero_mask(crypto_uint16_xy);
- }
- GCC_ATTR_UNUSED
- static crypto_uint16 crypto_uint16_equal_mask(crypto_uint16 crypto_uint16_x,crypto_uint16 crypto_uint16_y)
- {
- return ~crypto_uint16_unequal_mask(crypto_uint16_x,crypto_uint16_y);
- }
- GCC_ATTR_UNUSED
- static crypto_uint16 crypto_uint16_smaller_mask(crypto_uint16 crypto_uint16_x,crypto_uint16 crypto_uint16_y)
- {
- crypto_uint16 crypto_uint16_xy = crypto_uint16_x ^ crypto_uint16_y;
- crypto_uint16 crypto_uint16_z = crypto_uint16_x - crypto_uint16_y;
- crypto_uint16_z ^= crypto_uint16_xy & (crypto_uint16_z ^ crypto_uint16_x ^ (((crypto_uint16) 1) << (16-1)));
- return crypto_uint16_signed_negative_mask(crypto_uint16_z);
- }
- GCC_ATTR_UNUSED
- static crypto_uint16 crypto_uint16_min(crypto_uint16 crypto_uint16_x,crypto_uint16 crypto_uint16_y)
- {
- crypto_uint16 crypto_uint16_xy = crypto_uint16_y ^ crypto_uint16_x;
- crypto_uint16 crypto_uint16_z = crypto_uint16_y - crypto_uint16_x;
- crypto_uint16_z ^= crypto_uint16_xy & (crypto_uint16_z ^ crypto_uint16_y ^ (((crypto_uint16) 1) << (16-1)));
- crypto_uint16_z = crypto_uint16_signed_negative_mask(crypto_uint16_z);
- crypto_uint16_z &= crypto_uint16_xy;
- return crypto_uint16_x ^ crypto_uint16_z;
- }
- GCC_ATTR_UNUSED
- static crypto_uint16 crypto_uint16_max(crypto_uint16 crypto_uint16_x,crypto_uint16 crypto_uint16_y)
- {
- crypto_uint16 crypto_uint16_xy = crypto_uint16_y ^ crypto_uint16_x;
- crypto_uint16 crypto_uint16_z = crypto_uint16_y - crypto_uint16_x;
- crypto_uint16_z ^= crypto_uint16_xy & (crypto_uint16_z ^ crypto_uint16_y ^ (((crypto_uint16) 1) << (16-1)));
- crypto_uint16_z = crypto_uint16_signed_negative_mask(crypto_uint16_z);
- crypto_uint16_z &= crypto_uint16_xy;
- return crypto_uint16_y ^ crypto_uint16_z;
- }
- GCC_ATTR_UNUSED
- static void crypto_uint16_minmax(crypto_uint16 *crypto_uint16_a,crypto_uint16 *crypto_uint16_b)
- {
- crypto_uint16 crypto_uint16_x = *crypto_uint16_a;
- crypto_uint16 crypto_uint16_y = *crypto_uint16_b;
- crypto_uint16 crypto_uint16_xy = crypto_uint16_y ^ crypto_uint16_x;
- crypto_uint16 crypto_uint16_z = crypto_uint16_y - crypto_uint16_x;
- crypto_uint16_z ^= crypto_uint16_xy & (crypto_uint16_z ^ crypto_uint16_y ^ (((crypto_uint16) 1) << (16-1)));
- crypto_uint16_z = crypto_uint16_signed_negative_mask(crypto_uint16_z);
- crypto_uint16_z &= crypto_uint16_xy;
- *crypto_uint16_a = crypto_uint16_x ^ crypto_uint16_z;
- *crypto_uint16_b = crypto_uint16_y ^ crypto_uint16_z;
- }
- #endif
- /* from libmceliece-20230612/inttypes/crypto_uintN.h */
- #ifndef crypto_uint32_h
- #define crypto_uint32_h
- #define crypto_uint32 uint32_t
- #define crypto_uint32_signed int32_t
- GCC_ATTR_UNUSED
- static crypto_uint32_signed crypto_uint32_signed_negative_mask(crypto_uint32_signed crypto_uint32_signed_x)
- {
- return crypto_uint32_signed_x >> (32-1);
- }
- GCC_ATTR_UNUSED
- static crypto_uint32 crypto_uint32_nonzero_mask(crypto_uint32 crypto_uint32_x)
- {
- return crypto_uint32_signed_negative_mask(crypto_uint32_x) | crypto_uint32_signed_negative_mask(-crypto_uint32_x);
- }
- GCC_ATTR_UNUSED
- static crypto_uint32 crypto_uint32_zero_mask(crypto_uint32 crypto_uint32_x)
- {
- return ~crypto_uint32_nonzero_mask(crypto_uint32_x);
- }
- GCC_ATTR_UNUSED
- static crypto_uint32 crypto_uint32_unequal_mask(crypto_uint32 crypto_uint32_x,crypto_uint32 crypto_uint32_y)
- {
- crypto_uint32 crypto_uint32_xy = crypto_uint32_x ^ crypto_uint32_y;
- return crypto_uint32_nonzero_mask(crypto_uint32_xy);
- }
- GCC_ATTR_UNUSED
- static crypto_uint32 crypto_uint32_equal_mask(crypto_uint32 crypto_uint32_x,crypto_uint32 crypto_uint32_y)
- {
- return ~crypto_uint32_unequal_mask(crypto_uint32_x,crypto_uint32_y);
- }
- GCC_ATTR_UNUSED
- static crypto_uint32 crypto_uint32_smaller_mask(crypto_uint32 crypto_uint32_x,crypto_uint32 crypto_uint32_y)
- {
- crypto_uint32 crypto_uint32_xy = crypto_uint32_x ^ crypto_uint32_y;
- crypto_uint32 crypto_uint32_z = crypto_uint32_x - crypto_uint32_y;
- crypto_uint32_z ^= crypto_uint32_xy & (crypto_uint32_z ^ crypto_uint32_x ^ (((crypto_uint32) 1) << (32-1)));
- return crypto_uint32_signed_negative_mask(crypto_uint32_z);
- }
- GCC_ATTR_UNUSED
- static crypto_uint32 crypto_uint32_min(crypto_uint32 crypto_uint32_x,crypto_uint32 crypto_uint32_y)
- {
- crypto_uint32 crypto_uint32_xy = crypto_uint32_y ^ crypto_uint32_x;
- crypto_uint32 crypto_uint32_z = crypto_uint32_y - crypto_uint32_x;
- crypto_uint32_z ^= crypto_uint32_xy & (crypto_uint32_z ^ crypto_uint32_y ^ (((crypto_uint32) 1) << (32-1)));
- crypto_uint32_z = crypto_uint32_signed_negative_mask(crypto_uint32_z);
- crypto_uint32_z &= crypto_uint32_xy;
- return crypto_uint32_x ^ crypto_uint32_z;
- }
- GCC_ATTR_UNUSED
- static crypto_uint32 crypto_uint32_max(crypto_uint32 crypto_uint32_x,crypto_uint32 crypto_uint32_y)
- {
- crypto_uint32 crypto_uint32_xy = crypto_uint32_y ^ crypto_uint32_x;
- crypto_uint32 crypto_uint32_z = crypto_uint32_y - crypto_uint32_x;
- crypto_uint32_z ^= crypto_uint32_xy & (crypto_uint32_z ^ crypto_uint32_y ^ (((crypto_uint32) 1) << (32-1)));
- crypto_uint32_z = crypto_uint32_signed_negative_mask(crypto_uint32_z);
- crypto_uint32_z &= crypto_uint32_xy;
- return crypto_uint32_y ^ crypto_uint32_z;
- }
- GCC_ATTR_UNUSED
- static void crypto_uint32_minmax(crypto_uint32 *crypto_uint32_a,crypto_uint32 *crypto_uint32_b)
- {
- crypto_uint32 crypto_uint32_x = *crypto_uint32_a;
- crypto_uint32 crypto_uint32_y = *crypto_uint32_b;
- crypto_uint32 crypto_uint32_xy = crypto_uint32_y ^ crypto_uint32_x;
- crypto_uint32 crypto_uint32_z = crypto_uint32_y - crypto_uint32_x;
- crypto_uint32_z ^= crypto_uint32_xy & (crypto_uint32_z ^ crypto_uint32_y ^ (((crypto_uint32) 1) << (32-1)));
- crypto_uint32_z = crypto_uint32_signed_negative_mask(crypto_uint32_z);
- crypto_uint32_z &= crypto_uint32_xy;
- *crypto_uint32_a = crypto_uint32_x ^ crypto_uint32_z;
- *crypto_uint32_b = crypto_uint32_y ^ crypto_uint32_z;
- }
- #endif
- /* from libmceliece-20230612/crypto_kem/6688128f/vec/vec.h */
- #ifndef VEC_H
- #define VEC_H
- typedef uint64_t vec;
- static inline vec vec_setbits(vec b)
- {
- vec ret = -b;
- return ret;
- }
- static inline vec vec_set1_16b(uint16_t v)
- {
- vec ret;
- ret = v;
- ret |= ret << 16;
- ret |= ret << 32;
- return ret;
- }
- static inline void vec_copy(vec * out, vec * in)
- {
- int i;
- for (i = 0; i < GFBITS; i++)
- out[i] = in[i];
- }
- static inline vec vec_or_reduce(vec * a)
- {
- int i;
- vec ret;
- ret = a[0];
- for (i = 1; i < GFBITS; i++)
- ret |= a[i];
- return ret;
- }
- static inline int vec_testz(vec a)
- {
- a |= a >> 32;
- a |= a >> 16;
- a |= a >> 8;
- a |= a >> 4;
- a |= a >> 2;
- a |= a >> 1;
- return (a&1)^1;
- }
- static void vec_mul(vec *, const vec *, const vec *);
- static void vec_sq(vec *, vec *);
- static void vec_inv(vec *, vec *);
- #endif
- /* from libmceliece-20230612/crypto_kem/6688128f/vec/benes.h */
- /*
- This file is for Benes network related functions
- */
- #ifndef BENES_H
- #define BENES_H
- static void benes(vec *, const unsigned char *, int);
- #endif
- /* from libmceliece-20230612/crypto_kem/6688128f/vec/bm.h */
- /*
- This file is for the inversion-free Berlekamp-Massey algorithm
- see https://ieeexplore.ieee.org/document/87857
- */
- #ifndef BM_H
- #define BM_H
- static void bm(vec [][GFBITS], vec [][ GFBITS ]);
- #endif
- /* from libmceliece-20230612/crypto_kem/6688128f/vec/controlbits.h */
- /* This file is for implementing the Nassimi-Sahni algorithm */
- /* See David Nassimi, Sartaj Sahni "Parallel algorithms to set up the Benes permutationnetwork" */
- /* See also https://cr.yp.to/papers/controlbits-20200923.pdf */
- #ifndef CONTROLBITS_H
- #define CONTROLBITS_H
- #endif
- /* from libmceliece-20230612/crypto_kem/6688128f/vec/decrypt.h */
- /*
- This file is for Nieddereiter decryption
- */
- #ifndef DECRYPT_H
- #define DECRYPT_H
- static int decrypt(unsigned char *, const unsigned char *, const unsigned char *);
- #endif
- /* from libmceliece-20230612/crypto_kem/6688128f/vec/encrypt.h */
- /*
- This file is for Niederreiter encryption
- */
- /* 20230102 djb: rename encrypt() as pke_encrypt() */
- #ifndef ENCRYPT_H
- #define ENCRYPT_H
- static void pke_encrypt(unsigned char *, const unsigned char *, unsigned char *);
- #endif
- /* from libmceliece-20230612/crypto_kem/6688128f/vec/fft_consts.h */
- #ifndef fft_consts_h
- #define fft_consts_h
- #endif
- /* from libmceliece-20230612/crypto_kem/6688128f/vec/fft.h */
- /*
- This file is for the Gao-Mateer FFT
- sse http://www.math.clemson.edu/~sgao/papers/GM10.pdf
- */
- #ifndef FFT_H
- #define FFT_H
- static void fft(vec [][GFBITS], vec [][GFBITS]);
- #endif
- /* from libmceliece-20230612/crypto_kem/6688128f/vec/fft_powers.h */
- #ifndef fft_powers_h
- #define fft_powers_h
- #endif
- /* from libmceliece-20230612/crypto_kem/6688128f/vec/fft_scalars_2x.h */
- #ifndef fft_scalars_2x_h
- #define fft_scalars_2x_h
- #endif
- /* from libmceliece-20230612/crypto_kem/6688128f/vec/fft_scalars_4x.h */
- #ifndef fft_scalars_4x_h
- #define fft_scalars_4x_h
- #endif
- /* from libmceliece-20230612/crypto_kem/6688128f/vec/fft_tr.h */
- /*
- This file is for transpose of the Gao-Mateer FFT
- */
- #ifndef FFT_TR_H
- #define FFT_TR_H
- static void fft_tr(vec out[][GFBITS], vec in[][ GFBITS ]);
- #endif
- /* from libmceliece-20230612/crypto_kem/6688128f/vec/gf.h */
- /*
- This file is for functions for field arithmetic
- */
- /* 20221231 djb: const for GF_mul */
- #ifndef GF_H
- #define GF_H
- typedef uint16_t gf;
- gf gf_iszero(gf);
- gf gf_mul(gf, gf);
- gf gf_frac(gf, gf);
- gf gf_inv(gf);
- static void GF_mul(gf *, const gf *, const gf *);
- /* 2 field multiplications */
- static inline uint64_t gf_mul2(gf a, gf b0, gf b1)
- {
- int i;
- uint64_t tmp=0;
- uint64_t t0;
- uint64_t t1;
- uint64_t t;
- uint64_t mask = 0x0000000100000001;
- t0 = a;
- t1 = b1;
- t1 = (t1 << 32) | b0;
- for (i = 0; i < GFBITS; i++)
- {
- tmp ^= t0 * (t1 & mask);
- mask += mask;
- }
- /**/
- t = tmp & 0x01FF000001FF0000;
- tmp ^= (t >> 9) ^ (t >> 10) ^ (t >> 12) ^ (t >> 13);
- t = tmp & 0x0000E0000000E000;
- tmp ^= (t >> 9) ^ (t >> 10) ^ (t >> 12) ^ (t >> 13);
- return tmp & 0x00001FFF00001FFF;
- }
- #endif
- /* from libmceliece-20230612/crypto_kem/6688128f/vec/hash.h */
- #define shake crypto_xof_shake256
- #define crypto_hash_32b(out,in,inlen) \
- shake(out,32,in,inlen)
- /* from libmceliece-20230612/crypto_kem/6688128f/vec/int32_sort.h */
- #ifndef int32_sort_h
- #define int32_sort_h
- #define int32_MINMAX(a,b) \
- do { \
- int64_t ab = (int64_t)b ^ (int64_t)a; \
- int64_t c = (int64_t)b - (int64_t)a; \
- c ^= ab & (c ^ b); \
- c >>= 31; \
- c &= ab; \
- a ^= c; \
- b ^= c; \
- } while(0)
- static void int32_sort(int32_t *x,long long n)
- {
- long long top,p,q,r,i;
- if (n < 2) return;
- top = 1;
- while (top < n - top) top += top;
- for (p = top;p > 0;p >>= 1) {
- for (i = 0;i < n - p;++i)
- if (!(i & p))
- int32_MINMAX(x[i],x[i+p]);
- i = 0;
- for (q = top;q > p;q >>= 1) {
- for (;i < n - q;++i) {
- if (!(i & p)) {
- int32_t a = x[i + p];
- for (r = q;r > p;r >>= 1)
- int32_MINMAX(a,x[i+r]);
- x[i + p] = a;
- }
- }
- }
- }
- }
- #endif
- /* from libmceliece-20230612/crypto_kem/6688128f/vec/operations.h */
- #ifndef OPERATIONS_H
- #define OPERATIONS_H
- static void operation_enc(
- unsigned char *c,
- unsigned char *key,
- const unsigned char *pk
- );
- static void operation_dec(
- unsigned char *key,
- const unsigned char *c,
- const unsigned char *sk
- );
- static void operation_keypair
- (
- unsigned char *pk,
- unsigned char *sk
- );
- #endif
- /* from libmceliece-20230612/crypto_kem/6688128f/vec/pk_gen.h */
- /*
- This file is for public-key generation
- */
- #ifndef PK_GEN_H
- #define PK_GEN_H
- static int pk_gen(unsigned char *, const unsigned char *, uint32_t *, int16_t *, uint64_t *);
- #endif
- /* from libmceliece-20230612/crypto_kem/6688128f/vec/sk_gen.h */
- /*
- This file is for secret-key generation
- */
- #ifndef SK_GEN_H
- #define SK_GEN_H
- static int genpoly_gen(gf *, gf *);
- #endif
- /* from libmceliece-20230612/crypto_kem/6688128f/vec/transpose.h */
- /*
- This file is for matrix transposition
- */
- #ifndef TRANSPOSE_H
- #define TRANSPOSE_H
- /* input: in, a 64x64 matrix over GF(2) */
- /* output: out, transpose of in */
- static inline void transpose_64x64(uint64_t * out, uint64_t * in)
- {
- int i, j, s, d;
- uint64_t x, y;
- uint64_t masks[6][2] = {
- {0x5555555555555555, 0xAAAAAAAAAAAAAAAA},
- {0x3333333333333333, 0xCCCCCCCCCCCCCCCC},
- {0x0F0F0F0F0F0F0F0F, 0xF0F0F0F0F0F0F0F0},
- {0x00FF00FF00FF00FF, 0xFF00FF00FF00FF00},
- {0x0000FFFF0000FFFF, 0xFFFF0000FFFF0000},
- {0x00000000FFFFFFFF, 0xFFFFFFFF00000000}
- };
- for (i = 0; i < 64; i++)
- out[i] = in[i];
- for (d = 5; d >= 0; d--)
- {
- s = 1 << d;
- for (i = 0; i < 64; i += s*2)
- for (j = i; j < i+s; j++)
- {
- x = (out[j] & masks[d][0]) | ((out[j+s] & masks[d][0]) << s);
- y = ((out[j] & masks[d][1]) >> s) | (out[j+s] & masks[d][1]);
- out[j+0] = x;
- out[j+s] = y;
- }
- }
- }
- #endif
- /* from libmceliece-20230612/crypto_kem/6688128f/vec/uint16_sort.h */
- #ifndef uint16_sort_h
- #define uint16_sort_h
- #define uint16_MINMAX(a,b) \
- do { \
- uint16_t c = b - a; \
- c >>= 15; \
- c = -c; \
- c &= a ^ b; \
- a ^= c; \
- b ^= c; \
- } while(0)
- static void uint16_sort(uint16_t *x,long long n)
- {
- long long top,p,q,r,i;
- if (n < 2) return;
- top = 1;
- while (top < n - top) top += top;
- for (p = top;p > 0;p >>= 1) {
- for (i = 0;i < n - p;++i)
- if (!(i & p))
- uint16_MINMAX(x[i],x[i+p]);
- i = 0;
- for (q = top;q > p;q >>= 1) {
- for (;i < n - q;++i) {
- if (!(i & p)) {
- int16_t a = x[i + p];
- for (r = q;r > p;r >>= 1)
- uint16_MINMAX(a,x[i+r]);
- x[i + p] = a;
- }
- }
- }
- }
- }
- #endif
- /* from libmceliece-20230612/crypto_kem/6688128f/vec/uint64_sort.h */
- #ifndef uint64_sort_h
- #define uint64_sort_h
- #define uint64_MINMAX(a,b) \
- do { \
- uint64_t c = b - a; \
- c >>= 63; \
- c = -c; \
- c &= a ^ b; \
- a ^= c; \
- b ^= c; \
- } while(0)
- static void uint64_sort(uint64_t *x,long long n)
- {
- long long top,p,q,r,i;
- if (n < 2) return;
- top = 1;
- while (top < n - top) top += top;
- for (p = top;p > 0;p >>= 1) {
- for (i = 0;i < n - p;++i)
- if (!(i & p))
- uint64_MINMAX(x[i],x[i+p]);
- i = 0;
- for (q = top;q > p;q >>= 1) {
- for (;i < n - q;++i) {
- if (!(i & p)) {
- uint64_t a = x[i + p];
- for (r = q;r > p;r >>= 1)
- uint64_MINMAX(a,x[i+r]);
- x[i + p] = a;
- }
- }
- }
- }
- }
- #endif
- /* from libmceliece-20230612/crypto_kem/6688128f/vec/util.h */
- /*
- This file is for loading/storing data in a little-endian fashion
- */
- #ifndef UTIL_H
- #define UTIL_H
- static inline void store_i(unsigned char *out, uint64_t in, int i)
- {
- int j;
- for (j = 0; j < i; j++)
- out[j] = (in >> (j * 8)) & 0xFF;
- }
- static inline void store_gf(unsigned char *dest, uint16_t a)
- {
- dest[0] = a & 0xFF;
- dest[1] = a >> 8;
- }
- static inline uint16_t load_gf(const unsigned char *src)
- {
- uint16_t a;
- a = src[1];
- a <<= 8;
- a |= src[0];
- return a & GFMASK;
- }
- static inline uint32_t load4(const unsigned char *src)
- {
- uint32_t a;
- a = src[3]; a <<= 8;
- a |= src[2]; a <<= 8;
- a |= src[1]; a <<= 8;
- a |= src[0];
- return a;
- }
- static inline void irr_load(vec out[][GFBITS], const unsigned char * in)
- {
- int i, j;
- uint64_t v0 = 0, v1 = 0;
- uint16_t irr[ SYS_T ];
- for (i = 0; i < SYS_T; i++)
- irr[i] = load_gf(in + i*2);
- for (i = 0; i < GFBITS; i++)
- {
- for (j = 63; j >= 0; j--)
- {
- v0 <<= 1;
- v1 <<= 1;
- v0 |= (irr[j] >> i) & 1;
- v1 |= (irr[j+64] >> i) & 1;
- }
- out[0][i] = v0;
- out[1][i] = v1;
- }
- }
- static inline void store8(unsigned char *out, uint64_t in)
- {
- out[0] = (in >> 0x00) & 0xFF;
- out[1] = (in >> 0x08) & 0xFF;
- out[2] = (in >> 0x10) & 0xFF;
- out[3] = (in >> 0x18) & 0xFF;
- out[4] = (in >> 0x20) & 0xFF;
- out[5] = (in >> 0x28) & 0xFF;
- out[6] = (in >> 0x30) & 0xFF;
- out[7] = (in >> 0x38) & 0xFF;
- }
- static inline uint64_t load8(const unsigned char * in)
- {
- int i;
- uint64_t ret = in[7];
- for (i = 6; i >= 0; i--)
- {
- ret <<= 8;
- ret |= in[i];
- }
- return ret;
- }
- #endif
- static void crypto_xof_shake256(unsigned char *h,long long hlen,
- const unsigned char *m,long long mlen)
- {
- gcry_md_hd_t mdh;
- gcry_err_code_t ec;
- ec = _gcry_md_open (&mdh, GCRY_MD_SHAKE256, 0);
- if (ec)
- log_fatal ("internal md_open failed: %d\n", ec);
- _gcry_md_write (mdh, m, mlen);
- _gcry_md_extract (mdh, GCRY_MD_SHAKE256, h, hlen);
- _gcry_md_close (mdh);
- }
- /* from libmceliece-20230612/crypto_kem/6688128f/vec/benes.c */
- /*
- This file is for Benes network related functions
- For the implementation strategy, see
- https://eprint.iacr.org/2017/793.pdf
- */
- /* 20221230 djb: add linker lines */
- /* linker define benes */
- /* middle layers of the benes network */
- static void layer_in(uint64_t data[2][64], uint64_t * bits, int lgs)
- {
- int i, j, s;
- uint64_t d;
- s = 1 << lgs;
- for (i = 0; i < 64; i += s*2)
- for (j = i; j < i+s; j++)
- {
- d = (data[0][j+0] ^ data[0][j+s]);
- d &= (*bits++);
- data[0][j+0] ^= d;
- data[0][j+s] ^= d;
- d = (data[1][j+0] ^ data[1][j+s]);
- d &= (*bits++);
- data[1][j+0] ^= d;
- data[1][j+s] ^= d;
- }
- }
- /* first and last layers of the benes network */
- static void layer_ex(uint64_t * data, uint64_t * bits, int lgs)
- {
- int i, j, s;
- uint64_t d;
- s = 1 << lgs;
- for (i = 0; i < 128; i += s*2)
- for (j = i; j < i+s; j++)
- {
- d = (data[j+0] ^ data[j+s]);
- d &= (*bits++);
- data[j+0] ^= d;
- data[j+s] ^= d;
- }
- }
- /* input: r, sequence of bits to be permuted */
- /* bits, condition bits of the Benes network */
- /* rev, 0 for normal application; !0 for inverse */
- /* output: r, permuted bits */
- static void benes(vec * r, const unsigned char * bits, int rev)
- {
- int i, iter, inc;
- const unsigned char *bits_ptr;
- uint64_t r_int_v[2][64];
- uint64_t r_int_h[2][64];
- uint64_t b_int_v[64];
- uint64_t b_int_h[64];
- /**/
- if (rev) { bits_ptr = bits + 12288; inc = -1024; }
- else { bits_ptr = bits; inc = 0; }
- for (i = 0; i < 64; i++)
- {
- r_int_v[0][i] = r[i*2 + 0];
- r_int_v[1][i] = r[i*2 + 1];
- }
- transpose_64x64(r_int_h[0], r_int_v[0]);
- transpose_64x64(r_int_h[1], r_int_v[1]);
- for (iter = 0; iter <= 6; iter++)
- {
- for (i = 0; i < 64; i++)
- {
- b_int_v[i] = load8(bits_ptr); bits_ptr += 8;
- }
- bits_ptr += inc;
- transpose_64x64(b_int_h, b_int_v);
- layer_ex(r_int_h[0], b_int_h, iter);
- }
- transpose_64x64(r_int_v[0], r_int_h[0]);
- transpose_64x64(r_int_v[1], r_int_h[1]);
- for (iter = 0; iter <= 5; iter++)
- {
- for (i = 0; i < 64; i++) { b_int_v[i] = load8(bits_ptr); bits_ptr += 8; }
- bits_ptr += inc;
- layer_in(r_int_v, b_int_v, iter);
- }
- for (iter = 4; iter >= 0; iter--)
- {
- for (i = 0; i < 64; i++) { b_int_v[i] = load8(bits_ptr); bits_ptr += 8; }
- bits_ptr += inc;
- layer_in(r_int_v, b_int_v, iter);
- }
- transpose_64x64(r_int_h[0], r_int_v[0]);
- transpose_64x64(r_int_h[1], r_int_v[1]);
- for (iter = 6; iter >= 0; iter--)
- {
- for (i = 0; i < 64; i++)
- {
- b_int_v[i] = load8(bits_ptr); bits_ptr += 8;
- }
- bits_ptr += inc;
- transpose_64x64(b_int_h, b_int_v);
- layer_ex(r_int_h[0], b_int_h, iter);
- }
- transpose_64x64(r_int_v[0], r_int_h[0]);
- transpose_64x64(r_int_v[1], r_int_h[1]);
- for (i = 0; i < 64; i++)
- {
- r[i*2+0] = r_int_v[0][i];
- r[i*2+1] = r_int_v[1][i];
- }
- }
- /* from libmceliece-20230612/crypto_kem/6688128f/vec/bm.c */
- /*
- This file is for implementating the inversion-free Berlekamp-Massey algorithm
- see https://ieeexplore.ieee.org/document/87857
- For the implementation strategy, see
- https://eprint.iacr.org/2017/793.pdf
- */
- /* 20221230 djb: add linker lines */
- /* linker define bm */
- /* linker use vec_mul */
- /* linker use gf_inv */
- static inline uint16_t mask_nonzero(gf a)
- {
- uint32_t ret = a;
- ret -= 1;
- ret >>= 31;
- ret -= 1;
- return ret;
- }
- static inline uint16_t mask_leq(uint16_t a, uint16_t b)
- {
- uint32_t a_tmp = a;
- uint32_t b_tmp = b;
- uint32_t ret = b_tmp - a_tmp;
- ret >>= 31;
- ret -= 1;
- return ret;
- }
- static inline void vec_cmov(vec * out, vec * in, uint16_t mask)
- {
- int i;
- vec m0, m1;
- m0 = vec_set1_16b(mask);
- m1 = ~m0;
- for (i = 0; i < GFBITS; i++)
- {
- out[i] = (in[i] & m0) | (out[i] & m1);
- out[i] = (in[i] & m0) | (out[i] & m1);
- }
- }
- static inline void interleave(vec *in, int idx0, int idx1, vec *mask, int b)
- {
- int s = 1 << b;
- vec x, y;
- x = (in[idx0] & mask[0]) | ((in[idx1] & mask[0]) << s);
- y = ((in[idx0] & mask[1]) >> s) | (in[idx1] & mask[1]);
- in[idx0] = x;
- in[idx1] = y;
- }
- /* input: in, field elements in bitsliced form */
- /* output: out, field elements in non-bitsliced form */
- static inline void get_coefs(gf *out, vec *in)
- {
- int i, k;
- vec mask[4][2];
- vec buf[16];
- for (i = 0; i < 13; i++) buf[i] = in[i];
- for (i = 13; i < 16; i++) buf[i] = 0;
- mask[0][0] = vec_set1_16b(0x5555);
- mask[0][1] = vec_set1_16b(0xAAAA);
- mask[1][0] = vec_set1_16b(0x3333);
- mask[1][1] = vec_set1_16b(0xCCCC);
- mask[2][0] = vec_set1_16b(0x0F0F);
- mask[2][1] = vec_set1_16b(0xF0F0);
- mask[3][0] = vec_set1_16b(0x00FF);
- mask[3][1] = vec_set1_16b(0xFF00);
- interleave(buf, 0, 8, mask[3], 3);
- interleave(buf, 1, 9, mask[3], 3);
- interleave(buf, 2, 10, mask[3], 3);
- interleave(buf, 3, 11, mask[3], 3);
- interleave(buf, 4, 12, mask[3], 3);
- interleave(buf, 5, 13, mask[3], 3);
- interleave(buf, 6, 14, mask[3], 3);
- interleave(buf, 7, 15, mask[3], 3);
- interleave(buf, 0, 4, mask[2], 2);
- interleave(buf, 1, 5, mask[2], 2);
- interleave(buf, 2, 6, mask[2], 2);
- interleave(buf, 3, 7, mask[2], 2);
- interleave(buf, 8, 12, mask[2], 2);
- interleave(buf, 9, 13, mask[2], 2);
- interleave(buf, 10, 14, mask[2], 2);
- interleave(buf, 11, 15, mask[2], 2);
- interleave(buf, 0, 2, mask[1], 1);
- interleave(buf, 1, 3, mask[1], 1);
- interleave(buf, 4, 6, mask[1], 1);
- interleave(buf, 5, 7, mask[1], 1);
- interleave(buf, 8, 10, mask[1], 1);
- interleave(buf, 9, 11, mask[1], 1);
- interleave(buf, 12, 14, mask[1], 1);
- interleave(buf, 13, 15, mask[1], 1);
- interleave(buf, 0, 1, mask[0], 0);
- interleave(buf, 2, 3, mask[0], 0);
- interleave(buf, 4, 5, mask[0], 0);
- interleave(buf, 6, 7, mask[0], 0);
- interleave(buf, 8, 9, mask[0], 0);
- interleave(buf, 10, 11, mask[0], 0);
- interleave(buf, 12, 13, mask[0], 0);
- interleave(buf, 14, 15, mask[0], 0);
- for (i = 0; i < 16; i++)
- for (k = 0; k < 4; k++)
- out[ k*16 + i ] = (buf[i] >> (k*16)) & GFMASK;
- }
- static void update(vec in[][GFBITS], const gf e)
- {
- int i;
- vec tmp;
- for (i = 0; i < GFBITS; i++)
- {
- tmp = (e >> i) & 1;
- in[0][i] = (in[0][i] >> 1) | (in[1][i] << 63);
- in[1][i] = (in[1][i] >> 1) | (tmp << 63);
- }
- }
- static inline gf vec_reduce(vec in[][GFBITS])
- {
- int i;
- vec tmp;
- gf ret = 0;
- for (i = GFBITS-1; i >= 0; i--)
- {
- tmp = in[0][i] ^ in[1][i];
- tmp ^= tmp >> 32;
- tmp ^= tmp >> 16;
- tmp ^= tmp >> 8;
- tmp ^= tmp >> 4;
- tmp ^= tmp >> 2;
- tmp ^= tmp >> 1;
- ret <<= 1;
- ret |= tmp & 1;
- }
- return ret;
- }
- /* input: in, sequence of field elements */
- /* output: out, minimal polynomial of in */
- static void bm(vec out[][ GFBITS ], vec in[][ GFBITS ])
- {
- int i;
- uint16_t N, L;
- uint16_t mask;
- uint64_t one = 1, t;
- vec prod[2][GFBITS];
- vec interval[2][GFBITS];
- vec dd[2][GFBITS], bb[2][GFBITS];
- vec B[2][GFBITS], C[2][GFBITS];
- vec B_tmp[2][GFBITS], C_tmp[2][GFBITS];
- vec v[GFBITS];
- gf d, b, c0 = 1;
- gf coefs[256];
- /* initialization */
- get_coefs(&coefs[ 0], in[0]);
- get_coefs(&coefs[ 64], in[1]);
- get_coefs(&coefs[128], in[2]);
- get_coefs(&coefs[192], in[3]);
- C[0][0] = 0;
- C[1][0] = 0;
- B[0][0] = 0;
- B[1][0] = one << 63;
- for (i = 1; i < GFBITS; i++)
- C[0][i] = C[1][i] = B[0][i] = B[1][i] = 0;
- b = 1;
- L = 0;
- /**/
- for (i = 0; i < GFBITS; i++)
- interval[0][i] = interval[1][i] = 0;
- for (N = 0; N < 256; N++)
- {
- vec_mul(prod[0], C[0], interval[0]);
- vec_mul(prod[1], C[1], interval[1]);
- update(interval, coefs[N]);
- d = vec_reduce(prod);
- t = gf_mul2(c0, coefs[N], b);
- d ^= t & 0xFFFFFFFF;
- mask = mask_nonzero(d) & mask_leq(L*2, N);
- for (i = 0; i < GFBITS; i++)
- {
- dd[0][i] = dd[1][i] = vec_setbits((d >> i) & 1);
- bb[0][i] = bb[1][i] = vec_setbits((b >> i) & 1);
- }
- vec_mul(B_tmp[0], dd[0], B[0]);
- vec_mul(B_tmp[1], dd[1], B[1]);
- vec_mul(C_tmp[0], bb[0], C[0]);
- vec_mul(C_tmp[1], bb[1], C[1]);
- vec_cmov(B[0], C[0], mask);
- vec_cmov(B[1], C[1], mask);
- update(B, c0 & mask);
- for (i = 0; i < GFBITS; i++)
- {
- C[0][i] = B_tmp[0][i] ^ C_tmp[0][i];
- C[1][i] = B_tmp[1][i] ^ C_tmp[1][i];
- }
- c0 = t >> 32;
- b = (d & mask) | (b & ~mask);
- L = ((N+1-L) & mask) | (L & ~mask);
- }
- c0 = gf_inv(c0);
- for (i = 0; i < GFBITS; i++)
- v[i] = vec_setbits((c0 >> i) & 1);
- vec_mul(out[0], C[0], v);
- vec_mul(out[1], C[1], v);
- }
- /* from libmceliece-20230612/crypto_kem/6688128f/vec/controlbits.c */
- /* This file is for implementing the Nassimi-Sahni algorithm */
- /* See David Nassimi, Sartaj Sahni "Parallel algorithms to set up the Benes permutationnetwork" */
- /* See also https://cr.yp.to/papers/controlbits-20200923.pdf */
- /* 20221230 djb: add linker line */
- /* linker define controlbitsfrompermutation */
- typedef int16_t int16;
- typedef int32_t int32;
- #define int32_min crypto_int32_min
- /* parameters: 1 <= w <= 14; n = 2^w */
- /* input: permutation pi of {0,1,...,n-1} */
- /* output: (2m-1)n/2 control bits at positions pos,pos+step,... */
- /* output position pos is by definition 1&(out[pos/8]>>(pos&7)) */
- /* caller must 0-initialize positions first */
- /* temp must have space for int32[2*n] */
- static void cbrecursion(unsigned char *out,long long pos,long long step,const int16 *pi,long long w,long long n,int32 *temp)
- {
- #define A temp
- #define B (temp+n)
- #define q ((int16 *) (temp+n+n/4))
- /* q can start anywhere between temp+n and temp+n/2 */
- long long x,i,j,k;
- if (w == 1) {
- out[pos>>3] ^= pi[0]<<(pos&7);
- return;
- }
- for (x = 0;x < n;++x) A[x] = ((pi[x]^1)<<16)|pi[x^1];
- int32_sort(A,n); /* A = (id<<16)+pibar */
- for (x = 0;x < n;++x) {
- int32 Ax = A[x];
- int32 px = Ax&0xffff;
- int32 cx = int32_min(px,x);
- B[x] = (px<<16)|cx;
- }
- /* B = (p<<16)+c */
- for (x = 0;x < n;++x) A[x] = (A[x]<<16)|x; /* A = (pibar<<16)+id */
- int32_sort(A,n); /* A = (id<<16)+pibar^-1 */
- for (x = 0;x < n;++x) A[x] = (A[x]<<16)+(B[x]>>16); /* A = (pibar^(-1)<<16)+pibar */
- int32_sort(A,n); /* A = (id<<16)+pibar^2 */
- if (w <= 10) {
- for (x = 0;x < n;++x) B[x] = ((A[x]&0xffff)<<10)|(B[x]&0x3ff);
- for (i = 1;i < w-1;++i) {
- /* B = (p<<10)+c */
- for (x = 0;x < n;++x) A[x] = ((B[x]&~0x3ff)<<6)|x; /* A = (p<<16)+id */
- int32_sort(A,n); /* A = (id<<16)+p^{-1} */
- for (x = 0;x < n;++x) A[x] = (A[x]<<20)|B[x]; /* A = (p^{-1}<<20)+(p<<10)+c */
- int32_sort(A,n); /* A = (id<<20)+(pp<<10)+cp */
- for (x = 0;x < n;++x) {
- int32 ppcpx = A[x]&0xfffff;
- int32 ppcx = (A[x]&0xffc00)|(B[x]&0x3ff);
- B[x] = int32_min(ppcx,ppcpx);
- }
- }
- for (x = 0;x < n;++x) B[x] &= 0x3ff;
- } else {
- for (x = 0;x < n;++x) B[x] = (A[x]<<16)|(B[x]&0xffff);
- for (i = 1;i < w-1;++i) {
- /* B = (p<<16)+c */
- for (x = 0;x < n;++x) A[x] = (B[x]&~0xffff)|x;
- int32_sort(A,n); /* A = (id<<16)+p^(-1) */
- for (x = 0;x < n;++x) A[x] = (A[x]<<16)|(B[x]&0xffff);
- /* A = p^(-1)<<16+c */
- if (i < w-2) {
- for (x = 0;x < n;++x) B[x] = (A[x]&~0xffff)|(B[x]>>16);
- /* B = (p^(-1)<<16)+p */
- int32_sort(B,n); /* B = (id<<16)+p^(-2) */
- for (x = 0;x < n;++x) B[x] = (B[x]<<16)|(A[x]&0xffff);
- /* B = (p^(-2)<<16)+c */
- }
- int32_sort(A,n);
- /* A = id<<16+cp */
- for (x = 0;x < n;++x) {
- int32 cpx = (B[x]&~0xffff)|(A[x]&0xffff);
- B[x] = int32_min(B[x],cpx);
- }
- }
- for (x = 0;x < n;++x) B[x] &= 0xffff;
- }
- for (x = 0;x < n;++x) A[x] = (((int32)pi[x])<<16)+x;
- int32_sort(A,n); /* A = (id<<16)+pi^(-1) */
- for (j = 0;j < n/2;++j) {
- long long lx = 2*j;
- int32 fj = B[lx]&1; /* f[j] */
- int32 Fx = lx+fj; /* F[x] */
- int32 Fx1 = Fx^1; /* F[x+1] */
- out[pos>>3] ^= fj<<(pos&7);
- pos += step;
- B[lx] = (A[lx]<<16)|Fx;
- B[lx+1] = (A[lx+1]<<16)|Fx1;
- }
- /* B = (pi^(-1)<<16)+F */
- int32_sort(B,n); /* B = (id<<16)+F(pi) */
- pos += (2*w-3)*step*(n/2);
- for (k = 0;k < n/2;++k) {
- long long y = 2*k;
- int32 lk = B[y]&1; /* l[k] */
- int32 Ly = y+lk; /* L[y] */
- int32 Ly1 = Ly^1; /* L[y+1] */
- out[pos>>3] ^= lk<<(pos&7);
- pos += step;
- A[y] = (Ly<<16)|(B[y]&0xffff);
- A[y+1] = (Ly1<<16)|(B[y+1]&0xffff);
- }
- /* A = (L<<16)+F(pi) */
- int32_sort(A,n); /* A = (id<<16)+F(pi(L)) = (id<<16)+M */
- pos -= (2*w-2)*step*(n/2);
- for (j = 0;j < n/2;++j) {
- q[j] = (A[2*j]&0xffff)>>1;
- q[j+n/2] = (A[2*j+1]&0xffff)>>1;
- }
- cbrecursion(out,pos,step*2,q,w-1,n/2,temp);
- cbrecursion(out,pos+step,step*2,q+n/2,w-1,n/2,temp);
- }
- /* input: p, an array of int16 */
- /* input: n, length of p */
- /* input: s, meaning that stride-2^s cswaps are performed */
- /* input: cb, the control bits */
- /* output: the result of apply the control bits to p */
- static void layer(int16_t *p, const unsigned char *cb, int s, int n)
- {
- int i, j;
- int stride = 1 << s;
- int index = 0;
- int16_t d, m;
- for (i = 0; i < n; i += stride*2)
- {
- for (j = 0; j < stride; j++)
- {
- d = p[ i+j ] ^ p[ i+j+stride ];
- m = (cb[ index >> 3 ] >> (index & 7)) & 1;
- m = -m;
- d &= m;
- p[ i+j ] ^= d;
- p[ i+j+stride ] ^= d;
- index++;
- }
- }
- }
- /* parameters: 1 <= w <= 14; n = 2^w */
- /* input: permutation pi of {0,1,...,n-1} */
- /* output: (2m-1)n/2 control bits at positions 0,1,... */
- /* output position pos is by definition 1&(out[pos/8]>>(pos&7)) */
- static void controlbitsfrompermutation(unsigned char *out,const int16 *pi,long long w,long long n)
- {
- int32 temp[2*n];
- int16 pi_test[n], diff;
- int i;
- unsigned char *ptr;
- while (1)
- {
- memset(out,0,(((2*w-1)*n/2)+7)/8);
- cbrecursion(out,0,1,pi,w,n,temp);
- /* check for correctness */
- for (i = 0; i < n; i++)
- pi_test[i] = i;
- ptr = out;
- for (i = 0; i < w; i++)
- {
- layer(pi_test, ptr, i, n);
- ptr += n >> 4;
- }
- for (i = w-2; i >= 0; i--)
- {
- layer(pi_test, ptr, i, n);
- ptr += n >> 4;
- }
- diff = 0;
- for (i = 0; i < n; i++)
- diff |= pi[i] ^ pi_test[i];
- diff = crypto_int16_nonzero_mask(diff);
- crypto_declassify(&diff,sizeof diff);
- if (diff == 0)
- break;
- }
- }
- #undef A
- #undef B
- #undef q
- /* from libmceliece-20230612/crypto_kem/6688128f/vec/decrypt.c */
- /*
- This file is for Niederreiter decryption
- */
- /* 20221230 djb: add linker lines */
- /* linker define decrypt */
- /* linker use benes bm fft fft_tr */
- /* linker use vec_mul vec_sq vec_inv */
- static void scaling(vec out[][GFBITS], vec inv[][GFBITS], const unsigned char *sk, vec *recv)
- {
- int i, j;
- vec irr_int[2][ GFBITS ];
- vec eval[128][ GFBITS ];
- vec tmp[ GFBITS ];
- /**/
- irr_load(irr_int, sk);
- fft(eval, irr_int);
- for (i = 0; i < 128; i++)
- vec_sq(eval[i], eval[i]);
- vec_copy(inv[0], eval[0]);
- for (i = 1; i < 128; i++)
- vec_mul(inv[i], inv[i-1], eval[i]);
- vec_inv(tmp, inv[127]);
- for (i = 126; i >= 0; i--)
- {
- vec_mul(inv[i+1], tmp, inv[i]);
- vec_mul(tmp, tmp, eval[i+1]);
- }
- vec_copy(inv[0], tmp);
- /**/
- for (i = 0; i < 128; i++)
- for (j = 0; j < GFBITS; j++)
- out[i][j] = inv[i][j] & recv[i];
- }
- static void preprocess(vec *recv, const unsigned char *s)
- {
- int i;
- unsigned char r[ 1024 ];
- for (i = 0; i < SYND_BYTES; i++)
- r[i] = s[i];
- for (i = SYND_BYTES; i < 1024; i++)
- r[i] = 0;
- for (i = 0; i < 128; i++)
- recv[i] = load8(r + i*8);
- }
- static void postprocess(unsigned char * e, vec * err)
- {
- int i;
- unsigned char error8[ (1 << GFBITS)/8 ];
- for (i = 0; i < 128; i++)
- store8(error8 + i*8, err[i]);
- for (i = 0; i < SYS_N/8; i++)
- e[i] = error8[i];
- }
- static void scaling_inv(vec out[][GFBITS], vec inv[][GFBITS], vec *recv)
- {
- int i, j;
- for (i = 0; i < 128; i++)
- for (j = 0; j < GFBITS; j++)
- out[i][j] = inv[i][j] & recv[i];
- }
- static int weight_check(unsigned char * e, vec * error)
- {
- int i;
- uint16_t w0 = 0;
- uint16_t w1 = 0;
- uint16_t check;
- for (i = 0; i < (1 << GFBITS); i++)
- w0 += (error[i/64] >> (i%64)) & 1;
- for (i = 0; i < SYS_N; i++)
- w1 += (e[i/8] >> (i%8)) & 1;
- check = (w0 ^ SYS_T) | (w1 ^ SYS_T);
- check -= 1;
- check >>= 15;
- return check;
- }
- static uint16_t synd_cmp(vec s0[][ GFBITS ] , vec s1[][ GFBITS ])
- {
- int i, j;
- vec diff = 0;
- for (i = 0; i < 4; i++)
- for (j = 0; j < GFBITS; j++)
- diff |= (s0[i][j] ^ s1[i][j]);
- return vec_testz(diff);
- }
- /* Niederreiter decryption with the Berlekamp decoder */
- /* intput: sk, secret key */
- /* s, ciphertext (syndrome) */
- /* output: e, error vector */
- /* return: 0 for success; 1 for failure */
- static int decrypt(unsigned char *e, const unsigned char *sk, const unsigned char *s)
- {
- int i;
- uint16_t check_synd;
- uint16_t check_weight;
- vec inv[ 128 ][ GFBITS ];
- vec scaled[ 128 ][ GFBITS ];
- vec eval[ 128 ][ GFBITS ];
- vec error[ 128 ];
- vec s_priv[ 4 ][ GFBITS ];
- vec s_priv_cmp[ 4 ][ GFBITS ];
- vec locator[2][ GFBITS ];
- vec recv[ 128 ];
- vec allone;
- /* Berlekamp decoder */
- preprocess(recv, s);
- benes(recv, sk + IRR_BYTES, 1);
- scaling(scaled, inv, sk, recv);
- fft_tr(s_priv, scaled);
- bm(locator, s_priv);
- fft(eval, locator);
- /* reencryption and weight check */
- allone = vec_setbits(1);
- for (i = 0; i < 128; i++)
- {
- error[i] = vec_or_reduce(eval[i]);
- error[i] ^= allone;
- }
- scaling_inv(scaled, inv, error);
- fft_tr(s_priv_cmp, scaled);
- check_synd = synd_cmp(s_priv, s_priv_cmp);
- /**/
- benes(error, sk + IRR_BYTES, 0);
- postprocess(e, error);
- check_weight = weight_check(e, error);
- #ifdef KAT
- {
- int k;
- printf("decrypt e: positions");
- for (k = 0;k < SYS_N;++k)
- if (e[k/8] & (1 << (k&7)))
- printf(" %d",k);
- printf("\n");
- }
- #endif
- return 1 - (check_synd & check_weight);
- }
- /* from libmceliece-20230612/crypto_kem/6688128f/vec/encrypt.c */
- /* 20230102 djb: rename encrypt() as pke_encrypt() */
- /* 20221231 djb: move encrypt.h last for macos portability; tnx thom wiggers */
- /* 20221230 djb: add linker line */
- /* linker define pke_encrypt */
- /*
- This file is for Niederreiter encryption
- */
- static inline crypto_uint16 uint16_is_smaller_declassify(uint16_t t,uint16_t u)
- {
- crypto_uint16 mask = crypto_uint16_smaller_mask(t,u);
- crypto_declassify(&mask,sizeof mask);
- return mask;
- }
- static inline crypto_uint32 uint32_is_equal_declassify(uint32_t t,uint32_t u)
- {
- crypto_uint32 mask = crypto_uint32_equal_mask(t,u);
- crypto_declassify(&mask,sizeof mask);
- return mask;
- }
- /* output: e, an error vector of weight t */
- static void gen_e(unsigned char *e)
- {
- int i, j, eq, count;
- union
- {
- uint16_t nums[ SYS_T*2 ];
- unsigned char bytes[ SYS_T*2 * sizeof(uint16_t) ];
- } buf;
- uint16_t ind[ SYS_T ];
- uint64_t e_int[ (SYS_N+63)/64 ];
- uint64_t one = 1;
- uint64_t mask;
- uint64_t val[ SYS_T ];
- while (1)
- {
- randombytes(buf.bytes, sizeof(buf));
- for (i = 0; i < SYS_T*2; i++)
- buf.nums[i] = load_gf(buf.bytes + i*2);
- /* moving and counting indices in the correct range */
- count = 0;
- for (i = 0; i < SYS_T*2 && count < SYS_T; i++)
- if (uint16_is_smaller_declassify(buf.nums[i],SYS_N))
- ind[ count++ ] = buf.nums[i];
- if (count < SYS_T) continue;
- /* check for repetition */
- uint16_sort(ind, SYS_T);
- eq = 0;
- for (i = 1; i < SYS_T; i++)
- if (uint32_is_equal_declassify(ind[i-1],ind[i]))
- eq = 1;
- if (eq == 0)
- break;
- }
- for (j = 0; j < SYS_T; j++)
- val[j] = one << (ind[j] & 63);
- for (i = 0; i < (SYS_N+63)/64; i++)
- {
- e_int[i] = 0;
- for (j = 0; j < SYS_T; j++)
- {
- mask = i ^ (ind[j] >> 6);
- mask -= 1;
- mask >>= 63;
- mask = -mask;
- e_int[i] |= val[j] & mask;
- }
- }
- for (i = 0; i < (SYS_N+63)/64 - 1; i++)
- { store8(e, e_int[i]); e += 8; }
- for (j = 0; j < (SYS_N % 64); j+=8)
- e[ j/8 ] = (e_int[i] >> j) & 0xFF;
- }
- /* input: public key pk, error vector e */
- /* output: syndrome s */
- static void syndrome(unsigned char *s, const unsigned char *pk, unsigned char *e)
- {
- uint64_t b;
- const uint64_t *pk_ptr;
- const uint64_t *e_ptr = ((uint64_t *) (e + SYND_BYTES));
- int i, j;
- /**/
- for (i = 0; i < SYND_BYTES; i++)
- s[i] = e[i];
- for (i = 0; i < PK_NROWS; i++)
- {
- pk_ptr = ((uint64_t *) (pk + PK_ROW_BYTES * i));
- b = 0;
- for (j = 0; j < PK_NCOLS/64; j++)
- b ^= pk_ptr[j] & e_ptr[j];
- b ^= ((uint32_t *) &pk_ptr[j])[0] & ((uint32_t *) &e_ptr[j])[0];
- b ^= b >> 32;
- b ^= b >> 16;
- b ^= b >> 8;
- b ^= b >> 4;
- b ^= b >> 2;
- b ^= b >> 1;
- b &= 1;
- s[ i/8 ] ^= (b << (i%8));
- }
- }
- /* input: public key pk */
- /* output: error vector e, syndrome s */
- static void pke_encrypt(unsigned char *s, const unsigned char *pk, unsigned char *e)
- {
- gen_e(e);
- #ifdef KAT
- {
- int k;
- printf("encrypt e: positions");
- for (k = 0;k < SYS_N;++k)
- if (e[k/8] & (1 << (k&7)))
- printf(" %d",k);
- printf("\n");
- }
- #endif
- syndrome(s, pk, e);
- }
- /* from libmceliece-20230612/crypto_kem/6688128f/vec/shared-fft_consts.c */
- /* linker define fft_consts */
- const vec fft_consts[128][GFBITS] = {
- { 0x6969969669699696, 0x9966669966999966, 0x9966669966999966, 0xFF0000FF00FFFF00, 0xCC3333CCCC3333CC, 0x9966669966999966, 0x6666666666666666, 0xA55AA55AA55AA55A, 0xCCCC33333333CCCC, 0x5A5A5A5A5A5A5A5A, 0x55AAAA55AA5555AA, 0x0FF0F00FF00F0FF0, 0x5AA55AA5A55AA55A }, { 0x6969969669699696, 0x9966669966999966, 0x9966669966999966, 0xFF0000FF00FFFF00, 0xCC3333CCCC3333CC, 0x9966669966999966, 0x6666666666666666, 0xA55AA55AA55AA55A, 0xCCCC33333333CCCC, 0x5A5A5A5A5A5A5A5A, 0x55AAAA55AA5555AA, 0x0FF0F00FF00F0FF0, 0x5AA55AA5A55AA55A }, { 0xA55A5AA55AA5A55A, 0x6969696996969696, 0x5AA55AA5A55AA55A, 0x9999999966666666, 0x3C3CC3C3C3C33C3C, 0xFFFF0000FFFF0000, 0x0000000000000000, 0xCC33CC3333CC33CC, 0x0000000000000000, 0x3C3C3C3C3C3C3C3C, 0xAA5555AAAA5555AA, 0xC33C3CC33CC3C33C, 0x00FFFF0000FFFF00 }, { 0xA55A5AA55AA5A55A, 0x6969696996969696, 0x5AA55AA5A55AA55A, 0x6666666699999999, 0xC3C33C3C3C3CC3C3, 0x0000FFFF0000FFFF, 0x0000000000000000, 0x33CC33CCCC33CC33, 0x0000000000000000, 0x3C3C3C3C3C3C3C3C, 0xAA5555AAAA5555AA, 0xC33C3CC33CC3C33C, 0xFF0000FFFF0000FF }, { 0xFFFFFFFF00000000, 0xA5A5A5A55A5A5A5A, 0x0FF0F00FF00F0FF0, 0x9669966969966996, 0x0000FFFFFFFF0000, 0x33333333CCCCCCCC, 0xA55A5AA55AA5A55A, 0x00FFFF0000FFFF00, 0x0000000000000000, 0xC33CC33CC33CC33C, 0x0F0FF0F00F0FF0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAA55555555AAAA }, { 0xFFFFFFFF00000000, 0xA5A5A5A55A5A5A5A, 0x0FF0F00FF00F0FF0, 0x6996699696699669, 0xFFFF00000000FFFF, 0x33333333CCCCCCCC, 0x5AA5A55AA55A5AA5, 0xFF0000FFFF0000FF, 0xFFFFFFFFFFFFFFFF, 0xC33CC33CC33CC33C, 0x0F0FF0F00F0FF0F0, 0xCCCCCCCCCCCCCCCC, 0x5555AAAAAAAA5555 }, { 0xFFFFFFFF00000000, 0x5A5A5A5AA5A5A5A5, 0xF00F0FF00FF0F00F, 0x6996699696699669, 0x0000FFFFFFFF0000, 0x33333333CCCCCCCC, 0x5AA5A55AA55A5AA5, 0xFF0000FFFF0000FF, 0xFFFFFFFFFFFFFFFF, 0xC33CC33CC33CC33C, 0x0F0FF0F00F0FF0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAA55555555AAAA }, { 0xFFFFFFFF00000000, 0x5A5A5A5AA5A5A5A5, 0xF00F0FF00FF0F00F, 0x9669966969966996, 0xFFFF00000000FFFF, 0x33333333CCCCCCCC, 0xA55A5AA55AA5A55A, 0x00FFFF0000FFFF00, 0x0000000000000000, 0xC33CC33CC33CC33C, 0x0F0FF0F00F0FF0F0, 0xCCCCCCCCCCCCCCCC, 0x5555AAAAAAAA5555 }, { 0xC33C3CC33CC3C33C, 0x9966669966999966, 0x9966996699669966, 0x6969969669699696, 0xAA55AA5555AA55AA, 0x9966996699669966, 0x5AA5A55A5AA5A55A, 0xC3C3C3C33C3C3C3C, 0x3CC33CC3C33CC33C, 0x3333CCCC3333CCCC, 0x9999999966666666, 0xC33CC33CC33CC33C, 0x6666999999996666 }, { 0x3CC3C33CC33C3CC3, 0x6699996699666699, 0x6699669966996699, 0x6969969669699696, 0xAA55AA5555AA55AA, 0x9966996699669966, 0xA55A5AA5A55A5AA5, 0xC3C3C3C33C3C3C3C, 0x3CC33CC3C33CC33C, 0x3333CCCC3333CCCC, 0x6666666699999999, 0x3CC33CC33CC33CC3, 0x9999666666669999 }, { 0xC33C3CC33CC3C33C, 0x9966669966999966, 0x6699669966996699, 0x6969969669699696, 0xAA55AA5555AA55AA, 0x6699669966996699, 0x5AA5A55A5AA5A55A, 0x3C3C3C3CC3C3C3C3, 0xC33CC33C3CC33CC3, 0xCCCC3333CCCC3333, 0x6666666699999999, 0xC33CC33CC33CC33C, 0x9999666666669999 }, { 0x3CC3C33CC33C3CC3, 0x6699996699666699, 0x9966996699669966, 0x6969969669699696, 0xAA55AA5555AA55AA, 0x6699669966996699, 0xA55A5AA5A55A5AA5, 0x3C3C3C3CC3C3C3C3, 0xC33CC33C3CC33CC3, 0xCCCC3333CCCC3333, 0x9999999966666666, 0x3CC33CC33CC33CC3, 0x6666999999996666 }, { 0xC33C3CC33CC3C33C, 0x6699996699666699, 0x6699669966996699, 0x6969969669699696, 0x55AA55AAAA55AA55, 0x9966996699669966, 0x5AA5A55A5AA5A55A, 0xC3C3C3C33C3C3C3C, 0xC33CC33C3CC33CC3, 0x3333CCCC3333CCCC, 0x9999999966666666, 0xC33CC33CC33CC33C, 0x6666999999996666 }, { 0x3CC3C33CC33C3CC3, 0x9966669966999966, 0x9966996699669966, 0x6969969669699696, 0x55AA55AAAA55AA55, 0x9966996699669966, 0xA55A5AA5A55A5AA5, 0xC3C3C3C33C3C3C3C, 0xC33CC33C3CC33CC3, 0x3333CCCC3333CCCC, 0x6666666699999999, 0x3CC33CC33CC33CC3, 0x9999666666669999 }, { 0xC33C3CC33CC3C33C, 0x6699996699666699, 0x9966996699669966, 0x6969969669699696, 0x55AA55AAAA55AA55, 0x6699669966996699, 0x5AA5A55A5AA5A55A, 0x3C3C3C3CC3C3C3C3, 0x3CC33CC3C33CC33C, 0xCCCC3333CCCC3333, 0x6666666699999999, 0xC33CC33CC33CC33C, 0x9999666666669999 }, { 0x3CC3C33CC33C3CC3, 0x9966669966999966, 0x6699669966996699, 0x6969969669699696, 0x55AA55AAAA55AA55, 0x6699669966996699, 0xA55A5AA5A55A5AA5, 0x3C3C3C3CC3C3C3C3, 0x3CC33CC3C33CC33C, 0xCCCC3333CCCC3333, 0x9999999966666666, 0x3CC33CC33CC33CC3, 0x6666999999996666 }, { 0x3C3CC3C3C3C33C3C, 0x55555555AAAAAAAA, 0xF00FF00F0FF00FF0, 0x5AA55AA5A55AA55A, 0x55AAAA55AA5555AA, 0xF00F0FF0F00F0FF0, 0x9669699696696996, 0xA55AA55AA55AA55A, 0x55555555AAAAAAAA, 0xCCCC33333333CCCC, 0x0000FFFFFFFF0000, 0xFF0000FF00FFFF00, 0x6996699669966996 }, { 0xC3C33C3C3C3CC3C3, 0x55555555AAAAAAAA, 0x0FF00FF0F00FF00F, 0x5AA55AA5A55AA55A, 0x55AAAA55AA5555AA, 0xF00F0FF0F00F0FF0, 0x9669699696696996, 0x5AA55AA55AA55AA5, 0x55555555AAAAAAAA, 0x3333CCCCCCCC3333, 0x0000FFFFFFFF0000, 0x00FFFF00FF0000FF, 0x9669966996699669 }, { 0x3C3CC3C3C3C33C3C, 0x55555555AAAAAAAA, 0xF00FF00F0FF00FF0, 0xA55AA55A5AA55AA5, 0xAA5555AA55AAAA55, 0x0FF0F00F0FF0F00F, 0x9669699696696996, 0x5AA55AA55AA55AA5, 0xAAAAAAAA55555555, 0x3333CCCCCCCC3333, 0xFFFF00000000FFFF, 0xFF0000FF00FFFF00, 0x9669966996699669 }, { 0xC3C33C3C3C3CC3C3, 0x55555555AAAAAAAA, 0x0FF00FF0F00FF00F, 0xA55AA55A5AA55AA5, 0xAA5555AA55AAAA55, 0x0FF0F00F0FF0F00F, 0x9669699696696996, 0xA55AA55AA55AA55A, 0xAAAAAAAA55555555, 0xCCCC33333333CCCC, 0xFFFF00000000FFFF, 0x00FFFF00FF0000FF, 0x6996699669966996 }, { 0x3C3CC3C3C3C33C3C, 0x55555555AAAAAAAA, 0x0FF00FF0F00FF00F, 0xA55AA55A5AA55AA5, 0xAA5555AA55AAAA55, 0x0FF0F00F0FF0F00F, 0x6996966969969669, 0xA55AA55AA55AA55A, 0xAAAAAAAA55555555, 0xCCCC33333333CCCC, 0x0000FFFFFFFF0000, 0xFF0000FF00FFFF00, 0x6996699669966996 }, { 0xC3C33C3C3C3CC3C3, 0x55555555AAAAAAAA, 0xF00FF00F0FF00FF0, 0xA55AA55A5AA55AA5, 0xAA5555AA55AAAA55, 0x0FF0F00F0FF0F00F, 0x6996966969969669, 0x5AA55AA55AA55AA5, 0xAAAAAAAA55555555, 0x3333CCCCCCCC3333, 0x0000FFFFFFFF0000, 0x00FFFF00FF0000FF, 0x9669966996699669 }, { 0x3C3CC3C3C3C33C3C, 0x55555555AAAAAAAA, 0x0FF00FF0F00FF00F, 0x5AA55AA5A55AA55A, 0x55AAAA55AA5555AA, 0xF00F0FF0F00F0FF0, 0x6996966969969669, 0x5AA55AA55AA55AA5, 0x55555555AAAAAAAA, 0x3333CCCCCCCC3333, 0xFFFF00000000FFFF, 0xFF0000FF00FFFF00, 0x9669966996699669 }, { 0xC3C33C3C3C3CC3C3, 0x55555555AAAAAAAA, 0xF00FF00F0FF00FF0, 0x5AA55AA5A55AA55A, 0x55AAAA55AA5555AA, 0xF00F0FF0F00F0FF0, 0x6996966969969669, 0xA55AA55AA55AA55A, 0x55555555AAAAAAAA, 0xCCCC33333333CCCC, 0xFFFF00000000FFFF, 0x00FFFF00FF0000FF, 0x6996699669966996 }, { 0x3C3CC3C3C3C33C3C, 0xAAAAAAAA55555555, 0x0FF00FF0F00FF00F, 0x5AA55AA5A55AA55A, 0xAA5555AA55AAAA55, 0xF00F0FF0F00F0FF0, 0x9669699696696996, 0xA55AA55AA55AA55A, 0x55555555AAAAAAAA, 0xCCCC33333333CCCC, 0x0000FFFFFFFF0000, 0xFF0000FF00FFFF00, 0x6996699669966996 }, { 0xC3C33C3C3C3CC3C3, 0xAAAAAAAA55555555, 0xF00FF00F0FF00FF0, 0x5AA55AA5A55AA55A, 0xAA5555AA55AAAA55, 0xF00F0FF0F00F0FF0, 0x9669699696696996, 0x5AA55AA55AA55AA5, 0x55555555AAAAAAAA, 0x3333CCCCCCCC3333, 0x0000FFFFFFFF0000, 0x00FFFF00FF0000FF, 0x9669966996699669 }, { 0x3C3CC3C3C3C33C3C, 0xAAAAAAAA55555555, 0x0FF00FF0F00FF00F, 0xA55AA55A5AA55AA5, 0x55AAAA55AA5555AA, 0x0FF0F00F0FF0F00F, 0x9669699696696996, 0x5AA55AA55AA55AA5, 0xAAAAAAAA55555555, 0x3333CCCCCCCC3333, 0xFFFF00000000FFFF, 0xFF0000FF00FFFF00, 0x9669966996699669 }, { 0xC3C33C3C3C3CC3C3, 0xAAAAAAAA55555555, 0xF00FF00F0FF00FF0, 0xA55AA55A5AA55AA5, 0x55AAAA55AA5555AA, 0x0FF0F00F0FF0F00F, 0x9669699696696996, 0xA55AA55AA55AA55A, 0xAAAAAAAA55555555, 0xCCCC33333333CCCC, 0xFFFF00000000FFFF, 0x00FFFF00FF0000FF, 0x6996699669966996 }, { 0x3C3CC3C3C3C33C3C, 0xAAAAAAAA55555555, 0xF00FF00F0FF00FF0, 0xA55AA55A5AA55AA5, 0x55AAAA55AA5555AA, 0x0FF0F00F0FF0F00F, 0x6996966969969669, 0xA55AA55AA55AA55A, 0xAAAAAAAA55555555, 0xCCCC33333333CCCC, 0x0000FFFFFFFF0000, 0xFF0000FF00FFFF00, 0x6996699669966996 }, { 0xC3C33C3C3C3CC3C3, 0xAAAAAAAA55555555, 0x0FF00FF0F00FF00F, 0xA55AA55A5AA55AA5, 0x55AAAA55AA5555AA, 0x0FF0F00F0FF0F00F, 0x6996966969969669, 0x5AA55AA55AA55AA5, 0xAAAAAAAA55555555, 0x3333CCCCCCCC3333, 0x0000FFFFFFFF0000, 0x00FFFF00FF0000FF, 0x9669966996699669 }, { 0x3C3CC3C3C3C33C3C, 0xAAAAAAAA55555555, 0xF00FF00F0FF00FF0, 0x5AA55AA5A55AA55A, 0xAA5555AA55AAAA55, 0xF00F0FF0F00F0FF0, 0x6996966969969669, 0x5AA55AA55AA55AA5, 0x55555555AAAAAAAA, 0x3333CCCCCCCC3333, 0xFFFF00000000FFFF, 0xFF0000FF00FFFF00, 0x9669966996699669 }, { 0xC3C33C3C3C3CC3C3, 0xAAAAAAAA55555555, 0x0FF00FF0F00FF00F, 0x5AA55AA5A55AA55A, 0xAA5555AA55AAAA55, 0xF00F0FF0F00F0FF0, 0x6996966969969669, 0xA55AA55AA55AA55A, 0x55555555AAAAAAAA, 0xCCCC33333333CCCC, 0xFFFF00000000FFFF, 0x00FFFF00FF0000FF, 0x6996699669966996 }, { 0x3CC3C33C3CC3C33C, 0xAAAAAAAAAAAAAAAA, 0xFFFF0000FFFF0000, 0x3CC3C33C3CC3C33C, 0x55AA55AA55AA55AA, 0xFFFF0000FFFF0000, 0x0F0F0F0FF0F0F0F0, 0xFF0000FF00FFFF00, 0x33CCCC33CC3333CC, 0xFF0000FF00FFFF00, 0x6996966996696996, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0xAAAAAAAAAAAAAAAA, 0xFFFF0000FFFF0000, 0x3CC3C33C3CC3C33C, 0x55AA55AA55AA55AA, 0x0000FFFF0000FFFF, 0xF0F0F0F00F0F0F0F, 0x00FFFF00FF0000FF, 0xCC3333CC33CCCC33, 0x00FFFF00FF0000FF, 0x9669699669969669, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0xAAAAAAAAAAAAAAAA, 0xFFFF0000FFFF0000, 0x3CC3C33C3CC3C33C, 0xAA55AA55AA55AA55, 0x0000FFFF0000FFFF, 0xF0F0F0F00F0F0F0F, 0x00FFFF00FF0000FF, 0xCC3333CC33CCCC33, 0xFF0000FF00FFFF00, 0x6996966996696996, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0xAAAAAAAAAAAAAAAA, 0xFFFF0000FFFF0000, 0x3CC3C33C3CC3C33C, 0xAA55AA55AA55AA55, 0xFFFF0000FFFF0000, 0x0F0F0F0FF0F0F0F0, 0xFF0000FF00FFFF00, 0x33CCCC33CC3333CC, 0x00FFFF00FF0000FF, 0x9669699669969669, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0xAAAAAAAAAAAAAAAA, 0xFFFF0000FFFF0000, 0xC33C3CC3C33C3CC3, 0xAA55AA55AA55AA55, 0x0000FFFF0000FFFF, 0xF0F0F0F00F0F0F0F, 0xFF0000FF00FFFF00, 0x33CCCC33CC3333CC, 0xFF0000FF00FFFF00, 0x6996966996696996, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0xAAAAAAAAAAAAAAAA, 0xFFFF0000FFFF0000, 0xC33C3CC3C33C3CC3, 0xAA55AA55AA55AA55, 0xFFFF0000FFFF0000, 0x0F0F0F0FF0F0F0F0, 0x00FFFF00FF0000FF, 0xCC3333CC33CCCC33, 0x00FFFF00FF0000FF, 0x9669699669969669, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0xAAAAAAAAAAAAAAAA, 0xFFFF0000FFFF0000, 0xC33C3CC3C33C3CC3, 0x55AA55AA55AA55AA, 0xFFFF0000FFFF0000, 0x0F0F0F0FF0F0F0F0, 0x00FFFF00FF0000FF, 0xCC3333CC33CCCC33, 0xFF0000FF00FFFF00, 0x6996966996696996, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0xAAAAAAAAAAAAAAAA, 0xFFFF0000FFFF0000, 0xC33C3CC3C33C3CC3, 0x55AA55AA55AA55AA, 0x0000FFFF0000FFFF, 0xF0F0F0F00F0F0F0F, 0xFF0000FF00FFFF00, 0x33CCCC33CC3333CC, 0x00FFFF00FF0000FF, 0x9669699669969669, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0xAAAAAAAAAAAAAAAA, 0x0000FFFF0000FFFF, 0xC33C3CC3C33C3CC3, 0xAA55AA55AA55AA55, 0xFFFF0000FFFF0000, 0x0F0F0F0FF0F0F0F0, 0xFF0000FF00FFFF00, 0x33CCCC33CC3333CC, 0xFF0000FF00FFFF00, 0x6996966996696996, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0xAAAAAAAAAAAAAAAA, 0x0000FFFF0000FFFF, 0xC33C3CC3C33C3CC3, 0xAA55AA55AA55AA55, 0x0000FFFF0000FFFF, 0xF0F0F0F00F0F0F0F, 0x00FFFF00FF0000FF, 0xCC3333CC33CCCC33, 0x00FFFF00FF0000FF, 0x9669699669969669, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0xAAAAAAAAAAAAAAAA, 0x0000FFFF0000FFFF, 0xC33C3CC3C33C3CC3, 0x55AA55AA55AA55AA, 0x0000FFFF0000FFFF, 0xF0F0F0F00F0F0F0F, 0x00FFFF00FF0000FF, 0xCC3333CC33CCCC33, 0xFF0000FF00FFFF00, 0x6996966996696996, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0xAAAAAAAAAAAAAAAA, 0x0000FFFF0000FFFF, 0xC33C3CC3C33C3CC3, 0x55AA55AA55AA55AA, 0xFFFF0000FFFF0000, 0x0F0F0F0FF0F0F0F0, 0xFF0000FF00FFFF00, 0x33CCCC33CC3333CC, 0x00FFFF00FF0000FF, 0x9669699669969669, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0xAAAAAAAAAAAAAAAA, 0x0000FFFF0000FFFF, 0x3CC3C33C3CC3C33C, 0x55AA55AA55AA55AA, 0x0000FFFF0000FFFF, 0xF0F0F0F00F0F0F0F, 0xFF0000FF00FFFF00, 0x33CCCC33CC3333CC, 0xFF0000FF00FFFF00, 0x6996966996696996, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0xAAAAAAAAAAAAAAAA, 0x0000FFFF0000FFFF, 0x3CC3C33C3CC3C33C, 0x55AA55AA55AA55AA, 0xFFFF0000FFFF0000, 0x0F0F0F0FF0F0F0F0, 0x00FFFF00FF0000FF, 0xCC3333CC33CCCC33, 0x00FFFF00FF0000FF, 0x9669699669969669, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0xAAAAAAAAAAAAAAAA, 0x0000FFFF0000FFFF, 0x3CC3C33C3CC3C33C, 0xAA55AA55AA55AA55, 0xFFFF0000FFFF0000, 0x0F0F0F0FF0F0F0F0, 0x00FFFF00FF0000FF, 0xCC3333CC33CCCC33, 0xFF0000FF00FFFF00, 0x6996966996696996, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0xAAAAAAAAAAAAAAAA, 0x0000FFFF0000FFFF, 0x3CC3C33C3CC3C33C, 0xAA55AA55AA55AA55, 0x0000FFFF0000FFFF, 0xF0F0F0F00F0F0F0F, 0xFF0000FF00FFFF00, 0x33CCCC33CC3333CC, 0x00FFFF00FF0000FF, 0x9669699669969669, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0x5555555555555555, 0x0000FFFF0000FFFF, 0x3CC3C33C3CC3C33C, 0x55AA55AA55AA55AA, 0xFFFF0000FFFF0000, 0x0F0F0F0FF0F0F0F0, 0xFF0000FF00FFFF00, 0x33CCCC33CC3333CC, 0xFF0000FF00FFFF00, 0x6996966996696996, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0x5555555555555555, 0x0000FFFF0000FFFF, 0x3CC3C33C3CC3C33C, 0x55AA55AA55AA55AA, 0x0000FFFF0000FFFF, 0xF0F0F0F00F0F0F0F, 0x00FFFF00FF0000FF, 0xCC3333CC33CCCC33, 0x00FFFF00FF0000FF, 0x9669699669969669, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0x5555555555555555, 0x0000FFFF0000FFFF, 0x3CC3C33C3CC3C33C, 0xAA55AA55AA55AA55, 0x0000FFFF0000FFFF, 0xF0F0F0F00F0F0F0F, 0x00FFFF00FF0000FF, 0xCC3333CC33CCCC33, 0xFF0000FF00FFFF00, 0x6996966996696996, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0x5555555555555555, 0x0000FFFF0000FFFF, 0x3CC3C33C3CC3C33C, 0xAA55AA55AA55AA55, 0xFFFF0000FFFF0000, 0x0F0F0F0FF0F0F0F0, 0xFF0000FF00FFFF00, 0x33CCCC33CC3333CC, 0x00FFFF00FF0000FF, 0x9669699669969669, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0x5555555555555555, 0x0000FFFF0000FFFF, 0xC33C3CC3C33C3CC3, 0xAA55AA55AA55AA55, 0x0000FFFF0000FFFF, 0xF0F0F0F00F0F0F0F, 0xFF0000FF00FFFF00, 0x33CCCC33CC3333CC, 0xFF0000FF00FFFF00, 0x6996966996696996, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0x5555555555555555, 0x0000FFFF0000FFFF, 0xC33C3CC3C33C3CC3, 0xAA55AA55AA55AA55, 0xFFFF0000FFFF0000, 0x0F0F0F0FF0F0F0F0, 0x00FFFF00FF0000FF, 0xCC3333CC33CCCC33, 0x00FFFF00FF0000FF, 0x9669699669969669, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0x5555555555555555, 0x0000FFFF0000FFFF, 0xC33C3CC3C33C3CC3, 0x55AA55AA55AA55AA, 0xFFFF0000FFFF0000, 0x0F0F0F0FF0F0F0F0, 0x00FFFF00FF0000FF, 0xCC3333CC33CCCC33, 0xFF0000FF00FFFF00, 0x6996966996696996, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0x5555555555555555, 0x0000FFFF0000FFFF, 0xC33C3CC3C33C3CC3, 0x55AA55AA55AA55AA, 0x0000FFFF0000FFFF, 0xF0F0F0F00F0F0F0F, 0xFF0000FF00FFFF00, 0x33CCCC33CC3333CC, 0x00FFFF00FF0000FF, 0x9669699669969669, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0x5555555555555555, 0xFFFF0000FFFF0000, 0xC33C3CC3C33C3CC3, 0xAA55AA55AA55AA55, 0xFFFF0000FFFF0000, 0x0F0F0F0FF0F0F0F0, 0xFF0000FF00FFFF00, 0x33CCCC33CC3333CC, 0xFF0000FF00FFFF00, 0x6996966996696996, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0x5555555555555555, 0xFFFF0000FFFF0000, 0xC33C3CC3C33C3CC3, 0xAA55AA55AA55AA55, 0x0000FFFF0000FFFF, 0xF0F0F0F00F0F0F0F, 0x00FFFF00FF0000FF, 0xCC3333CC33CCCC33, 0x00FFFF00FF0000FF, 0x9669699669969669, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0x5555555555555555, 0xFFFF0000FFFF0000, 0xC33C3CC3C33C3CC3, 0x55AA55AA55AA55AA, 0x0000FFFF0000FFFF, 0xF0F0F0F00F0F0F0F, 0x00FFFF00FF0000FF, 0xCC3333CC33CCCC33, 0xFF0000FF00FFFF00, 0x6996966996696996, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0x5555555555555555, 0xFFFF0000FFFF0000, 0xC33C3CC3C33C3CC3, 0x55AA55AA55AA55AA, 0xFFFF0000FFFF0000, 0x0F0F0F0FF0F0F0F0, 0xFF0000FF00FFFF00, 0x33CCCC33CC3333CC, 0x00FFFF00FF0000FF, 0x9669699669969669, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0x5555555555555555, 0xFFFF0000FFFF0000, 0x3CC3C33C3CC3C33C, 0x55AA55AA55AA55AA, 0x0000FFFF0000FFFF, 0xF0F0F0F00F0F0F0F, 0xFF0000FF00FFFF00, 0x33CCCC33CC3333CC, 0xFF0000FF00FFFF00, 0x6996966996696996, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0x5555555555555555, 0xFFFF0000FFFF0000, 0x3CC3C33C3CC3C33C, 0x55AA55AA55AA55AA, 0xFFFF0000FFFF0000, 0x0F0F0F0FF0F0F0F0, 0x00FFFF00FF0000FF, 0xCC3333CC33CCCC33, 0x00FFFF00FF0000FF, 0x9669699669969669, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0x5555555555555555, 0xFFFF0000FFFF0000, 0x3CC3C33C3CC3C33C, 0xAA55AA55AA55AA55, 0xFFFF0000FFFF0000, 0x0F0F0F0FF0F0F0F0, 0x00FFFF00FF0000FF, 0xCC3333CC33CCCC33, 0xFF0000FF00FFFF00, 0x6996966996696996, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0x5555555555555555, 0xFFFF0000FFFF0000, 0x3CC3C33C3CC3C33C, 0xAA55AA55AA55AA55, 0x0000FFFF0000FFFF, 0xF0F0F0F00F0F0F0F, 0xFF0000FF00FFFF00, 0x33CCCC33CC3333CC, 0x00FFFF00FF0000FF, 0x9669699669969669, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA },
- };
- /* from libmceliece-20230612/crypto_kem/6688128f/vec/shared-fft_powers.c */
- /* linker define fft_powers */
- const vec fft_powers[128][GFBITS] = {
- { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }
- };
- /* from libmceliece-20230612/crypto_kem/6688128f/vec/shared-fft_scalars_2x.c */
- /* linker define fft_scalars_2x */
- const vec fft_scalars_2x[5][2][GFBITS] = {
- {{ 0X3C3CF30C0000C003, 0X0CCCC3F333C0000C, 0X03C33F33FCC0C03C, 0X0003000F3C03C0C0, 0XF33FF33030CF03F0, 0X0CF0303300F0CCC0, 0XFF3F0C0CC0FF3CC0, 0XCF3CF0FF003FC000, 0XC00FF3CF0303F300, 0X3CCC0CC00CF0CC00, 0XF30FFC3C3FCCFC00, 0X3F0FC3F0CCF0C000, 0X3000FF33CCF0F000 }, { 0X0C0F0FCF0F0CF330, 0XF0000FC33C3CCF3C, 0X3C0F3F00C3C300FC, 0X3C33CCC0F0F3CC30, 0XC0CFFFFFCCCC30CC, 0X3FC3F3CCFFFC033F, 0XFC3030CCCCC0CFCF, 0X0FCF0C00CCF333C3, 0XCFFCF33000CFF030, 0X00CFFCC330F30FCC, 0X3CCC3FCCC0F3FFF3, 0XF00F0C3FC003C0FF, 0X330CCFCC03C0FC33 }}, {{ 0X0F0F0FF0F000000F, 0X00FFFFFFFF0000F0, 0XFFFF00FF00000F00, 0XFFF000F00F0FF000, 0XFFF0000F0FF000F0, 0X00FF000FFF000000, 0XFF0F0FFF0F0FF000, 0X0FFF0000000F0000, 0X00F000F0FFF00F00, 0X00F00FF00F00F000, 0XFFF000F000F00000, 0X00F00F000FF00000, 0X0000FF0F0000F000 }, { 0XF0FFFFFFF0F00F00, 0X00FFF0FFFF0000FF, 0X00FF00000F0F0FFF, 0XF000F0000F00FF0F, 0XFF000000FFF00000, 0XF0FF000FF00F0FF0, 0X0F0F0F00FF000F0F, 0X0F0F00F0F0F0F000, 0X00F00F00F00F000F, 0X00F0F0F00000FFF0, 0XFFFFFF0FF00F0FFF, 0X0F0FFFF00FFFFFFF, 0XFFFF0F0FFF0FFF00 }}, {{ 0X00FF0000000000FF, 0XFFFFFFFFFF00FF00, 0XFF0000FF00FF0000, 0XFFFF000000FF0000, 0XFF00000000FF0000, 0X00FFFFFFFF000000, 0XFF0000FFFFFF0000, 0XFF00FF00FFFF0000, 0X00FFFFFFFF00FF00, 0XFFFF000000000000, 0X00FF0000FF000000, 0XFF00FF00FF000000, 0X00FF00FFFF000000 }, { 0X00FF00FF00FF0000, 0XFF00FFFF000000FF, 0X0000FFFF000000FF, 0X00FFFF00FF000000, 0XFFFFFF0000FF00FF, 0X0000FFFF00FFFF00, 0XFF00FF0000FFFF00, 0X00000000FFFFFFFF, 0X0000FF0000000000, 0XFF00FFFF00FFFF00, 0X00FFFF00000000FF, 0X0000FF00FF00FFFF, 0XFF0000FFFFFF0000 }}, {{ 0X000000000000FFFF, 0XFFFFFFFFFFFF0000, 0X0000000000000000, 0XFFFF0000FFFF0000, 0XFFFFFFFFFFFF0000, 0X0000FFFF00000000, 0X0000FFFFFFFF0000, 0XFFFF0000FFFF0000, 0X0000FFFF00000000, 0XFFFF000000000000, 0XFFFF000000000000, 0XFFFF000000000000, 0XFFFFFFFF00000000 }, { 0X0000FFFF00000000, 0XFFFFFFFF0000FFFF, 0X00000000FFFFFFFF, 0X0000000000000000, 0X0000FFFF00000000, 0XFFFF0000FFFF0000, 0X0000FFFFFFFF0000, 0X0000FFFF0000FFFF, 0XFFFFFFFF0000FFFF, 0X00000000FFFF0000, 0XFFFF0000FFFFFFFF, 0XFFFF0000FFFFFFFF, 0X0000000000000000 }}, {{ 0X00000000FFFFFFFF, 0X0000000000000000, 0XFFFFFFFF00000000, 0X0000000000000000, 0XFFFFFFFF00000000, 0XFFFFFFFF00000000, 0XFFFFFFFF00000000, 0X0000000000000000, 0XFFFFFFFF00000000, 0X0000000000000000, 0X0000000000000000, 0X0000000000000000, 0XFFFFFFFF00000000 }, { 0X0000000000000000, 0XFFFFFFFFFFFFFFFF, 0X0000000000000000, 0X0000000000000000, 0X00000000FFFFFFFF, 0XFFFFFFFF00000000, 0X0000000000000000, 0XFFFFFFFFFFFFFFFF, 0X00000000FFFFFFFF, 0XFFFFFFFF00000000, 0XFFFFFFFFFFFFFFFF, 0XFFFFFFFFFFFFFFFF, 0XFFFFFFFF00000000 }}
- };
- /* from libmceliece-20230612/crypto_kem/6688128f/vec/shared-fft_scalars_4x.c */
- /* linker define fft_scalars_4x */
- const vec fft_scalars_4x[6][4][GFBITS] = {
- {{ 0x3C3CF30C0000C003, 0x0CCCC3F333C0000C, 0x03C33F33FCC0C03C, 0x0003000F3C03C0C0, 0xF33FF33030CF03F0, 0x0CF0303300F0CCC0, 0xFF3F0C0CC0FF3CC0, 0xCF3CF0FF003FC000, 0xC00FF3CF0303F300, 0x3CCC0CC00CF0CC00, 0xF30FFC3C3FCCFC00, 0x3F0FC3F0CCF0C000, 0x3000FF33CCF0F000 }, { 0x0C0F0FCF0F0CF330, 0xF0000FC33C3CCF3C, 0x3C0F3F00C3C300FC, 0x3C33CCC0F0F3CC30, 0xC0CFFFFFCCCC30CC, 0x3FC3F3CCFFFC033F, 0xFC3030CCCCC0CFCF, 0x0FCF0C00CCF333C3, 0xCFFCF33000CFF030, 0x00CFFCC330F30FCC, 0x3CCC3FCCC0F3FFF3, 0xF00F0C3FC003C0FF, 0x330CCFCC03C0FC33 }, { 0xF0F30C33CF03F03F, 0x00F30FC00C3300FF, 0xF3CC3CF3F3FCF33F, 0x3C0FC0FC303C3F3C, 0xFC30CF303F3FF00F, 0x33300C0CC3300CF3, 0x3C030CF3F03FF3F3, 0x3CCC03FCCC3FFC03, 0x033C3C3CF0003FC3, 0xFFC0FF00F0FF0F03, 0xF3F30CF003FCC303, 0x30CFCFC3CC0F3000, 0x0CF30CCF3FCFCC0F }, { 0x3F30CC0C000F3FCC, 0xFC3CF030FC3FFF03, 0x33FFFCFF0CCF3CC3, 0x003CFF33C3CC30CF, 0xCFF3CF33C00F3003, 0x00F3CC0CF3003CCF, 0x3C000CFCCC3C3333, 0xF3CF03C0FCF03FF0, 0x3F3C3CF0C330330C, 0x33CCFCC0FF0033F0, 0x33C300C0F0C003F3, 0x003FF0003F00C00C, 0xCFF3C3033F030FFF }}, {{ 0x0F0F0FF0F000000F, 0x00FFFFFFFF0000F0, 0xFFFF00FF00000F00, 0xFFF000F00F0FF000, 0xFFF0000F0FF000F0, 0x00FF000FFF000000, 0xFF0F0FFF0F0FF000, 0x0FFF0000000F0000, 0x00F000F0FFF00F00, 0x00F00FF00F00F000, 0xFFF000F000F00000, 0x00F00F000FF00000, 0x0000FF0F0000F000 }, { 0xF0FFFFFFF0F00F00, 0x00FFF0FFFF0000FF, 0x00FF00000F0F0FFF, 0xF000F0000F00FF0F, 0xFF000000FFF00000, 0xF0FF000FF00F0FF0, 0x0F0F0F00FF000F0F, 0x0F0F00F0F0F0F000, 0x00F00F00F00F000F, 0x00F0F0F00000FFF0, 0xFFFFFF0FF00F0FFF, 0x0F0FFFF00FFFFFFF, 0xFFFF0F0FFF0FFF00 }, { 0x0F0F00FF0FF0FFFF, 0xF000F0F00F00FF0F, 0x000FFFF0FFF0FF0F, 0x00F00FFF00000FF0, 0xFFFFF0000FFFF00F, 0xFFF0FFF0000FFFF0, 0xF0F0F0000F0F0F00, 0x00F000F0F00FFF00, 0xF0FF0F0FFF00F0FF, 0xF0FF0FFFF0F0F0FF, 0x00FFFFFFFFFFFFF0, 0x00FFF0F0FF000F0F, 0x000FFFF0000FFF00 }, { 0xFF0F0F00F000F0FF, 0x0FFFFFFFFF00000F, 0xF0FFFF000F00F0FF, 0x0F0000F00FFF0FFF, 0x0F0F0F00FF0F000F, 0x000F0F0FFFF0F000, 0xF0FFFF0F00F0FF0F, 0x0F0F000F0F00F0FF, 0x0000F0FF00FF0F0F, 0x00FFFF0FF0FFF0F0, 0x0000000F00F0FFF0, 0xF0F00000FF00F0F0, 0x0F0F0FFFFFFFFFFF }}, {{ 0x00FF0000000000FF, 0xFFFFFFFFFF00FF00, 0xFF0000FF00FF0000, 0xFFFF000000FF0000, 0xFF00000000FF0000, 0x00FFFFFFFF000000, 0xFF0000FFFFFF0000, 0xFF00FF00FFFF0000, 0x00FFFFFFFF00FF00, 0xFFFF000000000000, 0x00FF0000FF000000, 0xFF00FF00FF000000, 0x00FF00FFFF000000 }, { 0x00FF00FF00FF0000, 0xFF00FFFF000000FF, 0x0000FFFF000000FF, 0x00FFFF00FF000000, 0xFFFFFF0000FF00FF, 0x0000FFFF00FFFF00, 0xFF00FF0000FFFF00, 0x00000000FFFFFFFF, 0x0000FF0000000000, 0xFF00FFFF00FFFF00, 0x00FFFF00000000FF, 0x0000FF00FF00FFFF, 0xFF0000FFFFFF0000 }, { 0xFFFF00FF00FF00FF, 0x00FFFF000000FF00, 0xFFFF00FFFFFFFF00, 0x0000FFFF00FFFFFF, 0x00FF0000FF0000FF, 0xFFFF0000FF00FFFF, 0xFF000000FFFFFF00, 0x000000000000FFFF, 0xFF00FF00FFFF0000, 0xFFFF00FFFF00FFFF, 0xFFFFFFFFFF00FF00, 0xFFFF00FFFF0000FF, 0x0000FF00000000FF }, { 0xFF0000FFFFFF00FF, 0xFFFF0000FFFFFFFF, 0xFFFF000000FFFFFF, 0x00FFFF00FF0000FF, 0xFFFFFF00FFFFFF00, 0x00FFFF00FFFF00FF, 0x0000FFFF00FF0000, 0x000000FFFF000000, 0xFF00FF0000FF00FF, 0x00FF0000000000FF, 0xFF00FFFF00FF00FF, 0xFFFFFFFFFFFFFFFF, 0x0000FF000000FFFF }}, {{ 0x000000000000FFFF, 0xFFFFFFFFFFFF0000, 0x0000000000000000, 0xFFFF0000FFFF0000, 0xFFFFFFFFFFFF0000, 0x0000FFFF00000000, 0x0000FFFFFFFF0000, 0xFFFF0000FFFF0000, 0x0000FFFF00000000, 0xFFFF000000000000, 0xFFFF000000000000, 0xFFFF000000000000, 0xFFFFFFFF00000000 }, { 0x0000FFFF00000000, 0xFFFFFFFF0000FFFF, 0x00000000FFFFFFFF, 0x0000000000000000, 0x0000FFFF00000000, 0xFFFF0000FFFF0000, 0x0000FFFFFFFF0000, 0x0000FFFF0000FFFF, 0xFFFFFFFF0000FFFF, 0x00000000FFFF0000, 0xFFFF0000FFFFFFFF, 0xFFFF0000FFFFFFFF, 0x0000000000000000 }, { 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF000000000000, 0x0000FFFF00000000, 0x00000000FFFF0000, 0x0000FFFFFFFFFFFF, 0x0000FFFFFFFFFFFF, 0xFFFFFFFF00000000, 0x000000000000FFFF, 0x000000000000FFFF, 0xFFFFFFFFFFFF0000, 0xFFFFFFFF0000FFFF, 0xFFFF0000FFFFFFFF }, { 0x0000FFFFFFFFFFFF, 0x0000FFFF0000FFFF, 0x0000FFFFFFFF0000, 0xFFFF0000FFFFFFFF, 0x00000000FFFF0000, 0xFFFF00000000FFFF, 0x0000FFFF0000FFFF, 0xFFFF00000000FFFF, 0x0000FFFF0000FFFF, 0x0000FFFF00000000, 0xFFFFFFFF00000000, 0x0000FFFFFFFF0000, 0x0000FFFFFFFFFFFF }}, {{ 0x00000000FFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFFFFFF00000000, 0xFFFFFFFF00000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000 }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0x00000000FFFFFFFF, 0xFFFFFFFF00000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x00000000FFFFFFFF, 0xFFFFFFFF00000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000 }, { 0x00000000FFFFFFFF, 0xFFFFFFFF00000000, 0xFFFFFFFF00000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0x00000000FFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF }, { 0xFFFFFFFFFFFFFFFF, 0x00000000FFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0x00000000FFFFFFFF, 0xFFFFFFFF00000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFFFFFF00000000 }}, {{ 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 }, { 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000 }, { 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF }},
- };
- /* from libmceliece-20230612/crypto_kem/6688128f/vec/fft.c */
- /*
- This file is for implementing the Gao-Mateer FFT, see
- http://www.math.clemson.edu/~sgao/papers/GM10.pdf
- For the implementation strategy, see
- https://eprint.iacr.org/2017/793.pdf
- */
- /* 20221230 djb: split these arrays into separate .c files */
- /* 20221230 djb: rename powers array as fft_powers */
- /* 20221230 djb: rename consts array as fft_consts */
- /* 20221230 djb: rename s array as fft_scalars_2x */
- /* 20221230 djb: add linker lines */
- /* linker define fft */
- /* linker use vec_mul */
- /* linker use fft_scalars_2x fft_consts fft_powers */
- /* input: in, polynomial in bitsliced form */
- /* output: in, result of applying the radix conversions on in */
- static void radix_conversions(vec in[][GFBITS])
- {
- int i, j, k;
- const vec mask[5][2] =
- {
- {0x8888888888888888, 0x4444444444444444},
- {0xC0C0C0C0C0C0C0C0, 0x3030303030303030},
- {0xF000F000F000F000, 0x0F000F000F000F00},
- {0xFF000000FF000000, 0x00FF000000FF0000},
- {0xFFFF000000000000, 0x0000FFFF00000000}
- };
- for (j = 0; j <= 5; j++)
- {
- for (i = 0; i < GFBITS; i++)
- {
- in[1][i] ^= in[1][i] >> 32;
- in[0][i] ^= in[1][i] << 32;
- }
- for (i = 0; i < GFBITS; i++)
- for (k = 4; k >= j; k--)
- {
- in[0][i] ^= (in[0][i] & mask[k][0]) >> (1 << k);
- in[0][i] ^= (in[0][i] & mask[k][1]) >> (1 << k);
- in[1][i] ^= (in[1][i] & mask[k][0]) >> (1 << k);
- in[1][i] ^= (in[1][i] & mask[k][1]) >> (1 << k);
- }
- if (j < 5)
- {
- vec_mul(in[0], in[0], fft_scalars_2x[j][0]);
- vec_mul(in[1], in[1], fft_scalars_2x[j][1]);
- }
- }
- }
- /* input: in, result of applying the radix conversions to the input polynomial */
- /* output: out, evaluation results (by applying the FFT butterflies) */
- static void butterflies(vec out[][ GFBITS ], vec in[][ GFBITS ])
- {
- int i, j, k, s, b;
- vec tmp[ GFBITS ];
- vec pre[8][ GFBITS ];
- vec buf[128];
- uint64_t consts_ptr = 2;
- const unsigned char reversal[128] =
- {
- 0, 64, 32, 96, 16, 80, 48, 112,
- 8, 72, 40, 104, 24, 88, 56, 120,
- 4, 68, 36, 100, 20, 84, 52, 116,
- 12, 76, 44, 108, 28, 92, 60, 124,
- 2, 66, 34, 98, 18, 82, 50, 114,
- 10, 74, 42, 106, 26, 90, 58, 122,
- 6, 70, 38, 102, 22, 86, 54, 118,
- 14, 78, 46, 110, 30, 94, 62, 126,
- 1, 65, 33, 97, 17, 81, 49, 113,
- 9, 73, 41, 105, 25, 89, 57, 121,
- 5, 69, 37, 101, 21, 85, 53, 117,
- 13, 77, 45, 109, 29, 93, 61, 125,
- 3, 67, 35, 99, 19, 83, 51, 115,
- 11, 75, 43, 107, 27, 91, 59, 123,
- 7, 71, 39, 103, 23, 87, 55, 119,
- 15, 79, 47, 111, 31, 95, 63, 127
- };
- const uint16_t beta[7] = {2522, 7827, 7801, 8035, 6897, 8167, 3476};
- /**/
- for (i = 0; i < 7; i++)
- {
- for (j = 0; j < GFBITS; j++)
- {
- pre[i][j] = (beta[i] >> j) & 1;
- pre[i][j] = -pre[i][j];
- }
- vec_mul(pre[i], in[1], pre[i]);
- }
- for (i = 0; i < GFBITS; i++)
- {
- buf[0] = in[0][i];
- buf[1] = buf[0] ^ pre[0][i]; buf[32] = in[0][i] ^ pre[5][i];
- buf[3] = buf[1] ^ pre[1][i]; buf[96] = buf[32] ^ pre[6][i];
- buf[97] = buf[96] ^ pre[0][i];
- buf[2] = in[0][i] ^ pre[1][i]; buf[99] = buf[97] ^ pre[1][i];
- buf[6] = buf[2] ^ pre[2][i]; buf[98] = buf[99] ^ pre[0][i];
- buf[7] = buf[6] ^ pre[0][i]; buf[102] = buf[98] ^ pre[2][i];
- buf[5] = buf[7] ^ pre[1][i]; buf[103] = buf[102] ^ pre[0][i];
- buf[101] = buf[103] ^ pre[1][i];
- buf[4] = in[0][i] ^ pre[2][i]; buf[100] = buf[101] ^ pre[0][i];
- buf[12] = buf[4] ^ pre[3][i]; buf[108] = buf[100] ^ pre[3][i];
- buf[13] = buf[12] ^ pre[0][i]; buf[109] = buf[108] ^ pre[0][i];
- buf[15] = buf[13] ^ pre[1][i]; buf[111] = buf[109] ^ pre[1][i];
- buf[14] = buf[15] ^ pre[0][i]; buf[110] = buf[111] ^ pre[0][i];
- buf[10] = buf[14] ^ pre[2][i]; buf[106] = buf[110] ^ pre[2][i];
- buf[11] = buf[10] ^ pre[0][i]; buf[107] = buf[106] ^ pre[0][i];
- buf[9] = buf[11] ^ pre[1][i]; buf[105] = buf[107] ^ pre[1][i];
- buf[104] = buf[105] ^ pre[0][i];
- buf[8] = in[0][i] ^ pre[3][i]; buf[120] = buf[104] ^ pre[4][i];
- buf[24] = buf[8] ^ pre[4][i]; buf[121] = buf[120] ^ pre[0][i];
- buf[25] = buf[24] ^ pre[0][i]; buf[123] = buf[121] ^ pre[1][i];
- buf[27] = buf[25] ^ pre[1][i]; buf[122] = buf[123] ^ pre[0][i];
- buf[26] = buf[27] ^ pre[0][i]; buf[126] = buf[122] ^ pre[2][i];
- buf[30] = buf[26] ^ pre[2][i]; buf[127] = buf[126] ^ pre[0][i];
- buf[31] = buf[30] ^ pre[0][i]; buf[125] = buf[127] ^ pre[1][i];
- buf[29] = buf[31] ^ pre[1][i]; buf[124] = buf[125] ^ pre[0][i];
- buf[28] = buf[29] ^ pre[0][i]; buf[116] = buf[124] ^ pre[3][i];
- buf[20] = buf[28] ^ pre[3][i]; buf[117] = buf[116] ^ pre[0][i];
- buf[21] = buf[20] ^ pre[0][i]; buf[119] = buf[117] ^ pre[1][i];
- buf[23] = buf[21] ^ pre[1][i]; buf[118] = buf[119] ^ pre[0][i];
- buf[22] = buf[23] ^ pre[0][i]; buf[114] = buf[118] ^ pre[2][i];
- buf[18] = buf[22] ^ pre[2][i]; buf[115] = buf[114] ^ pre[0][i];
- buf[19] = buf[18] ^ pre[0][i]; buf[113] = buf[115] ^ pre[1][i];
- buf[17] = buf[19] ^ pre[1][i]; buf[112] = buf[113] ^ pre[0][i];
- buf[80] = buf[112] ^ pre[5][i];
- buf[16] = in[0][i] ^ pre[4][i]; buf[81] = buf[80] ^ pre[0][i];
- buf[48] = buf[16] ^ pre[5][i]; buf[83] = buf[81] ^ pre[1][i];
- buf[49] = buf[48] ^ pre[0][i]; buf[82] = buf[83] ^ pre[0][i];
- buf[51] = buf[49] ^ pre[1][i]; buf[86] = buf[82] ^ pre[2][i];
- buf[50] = buf[51] ^ pre[0][i]; buf[87] = buf[86] ^ pre[0][i];
- buf[54] = buf[50] ^ pre[2][i]; buf[85] = buf[87] ^ pre[1][i];
- buf[55] = buf[54] ^ pre[0][i]; buf[84] = buf[85] ^ pre[0][i];
- buf[53] = buf[55] ^ pre[1][i]; buf[92] = buf[84] ^ pre[3][i];
- buf[52] = buf[53] ^ pre[0][i]; buf[93] = buf[92] ^ pre[0][i];
- buf[60] = buf[52] ^ pre[3][i]; buf[95] = buf[93] ^ pre[1][i];
- buf[61] = buf[60] ^ pre[0][i]; buf[94] = buf[95] ^ pre[0][i];
- buf[63] = buf[61] ^ pre[1][i]; buf[90] = buf[94] ^ pre[2][i];
- buf[62] = buf[63] ^ pre[0][i]; buf[91] = buf[90] ^ pre[0][i];
- buf[58] = buf[62] ^ pre[2][i]; buf[89] = buf[91] ^ pre[1][i];
- buf[59] = buf[58] ^ pre[0][i]; buf[88] = buf[89] ^ pre[0][i];
- buf[57] = buf[59] ^ pre[1][i]; buf[72] = buf[88] ^ pre[4][i];
- buf[56] = buf[57] ^ pre[0][i]; buf[73] = buf[72] ^ pre[0][i];
- buf[40] = buf[56] ^ pre[4][i]; buf[75] = buf[73] ^ pre[1][i];
- buf[41] = buf[40] ^ pre[0][i]; buf[74] = buf[75] ^ pre[0][i];
- buf[43] = buf[41] ^ pre[1][i]; buf[78] = buf[74] ^ pre[2][i];
- buf[42] = buf[43] ^ pre[0][i]; buf[79] = buf[78] ^ pre[0][i];
- buf[46] = buf[42] ^ pre[2][i]; buf[77] = buf[79] ^ pre[1][i];
- buf[47] = buf[46] ^ pre[0][i]; buf[76] = buf[77] ^ pre[0][i];
- buf[45] = buf[47] ^ pre[1][i]; buf[68] = buf[76] ^ pre[3][i];
- buf[44] = buf[45] ^ pre[0][i]; buf[69] = buf[68] ^ pre[0][i];
- buf[36] = buf[44] ^ pre[3][i]; buf[71] = buf[69] ^ pre[1][i];
- buf[37] = buf[36] ^ pre[0][i]; buf[70] = buf[71] ^ pre[0][i];
- buf[39] = buf[37] ^ pre[1][i]; buf[66] = buf[70] ^ pre[2][i];
- buf[38] = buf[39] ^ pre[0][i]; buf[67] = buf[66] ^ pre[0][i];
- buf[34] = buf[38] ^ pre[2][i]; buf[65] = buf[67] ^ pre[1][i];
- buf[35] = buf[34] ^ pre[0][i];
- buf[33] = buf[35] ^ pre[1][i]; buf[64] = in[0][i] ^ pre[6][i];
- transpose_64x64(buf + 0, buf + 0);
- transpose_64x64(buf + 64, buf + 64);
- for (j = 0; j < 128; j++)
- out[ reversal[j] ][i] = buf[j];
- }
- for (i = 1; i <= 6; i++)
- {
- s = 1 << i;
- for (j = 0; j < 128; j += 2*s)
- for (k = j; k < j+s; k++)
- {
- vec_mul(tmp, out[k+s], fft_consts[ consts_ptr + (k-j) ]);
- for (b = 0; b < GFBITS; b++) out[k ][b] ^= tmp[b];
- for (b = 0; b < GFBITS; b++) out[k+s][b] ^= out[k][b];
- }
- consts_ptr += (1 << i);
- }
- /* adding the part contributed by x^128 */
- for (i = 0; i < 128; i++)
- for (b = 0; b < GFBITS; b++)
- out[i][b] ^= fft_powers[i][b];
- }
- /* input: in, polynomial in bitsliced form */
- /* output: out, bitsliced results of evaluating in all the field elements */
- static void fft(vec out[][GFBITS], vec in[][GFBITS])
- {
- radix_conversions(in);
- butterflies(out, in);
- }
- /* from libmceliece-20230612/crypto_kem/6688128f/vec/fft_tr.c */
- /*
- This file is for transpose of the Gao-Mateer FFT
- Functions with names ending with _tr are (roughly) the transpose of the corresponding functions in fft.c
- For the implementation strategy, see
- https://eprint.iacr.org/2017/793.pdf
- */
- /* 20221230 djb: split these arrays into separate .c files */
- /* 20221230 djb: rename consts array as fft_consts */
- /* 20221230 djb: rename s array as fft_scalars_4x */
- /* 20221230 djb: add linker lines */
- /* linker define fft_tr */
- /* linker use vec_mul */
- /* linker use fft_scalars_4x fft_consts */
- static void radix_conversions_tr(vec in[][ GFBITS ])
- {
- int i, j, k;
- const vec mask[6][2] =
- {
- {0x2222222222222222, 0x4444444444444444},
- {0x0C0C0C0C0C0C0C0C, 0x3030303030303030},
- {0x00F000F000F000F0, 0x0F000F000F000F00},
- {0x0000FF000000FF00, 0x00FF000000FF0000},
- {0x00000000FFFF0000, 0x0000FFFF00000000},
- {0xFFFFFFFF00000000, 0x00000000FFFFFFFF}
- };
- /**/
- for (j = 6; j >= 0; j--)
- {
- if (j < 6)
- {
- vec_mul(in[0], in[0], fft_scalars_4x[j][0]); /* scaling */
- vec_mul(in[1], in[1], fft_scalars_4x[j][1]); /* scaling */
- vec_mul(in[2], in[2], fft_scalars_4x[j][2]); /* scaling */
- vec_mul(in[3], in[3], fft_scalars_4x[j][3]); /* scaling */
- }
- for (k = j; k <= 4; k++)
- for (i = 0; i < GFBITS; i++)
- {
- in[0][i] ^= (in[0][i] & mask[k][0]) << (1 << k);
- in[0][i] ^= (in[0][i] & mask[k][1]) << (1 << k);
- in[1][i] ^= (in[1][i] & mask[k][0]) << (1 << k);
- in[1][i] ^= (in[1][i] & mask[k][1]) << (1 << k);
- in[2][i] ^= (in[2][i] & mask[k][0]) << (1 << k);
- in[2][i] ^= (in[2][i] & mask[k][1]) << (1 << k);
- in[3][i] ^= (in[3][i] & mask[k][0]) << (1 << k);
- in[3][i] ^= (in[3][i] & mask[k][1]) << (1 << k);
- }
- if (j <= 5)
- for (i = 0; i < GFBITS; i++)
- {
- in[1][i] ^= in[0][i] >> 32;
- in[1][i] ^= in[1][i] << 32;
- in[3][i] ^= in[2][i] >> 32;
- in[3][i] ^= in[3][i] << 32;
- }
- for (i = 0; i < GFBITS; i++)
- in[3][i] ^= in[2][i] ^= in[1][i];
- }
- }
- static void butterflies_tr(vec out[][ GFBITS ], vec in[][ GFBITS ])
- {
- int i, j, k, s, b;
- vec tmp[ GFBITS ];
- vec pre[6][2][ GFBITS ];
- vec buf[2][64];
- uint64_t consts_ptr = 128;
- const unsigned char reversal[128] =
- {
- 0, 64, 32, 96, 16, 80, 48, 112,
- 8, 72, 40, 104, 24, 88, 56, 120,
- 4, 68, 36, 100, 20, 84, 52, 116,
- 12, 76, 44, 108, 28, 92, 60, 124,
- 2, 66, 34, 98, 18, 82, 50, 114,
- 10, 74, 42, 106, 26, 90, 58, 122,
- 6, 70, 38, 102, 22, 86, 54, 118,
- 14, 78, 46, 110, 30, 94, 62, 126,
- 1, 65, 33, 97, 17, 81, 49, 113,
- 9, 73, 41, 105, 25, 89, 57, 121,
- 5, 69, 37, 101, 21, 85, 53, 117,
- 13, 77, 45, 109, 29, 93, 61, 125,
- 3, 67, 35, 99, 19, 83, 51, 115,
- 11, 75, 43, 107, 27, 91, 59, 123,
- 7, 71, 39, 103, 23, 87, 55, 119,
- 15, 79, 47, 111, 31, 95, 63, 127
- };
- const uint16_t beta[6] = {5246, 5306, 6039, 6685, 4905, 6755};
- /**/
- for (i = 6; i >= 0; i--)
- {
- s = 1 << i;
- consts_ptr -= s;
- for (j = 0; j < 128; j += 2*s)
- for (k = j; k < j+s; k++)
- {
- for (b = 0; b < GFBITS; b++) in[k][b] ^= in[k+s][b];
- vec_mul(tmp, in[k], fft_consts[ consts_ptr + (k-j) ]);
- for (b = 0; b < GFBITS; b++) in[k+s][b] ^= tmp[b];
- }
- }
- for (i = 0; i < GFBITS; i++)
- {
- for (k = 0; k < 128; k++)
- (&buf[0][0])[ k ] = in[ reversal[k] ][i];
- transpose_64x64(buf[0], buf[0]);
- transpose_64x64(buf[1], buf[1]);
- for (k = 0; k < 2; k++)
- {
- pre[0][k][i] = buf[k][32]; buf[k][33] ^= buf[k][32];
- pre[1][k][i] = buf[k][33]; buf[k][35] ^= buf[k][33];
- pre[0][k][i] ^= buf[k][35]; buf[k][34] ^= buf[k][35];
- pre[2][k][i] = buf[k][34]; buf[k][38] ^= buf[k][34];
- pre[0][k][i] ^= buf[k][38]; buf[k][39] ^= buf[k][38];
- pre[1][k][i] ^= buf[k][39]; buf[k][37] ^= buf[k][39];
- pre[0][k][i] ^= buf[k][37]; buf[k][36] ^= buf[k][37];
- pre[3][k][i] = buf[k][36]; buf[k][44] ^= buf[k][36];
- pre[0][k][i] ^= buf[k][44]; buf[k][45] ^= buf[k][44];
- pre[1][k][i] ^= buf[k][45]; buf[k][47] ^= buf[k][45];
- pre[0][k][i] ^= buf[k][47]; buf[k][46] ^= buf[k][47];
- pre[2][k][i] ^= buf[k][46]; buf[k][42] ^= buf[k][46];
- pre[0][k][i] ^= buf[k][42]; buf[k][43] ^= buf[k][42];
- pre[1][k][i] ^= buf[k][43]; buf[k][41] ^= buf[k][43];
- pre[0][k][i] ^= buf[k][41]; buf[k][40] ^= buf[k][41];
- pre[4][k][i] = buf[k][40]; buf[k][56] ^= buf[k][40];
- pre[0][k][i] ^= buf[k][56]; buf[k][57] ^= buf[k][56];
- pre[1][k][i] ^= buf[k][57]; buf[k][59] ^= buf[k][57];
- pre[0][k][i] ^= buf[k][59]; buf[k][58] ^= buf[k][59];
- pre[2][k][i] ^= buf[k][58]; buf[k][62] ^= buf[k][58];
- pre[0][k][i] ^= buf[k][62]; buf[k][63] ^= buf[k][62];
- pre[1][k][i] ^= buf[k][63]; buf[k][61] ^= buf[k][63];
- pre[0][k][i] ^= buf[k][61]; buf[k][60] ^= buf[k][61];
- pre[3][k][i] ^= buf[k][60]; buf[k][52] ^= buf[k][60];
- pre[0][k][i] ^= buf[k][52]; buf[k][53] ^= buf[k][52];
- pre[1][k][i] ^= buf[k][53]; buf[k][55] ^= buf[k][53];
- pre[0][k][i] ^= buf[k][55]; buf[k][54] ^= buf[k][55];
- pre[2][k][i] ^= buf[k][54]; buf[k][50] ^= buf[k][54];
- pre[0][k][i] ^= buf[k][50]; buf[k][51] ^= buf[k][50];
- pre[1][k][i] ^= buf[k][51]; buf[k][49] ^= buf[k][51];
- pre[0][k][i] ^= buf[k][49]; buf[k][48] ^= buf[k][49];
- pre[5][k][i] = buf[k][48]; buf[k][16] ^= buf[k][48];
- pre[0][k][i] ^= buf[k][16]; buf[k][17] ^= buf[k][16];
- pre[1][k][i] ^= buf[k][17]; buf[k][19] ^= buf[k][17];
- pre[0][k][i] ^= buf[k][19]; buf[k][18] ^= buf[k][19];
- pre[2][k][i] ^= buf[k][18]; buf[k][22] ^= buf[k][18];
- pre[0][k][i] ^= buf[k][22]; buf[k][23] ^= buf[k][22];
- pre[1][k][i] ^= buf[k][23]; buf[k][21] ^= buf[k][23];
- pre[0][k][i] ^= buf[k][21]; buf[k][20] ^= buf[k][21];
- pre[3][k][i] ^= buf[k][20]; buf[k][28] ^= buf[k][20];
- pre[0][k][i] ^= buf[k][28]; buf[k][29] ^= buf[k][28];
- pre[1][k][i] ^= buf[k][29]; buf[k][31] ^= buf[k][29];
- pre[0][k][i] ^= buf[k][31]; buf[k][30] ^= buf[k][31];
- pre[2][k][i] ^= buf[k][30]; buf[k][26] ^= buf[k][30];
- pre[0][k][i] ^= buf[k][26]; buf[k][27] ^= buf[k][26];
- pre[1][k][i] ^= buf[k][27]; buf[k][25] ^= buf[k][27];
- pre[0][k][i] ^= buf[k][25]; buf[k][24] ^= buf[k][25];
- pre[4][k][i] ^= buf[k][24]; buf[k][8] ^= buf[k][24];
- pre[0][k][i] ^= buf[k][8]; buf[k][9] ^= buf[k][8];
- pre[1][k][i] ^= buf[k][9]; buf[k][11] ^= buf[k][9];
- pre[0][k][i] ^= buf[k][11]; buf[k][10] ^= buf[k][11];
- pre[2][k][i] ^= buf[k][10]; buf[k][14] ^= buf[k][10];
- pre[0][k][i] ^= buf[k][14]; buf[k][15] ^= buf[k][14];
- pre[1][k][i] ^= buf[k][15]; buf[k][13] ^= buf[k][15];
- pre[0][k][i] ^= buf[k][13]; buf[k][12] ^= buf[k][13];
- pre[3][k][i] ^= buf[k][12]; buf[k][4] ^= buf[k][12];
- pre[0][k][i] ^= buf[k][4]; buf[k][5] ^= buf[k][4];
- pre[1][k][i] ^= buf[k][5]; buf[k][7] ^= buf[k][5];
- pre[0][k][i] ^= buf[k][7]; buf[k][6] ^= buf[k][7];
- pre[2][k][i] ^= buf[k][6]; buf[k][2] ^= buf[k][6];
- pre[0][k][i] ^= buf[k][2]; buf[k][3] ^= buf[k][2];
- pre[1][k][i] ^= buf[k][3]; buf[k][1] ^= buf[k][3];
- pre[0][k][i] ^= buf[k][1]; out[k][i] = buf[k][0] ^ buf[k][1];
- }
- }
- for (j = 0; j < GFBITS; j++) tmp[j] = vec_setbits((beta[0] >> j) & 1);
- vec_mul(out[2], pre[0][0], tmp);
- vec_mul(out[3], pre[0][1], tmp);
- for (i = 1; i < 6; i++)
- {
- for (j = 0; j < GFBITS; j++) tmp[j] = vec_setbits((beta[i] >> j) & 1);
- vec_mul(pre[i][0], pre[i][0], tmp);
- vec_mul(pre[i][1], pre[i][1], tmp);
- for (b = 0; b < GFBITS; b++)
- {
- out[2][b] ^= pre[i][0][b];
- out[3][b] ^= pre[i][1][b];
- }
- }
- }
- static void fft_tr(vec out[][GFBITS], vec in[][ GFBITS ])
- {
- butterflies_tr(out, in);
- radix_conversions_tr(out);
- }
- /* from libmceliece-20230612/crypto_kem/6688128f/vec/gf.c */
- /*
- this file is for functions for field arithmetic
- */
- /* 20221231 djb: const for GF_mul */
- /* 20221230 djb: add linker line */
- /* linker define gf_iszero gf_mul gf_inv gf_frac GF_mul */
- /* field multiplication */
- gf gf_mul(gf in0, gf in1)
- {
- int i;
- uint64_t tmp;
- uint64_t t0;
- uint64_t t1;
- uint64_t t;
- t0 = in0;
- t1 = in1;
- tmp = t0 * (t1 & 1);
- for (i = 1; i < GFBITS; i++)
- tmp ^= (t0 * (t1 & (1 << i)));
- /**/
- t = tmp & 0x1FF0000;
- tmp ^= (t >> 9) ^ (t >> 10) ^ (t >> 12) ^ (t >> 13);
- t = tmp & 0x000E000;
- tmp ^= (t >> 9) ^ (t >> 10) ^ (t >> 12) ^ (t >> 13);
- return tmp & GFMASK;
- }
- /* 2 field squarings */
- static inline gf gf_sq2(gf in)
- {
- int i;
- const uint64_t B[] = {0x1111111111111111,
- 0x0303030303030303,
- 0x000F000F000F000F,
- 0x000000FF000000FF};
- const uint64_t M[] = {0x0001FF0000000000,
- 0x000000FF80000000,
- 0x000000007FC00000,
- 0x00000000003FE000};
- uint64_t x = in;
- uint64_t t;
- x = (x | (x << 24)) & B[3];
- x = (x | (x << 12)) & B[2];
- x = (x | (x << 6)) & B[1];
- x = (x | (x << 3)) & B[0];
- for (i = 0; i < 4; i++)
- {
- t = x & M[i];
- x ^= (t >> 9) ^ (t >> 10) ^ (t >> 12) ^ (t >> 13);
- }
- return x & GFMASK;
- }
- /* square and multiply */
- static inline gf gf_sqmul(gf in, gf m)
- {
- int i;
- uint64_t x;
- uint64_t t0;
- uint64_t t1;
- uint64_t t;
- const uint64_t M[] = {0x0000001FF0000000,
- 0x000000000FF80000,
- 0x000000000007E000};
- t0 = in;
- t1 = m;
- x = (t1 << 6) * (t0 & (1 << 6));
- t0 ^= (t0 << 7);
- x ^= (t1 * (t0 & (0x04001)));
- x ^= (t1 * (t0 & (0x08002))) << 1;
- x ^= (t1 * (t0 & (0x10004))) << 2;
- x ^= (t1 * (t0 & (0x20008))) << 3;
- x ^= (t1 * (t0 & (0x40010))) << 4;
- x ^= (t1 * (t0 & (0x80020))) << 5;
- for (i = 0; i < 3; i++)
- {
- t = x & M[i];
- x ^= (t >> 9) ^ (t >> 10) ^ (t >> 12) ^ (t >> 13);
- }
- return x & GFMASK;
- }
- /* square twice and multiply */
- static inline gf gf_sq2mul(gf in, gf m)
- {
- int i;
- uint64_t x;
- uint64_t t0;
- uint64_t t1;
- uint64_t t;
- const uint64_t M[] = {0x1FF0000000000000,
- 0x000FF80000000000,
- 0x000007FC00000000,
- 0x00000003FE000000,
- 0x0000000001FE0000,
- 0x000000000001E000};
- t0 = in;
- t1 = m;
- x = (t1 << 18) * (t0 & (1 << 6));
- t0 ^= (t0 << 21);
- x ^= (t1 * (t0 & (0x010000001)));
- x ^= (t1 * (t0 & (0x020000002))) << 3;
- x ^= (t1 * (t0 & (0x040000004))) << 6;
- x ^= (t1 * (t0 & (0x080000008))) << 9;
- x ^= (t1 * (t0 & (0x100000010))) << 12;
- x ^= (t1 * (t0 & (0x200000020))) << 15;
- for (i = 0; i < 6; i++)
- {
- t = x & M[i];
- x ^= (t >> 9) ^ (t >> 10) ^ (t >> 12) ^ (t >> 13);
- }
- return x & GFMASK;
- }
- /* return num/den */
- gf gf_frac(gf den, gf num)
- {
- gf tmp_11;
- gf tmp_1111;
- gf out;
- tmp_11 = gf_sqmul(den, den); /* 11 */
- tmp_1111 = gf_sq2mul(tmp_11, tmp_11); /* 1111 */
- out = gf_sq2(tmp_1111);
- out = gf_sq2mul(out, tmp_1111); /* 11111111 */
- out = gf_sq2(out);
- out = gf_sq2mul(out, tmp_1111); /* 111111111111 */
- return gf_sqmul(out, num); /* 1111111111110 */
- }
- /* return 1/den */
- gf gf_inv(gf den)
- {
- return gf_frac(den, ((gf) 1));
- }
- /* check if a == 0 */
- gf gf_iszero(gf a)
- {
- uint32_t t = a;
- t -= 1;
- t >>= 19;
- return (gf) t;
- }
- /* multiplication in GF((2^m)^t) */
- static void GF_mul(gf *out, const gf *in0, const gf *in1)
- {
- int i, j;
- gf prod[255];
- for (i = 0; i < 255; i++)
- prod[i] = 0;
- for (i = 0; i < 128; i++)
- for (j = 0; j < 128; j++)
- prod[i+j] ^= gf_mul(in0[i], in1[j]);
- /**/
- for (i = 254; i >= 128; i--)
- {
- prod[i - 121] ^= prod[i];
- prod[i - 126] ^= prod[i];
- prod[i - 127] ^= prod[i];
- prod[i - 128] ^= prod[i];
- }
- for (i = 0; i < 128; i++)
- out[i] = prod[i];
- }
- /* from libmceliece-20230612/crypto_kem/6688128f/vec/kem_dec.c */
- /* 20221230 djb: add linker lines */
- /* 20221230 djb: split out of operations.c */
- /* linker define operation_dec */
- /* linker use decrypt */
- static void operation_dec(
- unsigned char *key,
- const unsigned char *c,
- const unsigned char *sk
- )
- {
- int i;
- unsigned char ret_decrypt = 0;
- uint16_t m;
- unsigned char e[ SYS_N/8 ];
- unsigned char preimage[ 1 + SYS_N/8 + SYND_BYTES ];
- unsigned char *x = preimage;
- const unsigned char *s = sk + 40 + IRR_BYTES + COND_BYTES;
- /**/
- ret_decrypt = decrypt(e, sk + 40, c);
- m = ret_decrypt;
- m -= 1;
- m >>= 8;
- *x++ = m & 1;
- for (i = 0; i < SYS_N/8; i++)
- *x++ = (~m & s[i]) | (m & e[i]);
- for (i = 0; i < SYND_BYTES; i++)
- *x++ = c[i];
- crypto_hash_32b(key, preimage, sizeof(preimage));
- }
- /* from libmceliece-20230612/crypto_kem/6688128f/vec/kem_enc.c */
- /* 20230102 djb: rename encrypt() as pke_encrypt() */
- /* 20221230 djb: add linker lines */
- /* 20221230 djb: split out of operations.c */
- /* linker define operation_enc */
- /* linker use pke_encrypt */
- static void operation_enc(
- unsigned char *c,
- unsigned char *key,
- const unsigned char *pk
- )
- {
- unsigned char e[ SYS_N/8 ];
- unsigned char one_ec[ 1 + SYS_N/8 + SYND_BYTES ] = {1};
- /**/
- pke_encrypt(c, pk, e);
- memcpy(one_ec + 1, e, SYS_N/8);
- memcpy(one_ec + 1 + SYS_N/8, c, SYND_BYTES);
- crypto_hash_32b(key, one_ec, sizeof(one_ec));
- }
- /* from libmceliece-20230612/crypto_kem/6688128f/vec/kem_keypair.c */
- /* 20221230 djb: add linker lines */
- /* 20221230 djb: split out of operations.c */
- /* linker define operation_keypair */
- /* linker use controlbitsfrompermutation genpoly_gen pk_gen */
- static void operation_keypair
- (
- unsigned char *pk,
- unsigned char *sk
- )
- {
- int i;
- unsigned char seed[ 33 ] = {64};
- unsigned char r[ SYS_N/8 + (1 << GFBITS)*sizeof(uint32_t) + SYS_T*2 + 32 ];
- unsigned char *rp, *skp;
- uint64_t pivots = 0;
- gf f[ SYS_T ]; /* element in GF(2^mt) */
- gf irr[ SYS_T ]; /* Goppa polynomial */
- uint32_t perm[ 1 << GFBITS ]; /* random permutation as 32-bit integers */
- int16_t pi[ 1 << GFBITS ]; /* random permutation */
- randombytes(seed+1, 32);
- while (1)
- {
- rp = &r[ sizeof(r)-32 ];
- skp = sk;
- /* expanding and updating the seed */
- shake(r, sizeof(r), seed, 33);
- memcpy(skp, seed+1, 32);
- skp += 32 + 8;
- memcpy(seed+1, &r[ sizeof(r)-32 ], 32);
- /* generating irreducible polynomial */
- rp -= sizeof(f);
- for (i = 0; i < SYS_T; i++)
- f[i] = load_gf(rp + i*2);
- if (genpoly_gen(irr, f))
- continue;
- for (i = 0; i < SYS_T; i++)
- store_gf(skp + i*2, irr[i]);
- skp += IRR_BYTES;
- /* generating permutation */
- rp -= sizeof(perm);
- for (i = 0; i < (1 << GFBITS); i++)
- perm[i] = load4(rp + i*4);
- if (pk_gen(pk, skp - IRR_BYTES, perm, pi, &pivots))
- continue;
- controlbitsfrompermutation(skp, pi, GFBITS, 1 << GFBITS);
- skp += COND_BYTES;
- /* storing the random string s */
- rp -= SYS_N/8;
- memcpy(skp, rp, SYS_N/8);
- /* storing positions of the 32 pivots */
- store8(sk + 32, pivots);
- break;
- }
- }
- /* from libmceliece-20230612/crypto_kem/6688128f/vec/pk_gen.c */
- /*
- This file is for public-key generation
- */
- /* 20221231 djb: remove unused min definition */
- /* 20221231 djb: more 0 initialization to clarify data flow; tnx thom wiggers */
- /* 20221230 djb: add linker lines */
- /* linker define pk_gen */
- /* linker use fft vec_inv vec_mul */
- static crypto_uint64 uint64_is_equal_declassify(uint64_t t,uint64_t u)
- {
- crypto_uint64 mask = crypto_uint64_equal_mask(t,u);
- crypto_declassify(&mask,sizeof mask);
- return mask;
- }
- static crypto_uint64 uint64_is_zero_declassify(uint64_t t)
- {
- crypto_uint64 mask = crypto_uint64_zero_mask(t);
- crypto_declassify(&mask,sizeof mask);
- return mask;
- }
- static void de_bitslicing(uint64_t * out, const vec in[][GFBITS])
- {
- int i, j, r;
- for (i = 0; i < (1 << GFBITS); i++)
- out[i] = 0 ;
- for (i = 0; i < 128; i++)
- for (j = GFBITS-1; j >= 0; j--)
- for (r = 0; r < 64; r++)
- {
- out[i*64 + r] <<= 1;
- out[i*64 + r] |= (in[i][j] >> r) & 1;
- }
- }
- static void to_bitslicing_2x(vec out0[][GFBITS], vec out1[][GFBITS], const uint64_t * in)
- {
- int i, j, r;
- for (i = 0; i < 128; i++)
- {
- for (j = 0;j < GFBITS;++j) out0[i][j] = out1[i][j] = 0;
- for (j = GFBITS-1; j >= 0; j--)
- for (r = 63; r >= 0; r--)
- {
- out1[i][j] <<= 1;
- out1[i][j] |= (in[i*64 + r] >> (j + GFBITS)) & 1;
- }
- for (j = GFBITS-1; j >= 0; j--)
- for (r = 63; r >= 0; r--)
- {
- out0[i][GFBITS-1-j] <<= 1;
- out0[i][GFBITS-1-j] |= (in[i*64 + r] >> j) & 1;
- }
- }
- }
- /* return number of trailing zeros of in */
- static inline int ctz(uint64_t in)
- {
- int i, b, m = 0, r = 0;
- for (i = 0; i < 64; i++)
- {
- b = (in >> i) & 1;
- m |= b;
- r += (m^1) & (b^1);
- }
- return r;
- }
- static inline uint64_t same_mask(uint16_t x, uint16_t y)
- {
- uint64_t mask;
- mask = x ^ y;
- mask -= 1;
- mask >>= 63;
- mask = -mask;
- return mask;
- }
- static int mov_columns(uint64_t mat[][ (SYS_N + 63) / 64 ], int16_t * pi, uint64_t * pivots)
- {
- int i, j, k, s, block_idx, row;
- uint64_t buf[64], ctz_list[32], t, d, mask, one = 1;
- row = PK_NROWS - 32;
- block_idx = row/64;
- /* extract the 32x64 matrix */
- for (i = 0; i < 32; i++)
- buf[i] = (mat[ row + i ][ block_idx + 0 ] >> 32) |
- (mat[ row + i ][ block_idx + 1 ] << 32);
- /* compute the column indices of pivots by Gaussian elimination. */
- /* the indices are stored in ctz_list */
- *pivots = 0;
- for (i = 0; i < 32; i++)
- {
- t = buf[i];
- for (j = i+1; j < 32; j++)
- t |= buf[j];
- if (uint64_is_zero_declassify(t)) return -1; /* return if buf is not full rank */
- ctz_list[i] = s = ctz(t);
- *pivots |= one << ctz_list[i];
- for (j = i+1; j < 32; j++) { mask = (buf[i] >> s) & 1; mask -= 1; buf[i] ^= buf[j] & mask; }
- for (j = i+1; j < 32; j++) { mask = (buf[j] >> s) & 1; mask = -mask; buf[j] ^= buf[i] & mask; }
- }
- /* updating permutation */
- for (j = 0; j < 32; j++)
- for (k = j+1; k < 64; k++)
- {
- d = pi[ row + j ] ^ pi[ row + k ];
- d &= same_mask(k, ctz_list[j]);
- pi[ row + j ] ^= d;
- pi[ row + k ] ^= d;
- }
- /* moving columns of mat according to the column indices of pivots */
- for (i = 0; i < PK_NROWS; i++)
- {
- t = (mat[ i ][ block_idx + 0 ] >> 32) |
- (mat[ i ][ block_idx + 1 ] << 32);
- for (j = 0; j < 32; j++)
- {
- d = t >> j;
- d ^= t >> ctz_list[j];
- d &= 1;
- t ^= d << ctz_list[j];
- t ^= d << j;
- }
- mat[ i ][ block_idx + 0 ] = (mat[ i ][ block_idx + 0 ] << 32 >> 32) | (t << 32);
- mat[ i ][ block_idx + 1 ] = (mat[ i ][ block_idx + 1 ] >> 32 << 32) | (t >> 32);
- }
- return 0;
- }
- static int pk_gen(unsigned char * pk, const unsigned char * irr, uint32_t * perm, int16_t * pi, uint64_t * pivots)
- {
- const int nblocks_H = (SYS_N + 63) / 64;
- const int nblocks_I = (PK_NROWS + 63) / 64;
- int i, j, k;
- int row, c;
- uint64_t mat[ PK_NROWS ][ nblocks_H ];
- uint64_t mask;
- vec irr_int[2][ GFBITS ];
- vec consts[ 128 ][ GFBITS ];
- vec eval[ 128 ][ GFBITS ];
- vec prod[ 128 ][ GFBITS ];
- vec tmp[ GFBITS ];
- uint64_t list[1 << GFBITS];
- /* compute the inverses */
- irr_load(irr_int, irr);
- fft(eval, irr_int);
- vec_copy(prod[0], eval[0]);
- for (i = 1; i < 128; i++)
- vec_mul(prod[i], prod[i-1], eval[i]);
- vec_inv(tmp, prod[127]);
- for (i = 126; i >= 0; i--)
- {
- vec_mul(prod[i+1], prod[i], tmp);
- vec_mul(tmp, tmp, eval[i+1]);
- }
- vec_copy(prod[0], tmp);
- /* fill matrix */
- de_bitslicing(list, prod);
- for (i = 0; i < (1 << GFBITS); i++)
- {
- list[i] <<= GFBITS;
- list[i] |= i;
- list[i] |= ((uint64_t) perm[i]) << 31;
- }
- uint64_sort(list, 1 << GFBITS);
- for (i = 1; i < (1 << GFBITS); i++)
- if (uint64_is_equal_declassify(list[i-1] >> 31,list[i] >> 31))
- return -1;
- to_bitslicing_2x(consts, prod, list);
- for (i = 0; i < (1 << GFBITS); i++)
- pi[i] = list[i] & GFMASK;
- for (j = 0; j < nblocks_H; j++)
- for (k = 0; k < GFBITS; k++)
- mat[ k ][ j ] = prod[ j ][ k ];
- for (i = 1; i < SYS_T; i++)
- for (j = 0; j < nblocks_H; j++)
- {
- vec_mul(prod[j], prod[j], consts[j]);
- for (k = 0; k < GFBITS; k++)
- mat[ i*GFBITS + k ][ j ] = prod[ j ][ k ];
- }
- /* gaussian elimination */
- for (row = 0; row < PK_NROWS; row++)
- {
- i = row >> 6;
- j = row & 63;
- if (row == PK_NROWS - 32)
- {
- if (mov_columns(mat, pi, pivots))
- return -1;
- }
- for (k = row + 1; k < PK_NROWS; k++)
- {
- mask = mat[ row ][ i ] >> j;
- mask &= 1;
- mask -= 1;
- for (c = 0; c < nblocks_H; c++)
- mat[ row ][ c ] ^= mat[ k ][ c ] & mask;
- }
- if ( uint64_is_zero_declassify((mat[ row ][ i ] >> j) & 1) ) /* return if not systematic */
- {
- return -1;
- }
- for (k = 0; k < row; k++)
- {
- mask = mat[ k ][ i ] >> j;
- mask &= 1;
- mask = -mask;
- for (c = 0; c < nblocks_H; c++)
- mat[ k ][ c ] ^= mat[ row ][ c ] & mask;
- }
- for (k = row+1; k < PK_NROWS; k++)
- {
- mask = mat[ k ][ i ] >> j;
- mask &= 1;
- mask = -mask;
- for (c = 0; c < nblocks_H; c++)
- mat[ k ][ c ] ^= mat[ row ][ c ] & mask;
- }
- }
- for (i = 0; i < PK_NROWS; i++)
- {
- for (j = nblocks_I; j < nblocks_H-1; j++)
- {
- store8(pk, mat[i][j]);
- pk += 8;
- }
- store_i(pk, mat[i][j], PK_ROW_BYTES % 8);
- pk += PK_ROW_BYTES % 8;
- }
- /**/
- return 0;
- }
- /* from libmceliece-20230612/crypto_kem/6688128f/vec/sk_gen.c */
- /*
- This file is for secret-key generation
- */
- /* 20221230 djb: add linker lines */
- /* linker define genpoly_gen */
- /* linker use gf_iszero gf_mul gf_inv GF_mul */
- static inline crypto_uint16 gf_is_zero_declassify(gf t)
- {
- crypto_uint16 mask = crypto_uint16_zero_mask(t);
- crypto_declassify(&mask,sizeof mask);
- return mask;
- }
- /* input: f, element in GF((2^m)^t) */
- /* output: out, minimal polynomial of f */
- /* return: 0 for success and -1 for failure */
- static int genpoly_gen(gf *out, gf *f)
- {
- int i, j, k, c;
- gf mat[ SYS_T+1 ][ SYS_T ];
- gf mask, inv, t;
- /* fill matrix */
- mat[0][0] = 1;
- for (i = 1; i < SYS_T; i++)
- mat[0][i] = 0;
- for (i = 0; i < SYS_T; i++)
- mat[1][i] = f[i];
- for (j = 2; j <= SYS_T; j++)
- GF_mul(mat[j], mat[j-1], f);
- /* gaussian */
- for (j = 0; j < SYS_T; j++)
- {
- for (k = j + 1; k < SYS_T; k++)
- {
- mask = gf_iszero(mat[ j ][ j ]);
- for (c = j; c < SYS_T + 1; c++)
- mat[ c ][ j ] ^= mat[ c ][ k ] & mask;
- }
- if ( gf_is_zero_declassify(mat[ j ][ j ]) ) /* return if not systematic */
- {
- return -1;
- }
- inv = gf_inv(mat[j][j]);
- for (c = j; c < SYS_T + 1; c++)
- mat[ c ][ j ] = gf_mul(mat[ c ][ j ], inv) ;
- for (k = 0; k < SYS_T; k++)
- {
- if (k != j)
- {
- t = mat[ j ][ k ];
- for (c = j; c < SYS_T + 1; c++)
- mat[ c ][ k ] ^= gf_mul(mat[ c ][ j ], t);
- }
- }
- }
- for (i = 0; i < SYS_T; i++)
- out[i] = mat[ SYS_T ][ i ];
- return 0;
- }
- /* from libmceliece-20230612/crypto_kem/6688128f/vec/vec.c */
- /* 20221230 djb: add linker line */
- /* linker define vec_mul vec_sq vec_inv */
- static void vec_mul(vec * h, const vec * f, const vec * g)
- {
- int i, j;
- vec buf[ 2*GFBITS-1 ];
- for (i = 0; i < 2*GFBITS-1; i++)
- buf[i] = 0;
- for (i = 0; i < GFBITS; i++)
- for (j = 0; j < GFBITS; j++)
- buf[i+j] ^= f[i] & g[j];
- for (i = 2*GFBITS-2; i >= GFBITS; i--)
- {
- buf[i-GFBITS+4] ^= buf[i];
- buf[i-GFBITS+3] ^= buf[i];
- buf[i-GFBITS+1] ^= buf[i];
- buf[i-GFBITS+0] ^= buf[i];
- }
- for (i = 0; i < GFBITS; i++)
- h[i] = buf[i];
- }
- /* bitsliced field squarings */
- static void vec_sq(vec * out, vec * in)
- {
- int i;
- vec result[GFBITS], t;
- t = in[11] ^ in[12];
- result[0] = in[0] ^ in[11];
- result[1] = in[7] ^ t;
- result[2] = in[1] ^ in[7];
- result[3] = in[8] ^ t;
- result[4] = in[2] ^ in[7];
- result[4] = result[4] ^ in[8];
- result[4] = result[4] ^ t;
- result[5] = in[7] ^ in[9];
- result[6] = in[3] ^ in[8];
- result[6] = result[6] ^ in[9];
- result[6] = result[6] ^ in[12];
- result[7] = in[8] ^ in[10];
- result[8] = in[4] ^ in[9];
- result[8] = result[8] ^ in[10];
- result[9] = in[9] ^ in[11];
- result[10] = in[5] ^ in[10];
- result[10] = result[10] ^ in[11];
- result[11] = in[10] ^ in[12];
- result[12] = in[6] ^ t;
- for (i = 0; i < GFBITS; i++)
- out[i] = result[i];
- }
- /* bitsliced field inverses */
- static void vec_inv(vec * out, vec * in)
- {
- vec tmp_11[ GFBITS ];
- vec tmp_1111[ GFBITS ];
- vec_copy(out, in);
- vec_sq(out, out);
- vec_mul(tmp_11, out, in); /* ^11 */
- vec_sq(out, tmp_11);
- vec_sq(out, out);
- vec_mul(tmp_1111, out, tmp_11); /* ^1111 */
- vec_sq(out, tmp_1111);
- vec_sq(out, out);
- vec_sq(out, out);
- vec_sq(out, out);
- vec_mul(out, out, tmp_1111); /* ^11111111 */
- vec_sq(out, out);
- vec_sq(out, out);
- vec_sq(out, out);
- vec_sq(out, out);
- vec_mul(out, out, tmp_1111); /* ^111111111111 */
- vec_sq(out, out); /* ^1111111111110 */
- }
- /* from libmceliece-20230612/crypto_kem/6688128f/vec/wrap_dec.c */
- void mceliece6688128f_dec(uint8_t *key,
- const uint8_t *c,
- const uint8_t *sk)
- {
- operation_dec((unsigned char*) key,
- (unsigned char*) c,
- (unsigned char*) sk);
- }
- /* from libmceliece-20230612/crypto_kem/6688128f/vec/wrap_enc.c */
- void mceliece6688128f_enc(uint8_t *c,
- uint8_t *key,
- const uint8_t *pk)
- {
- operation_enc((unsigned char*) c,
- (unsigned char*) key,
- (unsigned char*) pk);
- }
- /* from libmceliece-20230612/crypto_kem/6688128f/vec/wrap_keypair.c */
- void mceliece6688128f_keypair(uint8_t *pk,
- uint8_t *sk)
- {
- operation_keypair((unsigned char*) pk, (unsigned char*) sk);
- }
|