ed25519-1.2.4/0000755000004100000410000000000013260523700012542 5ustar www-datawww-dataed25519-1.2.4/Rakefile0000644000004100000410000000113213260523700014204 0ustar www-datawww-data# frozen_string_literal: true require "bundler/gem_tasks" require "rake/clean" CLEAN.include("**/*.o", "**/*.so", "**/*.bundle", "*.jar", "pkg", "tmp") if defined? JRUBY_VERSION require "rake/javaextensiontask" Rake::JavaExtensionTask.new("ed25519_jruby") do |ext| ext.ext_dir = "ext/ed25519_jruby" end else require "rake/extensiontask" Rake::ExtensionTask.new("ed25519_ref10") do |ext| ext.ext_dir = "ext/ed25519_ref10" end end require "rspec/core/rake_task" RSpec::Core::RakeTask.new require "rubocop/rake_task" RuboCop::RakeTask.new task default: %w[compile spec rubocop] ed25519-1.2.4/ed25519.png0000644000004100000410000006407513260523700014262 0ustar www-datawww-dataPNG  IHDR6pPLTE񧧧RRRSSTKKK !!!VVVyyy۲BBBvvu888׻+++oooŌYYY...ԥEEE$%$<<<ʉcccґ???HHH()(OOO}}}555rrr000```\\\hhhߖwz|;R@PDž~gYl\ζ?kA$cZ{I32U^7uI$I$I"st|z+[j"fi-貽o.UHepTò (nri} t zRV'$\6q${u&;Q啺Ȑ~<֘`}l}w.Xۯ>'ý[ QuHe79r+?jH-9Txn+.pOb%903g,VNH/犦W_Z;g 0$3xI}įFϐrH!,xjXU z){/dȅb{yیCe'r|xeA\o#Kmd/8FCzUA@J |VBdHn1 OFIsUs<aQ CN/JUH?3/ xbgA[7PQG=(DF,BYAۯ/tkȡ(<>'F[2!M0*`֍ V=5(ʥCJELaB 8/53Yg[Lإ »:;#l4om9#\Ľ05H BZ鸞i-xPwApqE,f\a&yaL>e &9 TAS7*gi(T*R gr =kJ&;+1B@Np/C*Uϼ;tya+qP\q_o>E~?{X~;3H>&&žw\gN9߂zpRON~ ~ Oh'f܈ \(j繖~fFϿd6i&9d0_ Dz6v|6aA*UckMPNn2 ?\qWjdѸ' =]GwТm3bl Yfպ 3zww2dnrvP<:/X>R3914x~4bnC*\c\~8G>(o{ܸ RV qÈcIjW(¸ 8Os_  c6?\5ǍG{t!g Z."n\θׯ.Ⓑ)ņRꞮd5 lq\U\B, QE_66!0#5nŽYMSg<9yVDaUnd)AۥSs(|W*XmUVjL^Y}ˏT:rS_E\]K~uWhE g46aQ!,"؊Ϝ;ns]%Ѱg)4WtCCJĐㆦġ"kF\Ϟ{HdF|bFy{w̑~DGX_o#7K| k"d^jmVbxA܎EF2ُEIR1Vf18$iT~IAH2:HzvxB6ɷ4mFf rBϡV&H6 -]Q~WLHm'jy %htl-5UT6zcm ݣrRQ26 $β|`x1?' [rޓ˻ea2Gvt4=01frysr?T,?%"=ˑf+Aq0R Oz#tydUu-oDxەoЕkͽTyG(y}(2]`zf +fHe4-%d(" -:W~,0% ,2m6rS #[fNh 5d/l}MK"\ tC*$̀y=ؠz7p4ѡx7XPqr! Jl/UMcP+--:Ax ܍ B}B%m5[ln;0Z@B؇P%lE=XM'g#kp< ~[dmhF$1im8DN@CKtT 47SӘ مE{I j3Pk@N$؉NWy[ZoTա($rhETBhf1R@gCu* *0 y~b qܦb]?2d[Ul UsaljAxFےc mp:qtĺMj{!o ]y, k~lxgw$fnAxܻC] zӑJ`scGGw){L: ~eN,.ufe\թS8Po"YxJ̌Dx,p ,, b +Bk=b{ֹ؍!~b)ΝK4?^MݭK)1b#5=f,0n9sD<㶊Ύ)냻ō&!)z[5SVN7U9զgLPkۨ HchiXXDV̒Ƚ,ԨsR1u7qS9vQ/![1Iч|@PL3n*AEwyR;kO-A"/țD %);q0;ȏ~C~xE+%\Zd5]ȓ^2yqjdWг繱!8C}ڌ8gYV!Eݸig?LnvkrY]>@-0ԬWivOpq@`dzv -Ӆnr6rdyEɒv ʹLǒJ`yxN*Zu=Jx &\E^ȱNr@O9` "!6h(0zUB&9،(RB0rD=e" Q[\clL\}#8 =ehzb LV= !|M% N k!N7Kx(օSjyJkq5iW+P4i¿jJL]=sl?NfDf{;3q]j EGYEΩĠ k Іqfm2=:G0d+!F@%IF+FKc87Z&F3j7D+#;PGz̭hu@hr++w'q]hL4@@R~0@4G#FB[v6N/vdѓB;+ídT([4`g BWz&iE>i9 BȔ,]Dfb6ѹ Gm͂Y'9*j=iyjmoӳ hlWv_21CS@rv9Xލyb7Zg;$U%hBB(jGB)"ZUT>5RDƢxKS!aѭ=`|$);SEqbWxnɯ{ks^K V@zhWS3IL4d0ΠNP u’fjA#&Z4 d#vJThVR-IYrWji$%N$ he  fopŇ90q4wf~F6؅oq)>q=Ni|3Vfn&H0=@K-`lb XRe*}!o]\ V- ZNwǹ[r,5)C0>@r2N IUb_VG+ρO+/O3Ȏnj ť߯ j^5D.A0n 0#fHԬ S Yo A 2PI-VLll`N00Th!q Pt&Tk>x6Bޖw8z1!c\~1,a%Jޅ춖GNLJw)l"&$`{)Wvq P u E\VR?;twOM"K_CP*DBR&(&Cdi=hЯYFP/WKLǚbؒ߮yl>9'H5jIΣ %a&\@IR!R!BPX )yh\j4J;5g!%`e@U%l6W 3qd08~ fi \@2A^"˅`ԏuG1R`[Џ!XT:Z%(UQb08_WW7#FsBPP@!Ւ7135d850>D7 w6we0n0>TG,Sƪ+5RR'48u|^} ɻ6-0b)EbATĘ:C8}zK-PYBͫ@c? SҊa; ddKe@2TĴ0dB n]>)&^ƩO~@EȦZk8ĥ d4F6?6R*pn p=wC^>ۜ5A<1ӽ1c!jϭڜH%u(I+:bߞ-N|g6ecj77:,E~pIq x^0G؋N*8H=wQ`8 901>J ? |9蟛bDv\ca0t Ɇf}mebZ+ MK'\V\= %Pq6CB'F@EEP V}W֠Zj3AS  6%:@]BC4Tp:z,K. Rs%K|MOl1Q[#QrNѸv`puzi#.= ߔgռdhH-j(ީGG񝩤g@TEՍ;-Ԅ`_փ~ .0j)>XA7l2|O[Q[!'"c?ceC5_YV::F(9uy.~È(Pa0$d6 |b_+rX©8 51bn{7XT@9>oʉ_!CHA3/7t)ͶY(Ǟř#dєEn8JJs׏#(_qf!+GȘ(0PeA\&BvE#Qd&2yO&=9%8Cɶ(S)Cn$P(j_tOՄܧJrKz(4,?<ىj/|zG~FJc Y<rɅ:3ůKƌGaGf7O[e隸sNiiФ%)/aQ-AB0P(/Aĥ$HpHpKԸXߘYffx$4vӖؘLss 9_s£N3$h|4>ٌm-QbKĽ2`TfU6@#åG-=A< (O1q¿]'7Y#c N'/zbheBC"_oƢ7=…<0آ￐od ,8=ʄ$a̐bQ2[]X1><4R0hTM>xiFҊӣLPȜ$'vC\Pp) %v"wios !*>CB;>eBp FpwvCم̘81biL&ć1T!\h=&x{yb_s`d*RxyUG|Uu(0ǟ=R-jβKdtqD$"^;:PgR&V6K! 2W 2:5ᗷCe!xI57^WxJCuУW1Qd닃,2FF/6-.7g<&^)89N/OX@B]!F @-yңMfhhcЮIbd,Ɔ7YK[R\&r7#8ڲaVCOr k}{`Yx 'D9BbH=k7+ôGd Q`_2E* A]wKܗ$To"ruS]k)dZNwAY>B ~ h8ۃg`nÉP&Zij8&ǿ^.f7u.-HoZ297ee d 3q.{wG$ʅ`CE4 ዿB{*2ܘ⃩qSoS޻$qM*BHJGuJg5vBnH%TI a̱p{9Ԍe3>bv*k7SYnuRtI2iنgg};P> xʄl}YFņB!ccKB!V A)dȓL|[d|Ϛ3, ̅x![Ϣ"o_WBo! NT`\PɄ'.BфڱoPJo9\K"^Ŭٸqgk5cCCWVTR}f iDIq 9@چ^JLh.t=gn]x@D#ēp(!|Ɨ?/!+ vh ["rOc'Ulxz?qxch Sp ` ,lCZEw&Dmc a~hexXg:_04W\/Gᇷ x776N>Ob* s*0aP;' 8Y#24]z.a" f1<Y`=B?i!$S!Ojv}+H< 4dW(Y~ hαs@7(<ڜJz!ɇTFSNzK.3mF Cp-(r l!<544Vgo-BR7)!RL a(f%kcvh@ã߂IZg%Ba30F07<Շ?h?: b7AtQbQ"_qzR 4S!@52_T!iÞA.zj,3m\)`$0i`)]z Y}_yR53o9߈X p@w9`_(L g{\lG$!(@pԠ961q0|af0(s/Ԅ0C%{c Jq$ad ^FTU+܌ ا=r^o ,t0إCۧ& F'J!!(<c>ve,:Ǯ|{qǢh@\\}n'όԚHt>4[g8~69~(:]fոg"q51Q +@A;D8}pkU7 '&Į8 ϳ/\ޣ (0BW Ac4;)Vk٨QSSuiLh;M.i7M&lOHA ur~ ̄I 3:rG sHM^O10[2ux×/GnMDif_ݵA84()i(аQƛ7p=5O e!hA5 jih@9su.Wr+Q0S#reLb26Z snLQ Pd8 hLK]3 z3-+o۽auL/7KSH,˕lڜsSG{X9BHTC2KԮ۟v׋ю:Cw 44nIn~pC6=dK֕!;|R> +G }q°s l1Tp|.%`^@gsub> }8;τZ>X>42j&K܇nY@&9Bb.u a`gv8˶"VL@VQ-Z5#+#65ǀ(lmv[Q8l+{A6'^"8<&9'Z-`4s1lZj7zp2TRhO_&삦jSTN4i0sO}GG.&YZn,ռm c)M”ZXG OhQh-2ɟnr|v²H 'SQ`=TGáP4 ;q`z`=BF+M%A{B 4 Pd߷t`T/fsJ21Aчݯ'?,Pa ]`c"ܛA{ hfj*^`Kˊwu쮙YFR<xtQhqMYQ{uA|*"[6l jC^pe{28jسE{/Mʇo}6e{&(Z 1%E eRq'pQ]*y)&1MPu\?HIBkkMYU^xxW h^BZUng+,3C8<,[vYYQ%*%'"4 5ߪPDbHJx˷ޠDBCϞčײnz!% y Pe&>ef9b(> M;eɆ,+^qz)Jn^'Ĥ`a ;Xϼ9KwC Wh%2##ZJ) g$.Θphُ r"<2zc&]ެ^ENAC,ѼǦYN6U9Zزbu㊳).[8 W!̮̲ ?K,59Xe=a6R><>KhAJL*G$=I7_Vv>]9h+ #= \K;C7,+;W,$VVy<⪱ǎ,+!?zTmb!1"mP~+VYq=CF3Jch!MNWCsT@ ضirD~V4g(вbm~h(ԈjGƲ(Tزbm:*i`#h_[V F^ C;6{o}Ƅۄܾ2!E[,Z0'}=6tbY>i.Ρ&ӈ*Ӏ:sKՏYV>n\l6X!{.j+yɴ|:(|θqA9%'\mov-+ ¼hAe wS6͛f` 31\e4lb#O: .̭yȠ {Bf7&càˍQWp$ʶpcSMn,+_Y,2ʟ0S4 -0d3aZ1˃n/܃#1TvSufYqN}=i+=&R0˩!u~pV/vFiŀܫ[$\4}l̲bYEQ Fqż`| ȆDf* J(z_Ug+w#=iNΒT B5A]a@Q B@OFkdž,+VD%y.kFc 'Я3 UP35T T,zgIгnӄgpdx76dp6XhEc\5Frq3.clL"Q#x(j$=[V4L QoGN֐}\3",-9}#8c d~P6Y78m @eW\}FC1Q`$FD5&号 eޫǑ3C9;~rLJ93b^/]mPcYQ]SV(p; , #Eg A0d7vJ4Q62,+j[50蝜U&i&$$V1B73Ӟ)G6@`'69 ܾ ?sYҮۻq:#9Q'tcOr98\u WXPmYm1.c؛tkG:Y*)+jfHLT >SfY;gH{m4iԞx6qpӪ Z&inIb=`gL j$fe-'kp0%A2!5mdyHc*bŠMjSB("2S!$#b,`8LlOD7'MɬY 8k ziW8KZppr:MJV!هmT́/;FL śal+*=LIQ 'ӴBMDWvP\WJCQfq{5R4jDgtYLAkuy!L;jҾmǚEe9Ul+y2)2TqWn4H܃6z@%^b@{A(Ѧ86O{)T雝uԊ;"'6B@C6#Q3憜#fX5{+9 !wZ;LWq`w{e}[vcY qla%JϹ ~LcaT#>q7\{d"^CĖZʕuUkz e!kܾ}Q̩kN8A o &[:vj B P{[5SO>g @΢r-^PYC]e*LN;m0 Bgn2 h73Oؘ@3rg߫TY1֕2cg tf>9*Z{[Jh6"7j0 KnŁ%TVlc |_'Ef KC. FA撆oS%59 %VRUF3maX"DYqCAZ쬐yOي 0QJmVs2 ^?B(L@V2xbXGB!Mɮ H]F.=^($hB`Zi@>V3 )OdC @Eln3/+Jwedd\MqzIwQ \丿lEʊi=YҧTcwPZSe;AIKcMqiN ZDi +0qG"kHgC;Lhp-]ݝy-ʊ{:g Ye]YFٺ&BP+7S{ @iG e)/˩#a1I*xD#Sr 2YCTe7tbȡA.  Һuw^K\R,.~Ub(+J12ȫIIB9Kb/V!3l1!g療 ?ʉp]iѲ킏]/~;JJ1* G>GA~H:d&=1l"f#3Wy|rc |YXz/û.1߽kg?qKSgcg{7Z.lLհIm2AfOf5cDy⻥ ZK߽wS-/?Z {*WV\揍A<ZeňnFtOfgDa1fDHXᏋbN|J`e< 6]˄)h-s_ēU[qG B&U4CA3GXZw9Ͼ+KKKFj \ ']/./ xp r"("2 2ץ!Yw iZY GJ]*ZIUƔ@8=L  aO)\v-S 2WthSrf X+\X6~'UXGHI򣅅/Wչジ%vR8|dhxp'ʊ0 yhhrFahŰQ, kW,?H`GrظL&fǞF)+4q?L^j-vcf*$V((ql[Pp^.Dڬ9 @,>ʽJ c>`U|tA(y7J#JeNfy9#{ 6씄 q]٭xLyuONw>$3vR+U-3k{a)RYG>"]/(!u791eNY 5$ptǫz9U"MB|>8IN:=_{)cPN B &sتE$_@ hHqlVZm;N`km{ ]t.טB =l.wZz2B(0< !9 f0xM(3ctbOwLa/W}ؤ(CZ!"qpj(}|qqITb~rP>X1[Ե%(tiWZF!hbN]\) ^x%6i(s?[o~ (5]i(=_*;X!ɠQN^O <*?-z(3P7,*g:U Ctl-n*dlARm|G JYP\|WY q YkZ{EAVN t\khl Tv[}P^3=K8k*Ջz+9 2aҊ5 ˆ6@}7(~Tx$ˑ\wܣRم-Fiw8 Bn ,A` ~;0ȏ@?x%Y4PrN"yιVٌ(軆,aZZA*hก"K458Ht7PُQd>k.<,E5L=ItMKئ홫jbwلGt\Y>Edems~,s9upP$y˞.٢ bi8k"g5nDw Åa ,>u27*O3.#)'6`^ڍ{v:)Mƛk'K{=;y *롩IpbEqwy5Fb,#m`|nB?n 72EӵRơ}u2yƯkenC+iɀ> ('+!sڿcuHܤԧMҘiZ&},!} ҕ8dٌ=IYIݐqQKy9ѽo+M"[T~L5!B0.%g}]xEj斳>q1TA-S7Z,WT"}e0QE:yXVЎih5 jc5Xqø*ħImAICP5eX]0OD. Mө̝V{ +1_T؄ fuMU{xHՙWK9$Y 2HU#)hfR H+P>a-<^ys/)F^ҩι7%j$i"Yjz:ݹ4bdAW1k=(0g Ɔ `S7zSì̮'n4C^#IOUJ&kIrDt7?5ä.syEUp6qԊ#҉J?Di?Kgw7y, Jh3 ]o01ytNۏh8:"~%&'UcXFD GI9fIGRb쑕)Q*DsBN0q+u%4\$Rz][P&!CncYf6aLl$h{2b32ULUUSxVTjV"թ%j\j(xRk 3%;07MؚIΜ8R$VRk8#P{d(!`O^GK $ e4BbdI64]d 4Fa)"sK -ChWz}t9n=CPHa16,x7b9pˏcNJ3s؇d^l )`s.&HI؟d޸u&bD W8Rx(;.&ctgdx2vƉOU25/U& %j] 3S؞ }{sFN2FC* E`6W&x$58dGmdI+<դcWTFȅ }m3pKM?j֌*2qNVKBg'F Dm%h\mV̅$3H?udnrmр}QXrIV– d7qۥ Hi.#) %U1Ԟr/7O#$sUdY6o>*H=ʴeQtɍ!}rwG DO qeqԉKIo5'[ŧj9 Qw8l X#<8qZN<̗Ekɹ۳+,P:ڙB]g,kNWUkI/+&Lj$qώ^ %߻-!ٟ~/p#I~(xSdb/V&N{mgrWujIU`Ǟx>'[vOa66W#\[[l.hH#xkHfX^p꺃_ IjNqCEJ5iIUu0>DÃ$+S:il;n,"v,(vRmQՈ$JxM6I$YM(kO˰$}vl ER%oLNF`WY*Wۺ>̬ǚb+oڢi;ok& mgbY ELe"S+?NP][>TńϾ2'c 6=5aw0I`1a}y)LNlҚCd)=Ywh&k`1E-.=HN$Y|PM. | > XL•/G_zג~=֝$;dؽJ2:IVY%p #gG̎d%Lp^mT9xw&ՕR^%P$d˩Ip6rSa'6#CPɒa-M&CBCEhCxXJfc{ @Q 9)x^9UÐϬLJx+N"-I 78PR bol+ST<H;!1} U3CΓ5׼xObTeKQn*JBRGf6dy9 ԫ̮٧*iyՁ]S<1Ӥרjk5\ Q7Z&u5Y0 ڲp&?@k2R'Yh^]^\AX\}l +Cbejiqz #=_+O[04$]cW<ܢiJXrN @n(̕8ʜAyL*Y$$ɥLOsK|xnjX47ck+[0ZXjA`|2nxHb;ιqz> Bg 0 &!WgVəOL`dn<ܜ{LNb@AXu;1`*Y\e@ h\A(^ BP a 1%G !d3AI+so߲dqbus&-ŹD@uh0`]Eh] B@1׃`kt]vj-t']CDx`jyv%L>ɵVsou̅=ϫd <I@T[pAzS# `q,Opa^xӻ\,n%>djJ,곩 M>tXYzݒvzӴxR4 Wc):Iө,ͶFC =M簕kgoaϔ)l lHKVH~ZCïfWg/5[ػ@[t|ӥ{k@-U ӱ6>68anj)keEw$yF-g#ص?Nr >2 c^8 [6hj; xe&l+_\mޖPLf^X^hqN$beuf@.6.Nd4/oS^DBBVぶ Ww VYF]|oǾ)<8DDۀXFADGY 1&8Uhkp.Q@y<:BEmL19JH |+H şJaI|o 2)v#PS_zƙѨJ,ܒG^14e48ُBtN^[QL\kkYW Fժ55iG# WwZ ;(j`f|3<'h#zp* P$j늺5W¥i:GFʋTsDIH ;Fo@r4ɏα=bSUdʻ!%_d?ZhI`%QuG-@N+?̇KLx(FU@ܹ5zHôRs UNF-aDVV>eZc@&Q(% 2TAt$N !=F8cMM*@QiΫnlٗw޿74<|pq`nBRb#Sx`UD9lt;EfRK3H oS_f!0U0Q6(r.PF|{jaJ6m҉\?pi.CiQÊ N3l's>NOx&ho.BQv\nWt<$݈pJ*>!!먲96kλ {p\o{_{pͶOW~8sGTdb.82|E}[&Aܿ=W]PZחޛn2bzuG"ۣOT穹J;ɧVK;"WehijkX)>YZ5zD*`7(r&ŖwOv)" ?2 -ʲ49T$u$lOiu`ebHf)# U. _3֓`eO $;2d0F#† ߲&Gv/&Z/ՐG=Ҍ _R쎱4w(Iu|ɢ!+kLҮhA>5FX'r67t #ȧ85"Nt&.tAK>!Y%Z=-UWbK$gx'|fe #hWNyPf ɥϕ bGdXc)|kUeo{fC׬;bb2Duhᙖ^;7yM/.3ݨqLF<^rJ"xNwǛ^]s okGNa}I]Pxnx g)^5|].@'#bI;K™h(Ze'd}5o3> VUMx`5<0aDZ7r},L6,I1)@@)MH)&:IkA,S~dyE\D3_DM ^H^5ߧ۪Dq:;Co6oѨ$3b|\J&}N~і'}6k>m[K gƥUC/Zk;I`H?aC~#%(^ b>g{OS}JLN+xUޏ0\d8CF#8s oUcGpai[AH֯Vh+Ah;+ UC_{(ܚn_{d뻓t1xTe s. G$ В!46y@RCtuŐ8,Naǜ$B!XP!(2?c /j3=@CvTQJ6rb@o x(V݄:cJµ n9j2p[P)+UDK*g -|-q7#\d얢gdT iE 42 ua?M%3i`ֻ@VeK`j4qz7/q3HFl ,=vb=!mlLjA/S 1.0", require: false gem "rspec", "~> 3.7", require: false gem "rubocop", "0.50.0", require: false end ed25519-1.2.4/appveyor.yml0000644000004100000410000000063113260523700015132 0ustar www-datawww-databranches: only: - master environment: PATH: C:\Ruby%RUBY_VERSION%\DevKit\mingw\bin;C:\Ruby%RUBY_VERSION%\bin;C:\Ruby%RUBY_VERSION%\DevKit\bin;%PATH% matrix: - RUBY_VERSION: "21-x64" - RUBY_VERSION: "22-x64" - RUBY_VERSION: "23-x64" - RUBY_VERSION: "24-x64" build: off test_script: - SET RAKEOPT=-rdevkit - ruby -v - gem -v - bundle -v - bundle - bundle exec rake compile spec ed25519-1.2.4/.rspec0000644000004100000410000000011713260523700013656 0ustar www-datawww-data--color --format documentation --order random --warnings --require spec_helper ed25519-1.2.4/CODE_OF_CONDUCT.md0000644000004100000410000000623113260523700015343 0ustar www-datawww-data# Contributor Covenant Code of Conduct ## Our Pledge In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. ## Our Standards Examples of behavior that contributes to creating a positive environment include: * Using welcoming and inclusive language * Being respectful of differing viewpoints and experiences * Gracefully accepting constructive criticism * Focusing on what is best for the community * Showing empathy towards other community members Examples of unacceptable behavior by participants include: * The use of sexualized language or imagery and unwelcome sexual attention or advances * Trolling, insulting/derogatory comments, and personal or political attacks * Public or private harassment * Publishing others' private information, such as a physical or electronic address, without explicit permission * Other conduct which could reasonably be considered inappropriate in a professional setting ## Our Responsibilities Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. ## Scope This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. ## Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at bascule@gmail.com. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. ## Attribution This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] [homepage]: http://contributor-covenant.org [version]: http://contributor-covenant.org/version/1/4/ ed25519-1.2.4/.travis.yml0000644000004100000410000000047713260523700014663 0ustar www-datawww-datalanguage: ruby cache: bundler before_install: - gem update --system - gem --version - gem install bundler -v 1.16.1 - bundle --version bundler_args: --without development rvm: - jruby-9.1.15.0 - 2 - 2.1 - 2.2 - 2.3.6 - 2.4.3 - 2.5.0 matrix: fast_finish: true branches: only: - master ed25519-1.2.4/lib/0000755000004100000410000000000013260523700013310 5ustar www-datawww-dataed25519-1.2.4/lib/ed25519.rb0000644000004100000410000000476513260523700014647 0ustar www-datawww-data# frozen_string_literal: true require "ed25519/version" require "ed25519/signing_key" require "ed25519/verify_key" # The Ed25519 digital signatre algorithm # rubocop:disable Metrics/LineLength module Ed25519 module_function # Size of an Ed25519 key (public or private) in bytes KEY_SIZE = 32 # Size of an Ed25519 signature in bytes SIGNATURE_SIZE = 64 # Raised when a signature fails to verify VerifyError = Class.new(StandardError) # Raised when the built-in self-test fails SelfTestFailure = Class.new(StandardError) class << self # Obtain the backend provider module used to perform signatures attr_accessor :provider end # Select the Ed25519::Provider to use based on the current environment if defined? JRUBY_VERSION require "ed25519_jruby" self.provider = org.cryptorb.Ed25519Provider.createEd25519Module(JRuby.runtime) else require "ed25519_ref10" self.provider = Ed25519::Provider::Ref10 end # Ensure a serialized key meets the requirements def validate_key_bytes(key_bytes) raise TypeError, "expected String, got #{key_bytes.class}" unless key_bytes.is_a?(String) return true if key_bytes.bytesize == KEY_SIZE raise ArgumentError, "expected #{KEY_SIZE}-byte String, got #{key_bytes.bytesize}" end # Perform a self-test to ensure the selected provider is working def self_test signature_key = Ed25519::SigningKey.new("A" * 32) raise SelfTestFailure, "failed to generate verify key correctly" unless signature_key.verify_key.to_bytes.unpack("H*").first == "db995fe25169d141cab9bbba92baa01f9f2e1ece7df4cb2ac05190f37fcc1f9d" message = "crypto libraries should self-test on boot" signature = signature_key.sign(message) raise SelfTestFailure, "failed to generate correct signature" unless signature.unpack("H*").first == "c62c12a3a6cbfa04800d4be81468ef8aecd152a6a26a81d91257baecef13ba209531fe905a843e833c8b71cee04400fa2af3a29fef1152ece470421848758d0a" verify_key = signature_key.verify_key raise SelfTestFailure, "failed to verify a valid signature" unless verify_key.verify(signature, message) bad_signature = signature[0...63] + "X" ex = nil # rubocop:disable Lint/HandleExceptions begin verify_key.verify(bad_signature, message) rescue Ed25519::VerifyError => ex end # rubocop:enable Lint/HandleExceptions raise SelfTestFailure, "failed to detect an invalid signature" unless ex.is_a?(Ed25519::VerifyError) end end # Automatically run self-test when library loads Ed25519.self_test ed25519-1.2.4/lib/ed25519/0000755000004100000410000000000013260523700014306 5ustar www-datawww-dataed25519-1.2.4/lib/ed25519/signing_key.rb0000644000004100000410000000343013260523700017141 0ustar www-datawww-data# frozen_string_literal: true require "securerandom" module Ed25519 # Private key for producing digital signatures class SigningKey attr_reader :seed, :keypair, :verify_key # Generate a random Ed25519 signing key (i.e. private scalar) def self.generate new SecureRandom.random_bytes(Ed25519::KEY_SIZE) end # Create a SigningKey from a 64-byte Ed25519 keypair (i.e. public + private) # # @param keypair [String] 64-byte keypair value containing both seed + public key def self.from_keypair(keypair) raise TypeError, "expected String, got #{keypair.class}" unless keypair.is_a?(String) raise ArgumentError, "expected 64-byte String, got #{keypair.bytesize}" unless keypair.bytesize == 64 new(keypair[0, KEY_SIZE]).tap do |key| raise ArgumentError, "corrupt keypair" unless keypair[KEY_SIZE, KEY_SIZE] == key.verify_key.to_bytes end end # Create a new Ed25519::SigningKey from the given seed value # # @param seed [String] 32-byte seed value from which the key should be derived def initialize(seed) Ed25519.validate_key_bytes(seed) @seed = seed @keypair = Ed25519.provider.create_keypair(seed) @verify_key = VerifyKey.new(@keypair[32, 32]) end # Sign the given message, returning an Ed25519 signature # # @param message [String] message to be signed # # @return [String] 64-byte Ed25519 signature def sign(message) Ed25519.provider.sign(@keypair, message) end # String inspection that does not leak secret values def inspect to_s end # Return a bytestring representation of this signing key # # @return [String] signing key converted to a bytestring def to_bytes seed end alias to_str to_bytes end end ed25519-1.2.4/lib/ed25519/version.rb0000644000004100000410000000010613260523700016315 0ustar www-datawww-data# frozen_string_literal: true module Ed25519 VERSION = "1.2.4" end ed25519-1.2.4/lib/ed25519/verify_key.rb0000644000004100000410000000263313260523700017013 0ustar www-datawww-data# frozen_string_literal: true module Ed25519 # Public key for verifying digital signatures class VerifyKey # Create a Ed25519::VerifyKey from its serialized Twisted Edwards representation # # @param key [String] 32-byte string representing a serialized public key def initialize(key) Ed25519.validate_key_bytes(key) @key_bytes = key end # Verify an Ed25519 signature against the message # # @param signature [String] 64-byte string containing an Ed25519 signature # @param message [String] string containing message to be verified # # @raise Ed25519::VerifyError signature verification failed # # @return [true] message verified successfully def verify(signature, message) if signature.length != SIGNATURE_SIZE raise ArgumentError, "expected #{SIGNATURE_SIZE} byte signature, got #{signature.length}" end return true if Ed25519.provider.verify(@key_bytes, signature, message) raise VerifyError, "signature verification failed!" end # Return a compressed twisted Edwards coordinate representing the public key # # @return [String] bytestring serialization of this public key def to_bytes @key_bytes end alias to_str to_bytes # Show hex representation of serialized coordinate in string inspection def inspect "#<#{self.class}:#{@key_bytes.unpack('H*').first}>" end end end ed25519-1.2.4/.rubocop.yml0000644000004100000410000000062113260523700015013 0ustar www-datawww-dataAllCops: TargetRubyVersion: 2.4 DisplayCopNames: true # # Style # Style/StringLiterals: EnforcedStyle: double_quotes # # Metrics # Metrics/AbcSize: Enabled: false Metrics/CyclomaticComplexity: Enabled: false Metrics/PerceivedComplexity: Enabled: false Metrics/BlockLength: Max: 100 Metrics/ClassLength: Max: 100 Metrics/LineLength: Max: 128 Metrics/MethodLength: Max: 25 ed25519-1.2.4/.gitignore0000644000004100000410000000021013260523700014523 0ustar www-datawww-data/Gemfile.lock /.bundle/ /.yardoc /_yardoc/ /coverage/ /doc/ /pkg/ /spec/reports/ /tmp/ *.o *.so *.bundle *.jar .rspec_status .rakeTasks ed25519-1.2.4/LICENSE0000644000004100000410000000206213260523700013547 0ustar www-datawww-dataCopyright (c) 2012-2017 Tony Arcieri MIT License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ed25519-1.2.4/CHANGES.md0000644000004100000410000000365413260523700014144 0ustar www-datawww-data## [1.2.4] (2018-01-04) [1.2.4]: https://github.com/crypto-rb/ed25519/compare/v1.2.3...v1.2.4 * Fix JRuby platform name * Add license information to gemspec ## [1.2.3] (2017-12-31) [1.2.3]: https://github.com/crypto-rb/ed25519/compare/v1.2.2...v1.2.3 * [#18](https://github.com/crypto-rb/ed25519/pull/18) `ext/ed25519_ref10`: Consolidate fe.c and ge.c ## [1.2.2] (2017-12-31) [1.2.2]: https://github.com/crypto-rb/ed25519/compare/v1.2.1...v1.2.2 * [#17](https://github.com/crypto-rb/ed25519/pull/17) Test against Ruby 2.5.0 * [#16](https://github.com/crypto-rb/ed25519/pull/16) Move project to the crypto-rb GitHub organization ## [1.2.1] (2017-12-15) [1.2.1]: https://github.com/crypto-rb/ed25519/compare/v1.2.0...v1.2.1 * [#14](https://github.com/crypto-rb/ed25519/pull/14) Support MRI 2.0+ ## [1.2.0] (2017-12-15) [1.2.0]: https://github.com/crypto-rb/ed25519/compare/v1.1.0...v1.2.0 * [#13](https://github.com/crypto-rb/ed25519/pull/13) Add `Ed25519::SigningKey.from_keypair` * [#12](https://github.com/crypto-rb/ed25519/pull/12) Add `Ed25519.validate_key_bytes` method ## [1.1.0] (2017-12-13) [1.1.0]: https://github.com/crypto-rb/ed25519/compare/v1.0.0...v1.1.0 * [#11](https://github.com/crypto-rb/ed25519/pull/11) ext/ed25519_java: switch to str4d/ed25519-java implementation (fixes #4) * [#9](https://github.com/crypto-rb/ed25519/pull/9) Implement Java backend as a proper JRuby extension * [#8](https://github.com/crypto-rb/ed25519/pull/8) Use an attr_accessor for Ed25519.provider ## [1.0.0] (2017-12-12) [1.0.0]: https://github.com/crypto-rb/ed25519/compare/v0.1.0...v1.0.0 * [#7](https://github.com/crypto-rb/ed25519/pull/7) Keypair refactor * [#6](https://github.com/crypto-rb/ed25519/pull/6) Switch from "ref" C implementation to SUPERCOP "ref10" * [#5](https://github.com/crypto-rb/ed25519/pull/5) Raise Ed25519::VerifyError if signature verification fails # 0.1.0 (2017-12-11) * Initial release ed25519-1.2.4/ed25519.gemspec0000644000004100000410000000225713260523700015113 0ustar www-datawww-data# frozen_string_literal: true require File.expand_path("lib/ed25519/version", __dir__) Gem::Specification.new do |spec| spec.name = "ed25519" spec.version = Ed25519::VERSION spec.authors = ["Tony Arcieri"] spec.email = ["tony.arcieri@gmail.com"] spec.summary = "An efficient digital signature library providing the Ed25519 algorithm" spec.description = <<-DESCRIPTION.strip.gsub(/\s+/, " ") A Ruby binding to the Ed25519 elliptic curve public-key signature system described in RFC 8032. DESCRIPTION spec.homepage = "https://github.com/crypto-rb/ed25519" spec.license = "MIT" spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } spec.bindir = "exe" spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } spec.require_paths = ["lib"] if defined? JRUBY_VERSION spec.platform = "java" spec.files << "lib/ed25519_jruby.jar" else spec.platform = Gem::Platform::RUBY spec.extensions = ["ext/ed25519_ref10/extconf.rb"] end spec.required_ruby_version = ">= 2.0.0" spec.add_development_dependency "bundler", "~> 1.16" end ed25519-1.2.4/ext/0000755000004100000410000000000013260523700013342 5ustar www-datawww-dataed25519-1.2.4/ext/ed25519_jruby/0000755000004100000410000000000013260523700015553 5ustar www-datawww-dataed25519-1.2.4/ext/ed25519_jruby/net/0000755000004100000410000000000013260523700016341 5ustar www-datawww-dataed25519-1.2.4/ext/ed25519_jruby/net/i2p/0000755000004100000410000000000013260523700017033 5ustar www-datawww-dataed25519-1.2.4/ext/ed25519_jruby/net/i2p/crypto/0000755000004100000410000000000013260523700020353 5ustar www-datawww-dataed25519-1.2.4/ext/ed25519_jruby/net/i2p/crypto/eddsa/0000755000004100000410000000000013260523700021433 5ustar www-datawww-dataed25519-1.2.4/ext/ed25519_jruby/net/i2p/crypto/eddsa/KeyFactory.java0000644000004100000410000000553413260523700024365 0ustar www-datawww-data/** * EdDSA-Java by str4d * * To the extent possible under law, the person who associated CC0 with * EdDSA-Java has waived all copyright and related or neighboring rights * to EdDSA-Java. * * You should have received a copy of the CC0 legalcode along with this * work. If not, see . * */ package net.i2p.crypto.eddsa; import java.security.InvalidKeyException; import java.security.Key; import java.security.KeyFactorySpi; import java.security.PrivateKey; import java.security.PublicKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import net.i2p.crypto.eddsa.spec.EdDSAPrivateKeySpec; import net.i2p.crypto.eddsa.spec.EdDSAPublicKeySpec; /** * @author str4d * */ public final class KeyFactory extends KeyFactorySpi { protected PrivateKey engineGeneratePrivate(KeySpec keySpec) throws InvalidKeySpecException { if (keySpec instanceof EdDSAPrivateKeySpec) { return new EdDSAPrivateKey((EdDSAPrivateKeySpec) keySpec); } if (keySpec instanceof PKCS8EncodedKeySpec) { return new EdDSAPrivateKey((PKCS8EncodedKeySpec) keySpec); } throw new InvalidKeySpecException("key spec not recognised: " + keySpec.getClass()); } protected PublicKey engineGeneratePublic(KeySpec keySpec) throws InvalidKeySpecException { if (keySpec instanceof EdDSAPublicKeySpec) { return new EdDSAPublicKey((EdDSAPublicKeySpec) keySpec); } if (keySpec instanceof X509EncodedKeySpec) { return new EdDSAPublicKey((X509EncodedKeySpec) keySpec); } throw new InvalidKeySpecException("key spec not recognised: " + keySpec.getClass()); } @SuppressWarnings("unchecked") protected T engineGetKeySpec(Key key, Class keySpec) throws InvalidKeySpecException { if (keySpec.isAssignableFrom(EdDSAPublicKeySpec.class) && key instanceof EdDSAPublicKey) { EdDSAPublicKey k = (EdDSAPublicKey) key; if (k.getParams() != null) { return (T) new EdDSAPublicKeySpec(k.getA(), k.getParams()); } } else if (keySpec.isAssignableFrom(EdDSAPrivateKeySpec.class) && key instanceof EdDSAPrivateKey) { EdDSAPrivateKey k = (EdDSAPrivateKey) key; if (k.getParams() != null) { return (T) new EdDSAPrivateKeySpec(k.getSeed(), k.getH(), k.geta(), k.getA(), k.getParams()); } } throw new InvalidKeySpecException("not implemented yet " + key + " " + keySpec); } protected Key engineTranslateKey(Key key) throws InvalidKeyException { throw new InvalidKeyException("No other EdDSA key providers known"); } } ed25519-1.2.4/ext/ed25519_jruby/net/i2p/crypto/eddsa/KeyPairGenerator.java0000644000004100000410000000730613260523700025517 0ustar www-datawww-data/** * EdDSA-Java by str4d * * To the extent possible under law, the person who associated CC0 with * EdDSA-Java has waived all copyright and related or neighboring rights * to EdDSA-Java. * * You should have received a copy of the CC0 legalcode along with this * work. If not, see . * */ package net.i2p.crypto.eddsa; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidParameterException; import java.security.KeyPair; import java.security.KeyPairGeneratorSpi; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import java.util.Hashtable; import net.i2p.crypto.eddsa.spec.EdDSAGenParameterSpec; import net.i2p.crypto.eddsa.spec.EdDSANamedCurveSpec; import net.i2p.crypto.eddsa.spec.EdDSANamedCurveTable; import net.i2p.crypto.eddsa.spec.EdDSAParameterSpec; import net.i2p.crypto.eddsa.spec.EdDSAPrivateKeySpec; import net.i2p.crypto.eddsa.spec.EdDSAPublicKeySpec; /** * Default keysize is 256 (Ed25519) */ public final class KeyPairGenerator extends KeyPairGeneratorSpi { private static final int DEFAULT_KEYSIZE = 256; private EdDSAParameterSpec edParams; private SecureRandom random; private boolean initialized; private static final Hashtable edParameters; static { edParameters = new Hashtable(); edParameters.put(Integer.valueOf(256), new EdDSAGenParameterSpec(EdDSANamedCurveTable.ED_25519)); } public void initialize(int keysize, SecureRandom random) { AlgorithmParameterSpec edParams = edParameters.get(Integer.valueOf(keysize)); if (edParams == null) throw new InvalidParameterException("unknown key type."); try { initialize(edParams, random); } catch (InvalidAlgorithmParameterException e) { throw new InvalidParameterException("key type not configurable."); } } @Override public void initialize(AlgorithmParameterSpec params, SecureRandom random) throws InvalidAlgorithmParameterException { if (params instanceof EdDSAParameterSpec) { edParams = (EdDSAParameterSpec) params; } else if (params instanceof EdDSAGenParameterSpec) { edParams = createNamedCurveSpec(((EdDSAGenParameterSpec) params).getName()); } else throw new InvalidAlgorithmParameterException("parameter object not a EdDSAParameterSpec"); this.random = random; initialized = true; } public KeyPair generateKeyPair() { if (!initialized) initialize(DEFAULT_KEYSIZE, new SecureRandom()); byte[] seed = new byte[edParams.getCurve().getField().getb()/8]; random.nextBytes(seed); EdDSAPrivateKeySpec privKey = new EdDSAPrivateKeySpec(seed, edParams); EdDSAPublicKeySpec pubKey = new EdDSAPublicKeySpec(privKey.getA(), edParams); return new KeyPair(new EdDSAPublicKey(pubKey), new EdDSAPrivateKey(privKey)); } /** * Create an EdDSANamedCurveSpec from the provided curve name. The current * implementation fetches the pre-created curve spec from a table. * @param curveName the EdDSA named curve. * @return the specification for the named curve. * @throws InvalidAlgorithmParameterException if the named curve is unknown. */ protected EdDSANamedCurveSpec createNamedCurveSpec(String curveName) throws InvalidAlgorithmParameterException { EdDSANamedCurveSpec spec = EdDSANamedCurveTable.getByName(curveName); if (spec == null) { throw new InvalidAlgorithmParameterException("unknown curve name: " + curveName); } return spec; } } ed25519-1.2.4/ext/ed25519_jruby/net/i2p/crypto/eddsa/Utils.java0000644000004100000410000000530213260523700023376 0ustar www-datawww-data/** * EdDSA-Java by str4d * * To the extent possible under law, the person who associated CC0 with * EdDSA-Java has waived all copyright and related or neighboring rights * to EdDSA-Java. * * You should have received a copy of the CC0 legalcode along with this * work. If not, see . * */ package net.i2p.crypto.eddsa; /** * Basic utilities for EdDSA. * Not for external use, not maintained as a public API. * * @author str4d * */ public class Utils { /** * Constant-time byte comparison. * @param b a byte * @param c a byte * @return 1 if b and c are equal, 0 otherwise. */ public static int equal(int b, int c) { int result = 0; int xor = b ^ c; for (int i = 0; i < 8; i++) { result |= xor >> i; } return (result ^ 0x01) & 0x01; } /** * Constant-time byte[] comparison. * @param b a byte[] * @param c a byte[] * @return 1 if b and c are equal, 0 otherwise. */ public static int equal(byte[] b, byte[] c) { int result = 0; for (int i = 0; i < 32; i++) { result |= b[i] ^ c[i]; } return equal(result, 0); } /** * Constant-time determine if byte is negative. * @param b the byte to check. * @return 1 if the byte is negative, 0 otherwise. */ public static int negative(int b) { return (b >> 8) & 1; } /** * Get the i'th bit of a byte array. * @param h the byte array. * @param i the bit index. * @return 0 or 1, the value of the i'th bit in h */ public static int bit(byte[] h, int i) { return (h[i >> 3] >> (i & 7)) & 1; } /** * Converts a hex string to bytes. * @param s the hex string to be converted. * @return the byte[] */ public static byte[] hexToBytes(String s) { int len = s.length(); byte[] data = new byte[len / 2]; for (int i = 0; i < len; i += 2) { data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i+1), 16)); } return data; } /** * Converts bytes to a hex string. * @param raw the byte[] to be converted. * @return the hex representation as a string. */ public static String bytesToHex(byte[] raw) { if ( raw == null ) { return null; } final StringBuilder hex = new StringBuilder(2 * raw.length); for (final byte b : raw) { hex.append(Character.forDigit((b & 0xF0) >> 4, 16)) .append(Character.forDigit((b & 0x0F), 16)); } return hex.toString(); } } ed25519-1.2.4/ext/ed25519_jruby/net/i2p/crypto/eddsa/spec/0000755000004100000410000000000013260523700022365 5ustar www-datawww-dataed25519-1.2.4/ext/ed25519_jruby/net/i2p/crypto/eddsa/spec/EdDSANamedCurveSpec.java0000644000004100000410000000167413260523700026705 0ustar www-datawww-data/** * EdDSA-Java by str4d * * To the extent possible under law, the person who associated CC0 with * EdDSA-Java has waived all copyright and related or neighboring rights * to EdDSA-Java. * * You should have received a copy of the CC0 legalcode along with this * work. If not, see . * */ package net.i2p.crypto.eddsa.spec; import net.i2p.crypto.eddsa.math.Curve; import net.i2p.crypto.eddsa.math.GroupElement; import net.i2p.crypto.eddsa.math.ScalarOps; /** * EdDSA Curve specification that can also be referred to by name. * @author str4d * */ public class EdDSANamedCurveSpec extends EdDSAParameterSpec { private final String name; public EdDSANamedCurveSpec(String name, Curve curve, String hashAlgo, ScalarOps sc, GroupElement B) { super(curve, hashAlgo, sc, B); this.name = name; } public String getName() { return name; } } ed25519-1.2.4/ext/ed25519_jruby/net/i2p/crypto/eddsa/spec/EdDSANamedCurveTable.java0000644000004100000410000000477513260523700027047 0ustar www-datawww-data/** * EdDSA-Java by str4d * * To the extent possible under law, the person who associated CC0 with * EdDSA-Java has waived all copyright and related or neighboring rights * to EdDSA-Java. * * You should have received a copy of the CC0 legalcode along with this * work. If not, see . * */ package net.i2p.crypto.eddsa.spec; import java.util.Hashtable; import java.util.Locale; import net.i2p.crypto.eddsa.Utils; import net.i2p.crypto.eddsa.math.Curve; import net.i2p.crypto.eddsa.math.Field; import net.i2p.crypto.eddsa.math.ed25519.Ed25519LittleEndianEncoding; import net.i2p.crypto.eddsa.math.ed25519.Ed25519ScalarOps; /** * The named EdDSA curves. * @author str4d * */ public class EdDSANamedCurveTable { public static final String ED_25519 = "Ed25519"; private static final Field ed25519field = new Field( 256, // b Utils.hexToBytes("edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f"), // q new Ed25519LittleEndianEncoding()); private static final Curve ed25519curve = new Curve(ed25519field, Utils.hexToBytes("a3785913ca4deb75abd841414d0a700098e879777940c78c73fe6f2bee6c0352"), // d ed25519field.fromByteArray(Utils.hexToBytes("b0a00e4a271beec478e42fad0618432fa7d7fb3d99004d2b0bdfc14f8024832b"))); // I private static final EdDSANamedCurveSpec ed25519 = new EdDSANamedCurveSpec( ED_25519, ed25519curve, "SHA-512", // H new Ed25519ScalarOps(), // l ed25519curve.createPoint( // B Utils.hexToBytes("5866666666666666666666666666666666666666666666666666666666666666"), true)); // Precompute tables for B private static final Hashtable curves = new Hashtable(); public static void defineCurve(EdDSANamedCurveSpec curve) { curves.put(curve.getName().toLowerCase(Locale.ENGLISH), curve); } static void defineCurveAlias(String name, String alias) { EdDSANamedCurveSpec curve = curves.get(name.toLowerCase(Locale.ENGLISH)); if (curve == null) { throw new IllegalStateException(); } curves.put(alias.toLowerCase(Locale.ENGLISH), curve); } static { // RFC 8032 defineCurve(ed25519); } public static EdDSANamedCurveSpec getByName(String name) { return curves.get(name.toLowerCase(Locale.ENGLISH)); } } ed25519-1.2.4/ext/ed25519_jruby/net/i2p/crypto/eddsa/spec/EdDSAGenParameterSpec.java0000644000004100000410000000145613260523700027224 0ustar www-datawww-data/** * EdDSA-Java by str4d * * To the extent possible under law, the person who associated CC0 with * EdDSA-Java has waived all copyright and related or neighboring rights * to EdDSA-Java. * * You should have received a copy of the CC0 legalcode along with this * work. If not, see . * */ package net.i2p.crypto.eddsa.spec; import java.security.spec.AlgorithmParameterSpec; /** * Implementation of AlgorithmParameterSpec that holds the name of a named * EdDSA curve specification. * @author str4d * */ public class EdDSAGenParameterSpec implements AlgorithmParameterSpec { private final String name; public EdDSAGenParameterSpec(String stdName) { name = stdName; } public String getName() { return name; } } ed25519-1.2.4/ext/ed25519_jruby/net/i2p/crypto/eddsa/spec/EdDSAPrivateKeySpec.java0000644000004100000410000000715613260523700026740 0ustar www-datawww-data/** * EdDSA-Java by str4d * * To the extent possible under law, the person who associated CC0 with * EdDSA-Java has waived all copyright and related or neighboring rights * to EdDSA-Java. * * You should have received a copy of the CC0 legalcode along with this * work. If not, see . * */ package net.i2p.crypto.eddsa.spec; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.spec.KeySpec; import java.util.Arrays; import net.i2p.crypto.eddsa.math.GroupElement; /** * @author str4d * */ public class EdDSAPrivateKeySpec implements KeySpec { private final byte[] seed; private final byte[] h; private final byte[] a; private final GroupElement A; private final EdDSAParameterSpec spec; /** * @param seed the private key * @param spec the parameter specification for this key * @throws IllegalArgumentException if seed length is wrong or hash algorithm is unsupported */ public EdDSAPrivateKeySpec(byte[] seed, EdDSAParameterSpec spec) { if (seed.length != spec.getCurve().getField().getb()/8) throw new IllegalArgumentException("seed length is wrong"); this.spec = spec; this.seed = seed; try { MessageDigest hash = MessageDigest.getInstance(spec.getHashAlgorithm()); int b = spec.getCurve().getField().getb(); // H(k) h = hash.digest(seed); /*a = BigInteger.valueOf(2).pow(b-2); for (int i=3;i<(b-2);i++) { a = a.add(BigInteger.valueOf(2).pow(i).multiply(BigInteger.valueOf(Utils.bit(h,i)))); }*/ // Saves ~0.4ms per key when running signing tests. // TODO: are these bitflips the same for any hash function? h[0] &= 248; h[(b/8)-1] &= 63; h[(b/8)-1] |= 64; a = Arrays.copyOfRange(h, 0, b/8); A = spec.getB().scalarMultiply(a); } catch (NoSuchAlgorithmException e) { throw new IllegalArgumentException("Unsupported hash algorithm"); } } /** * Initialize directly from the hash. * getSeed() will return null if this constructor is used. * * @param spec the parameter specification for this key * @param h the private key * @throws IllegalArgumentException if hash length is wrong * @since 0.1.1 */ public EdDSAPrivateKeySpec(EdDSAParameterSpec spec, byte[] h) { if (h.length != spec.getCurve().getField().getb()/4) throw new IllegalArgumentException("hash length is wrong"); this.seed = null; this.h = h; this.spec = spec; int b = spec.getCurve().getField().getb(); h[0] &= 248; h[(b/8)-1] &= 63; h[(b/8)-1] |= 64; a = Arrays.copyOfRange(h, 0, b/8); A = spec.getB().scalarMultiply(a); } public EdDSAPrivateKeySpec(byte[] seed, byte[] h, byte[] a, GroupElement A, EdDSAParameterSpec spec) { this.seed = seed; this.h = h; this.a = a; this.A = A; this.spec = spec; } /** * @return will be null if constructed directly from the private key */ public byte[] getSeed() { return seed; } /** * @return the hash */ public byte[] getH() { return h; } /** * @return the private key */ public byte[] geta() { return a; } /** * @return the public key */ public GroupElement getA() { return A; } public EdDSAParameterSpec getParams() { return spec; } } ed25519-1.2.4/ext/ed25519_jruby/net/i2p/crypto/eddsa/spec/EdDSAParameterSpec.java0000644000004100000410000000536713260523700026577 0ustar www-datawww-data/** * EdDSA-Java by str4d * * To the extent possible under law, the person who associated CC0 with * EdDSA-Java has waived all copyright and related or neighboring rights * to EdDSA-Java. * * You should have received a copy of the CC0 legalcode along with this * work. If not, see . * */ package net.i2p.crypto.eddsa.spec; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.spec.AlgorithmParameterSpec; import net.i2p.crypto.eddsa.math.Curve; import net.i2p.crypto.eddsa.math.GroupElement; import net.i2p.crypto.eddsa.math.ScalarOps; import java.io.Serializable; /** * Parameter specification for an EdDSA algorithm. * @author str4d * */ public class EdDSAParameterSpec implements AlgorithmParameterSpec, Serializable { private static final long serialVersionUID = 8274987108472012L; private final Curve curve; private final String hashAlgo; private final ScalarOps sc; private final GroupElement B; /** * @param curve the curve * @param hashAlgo the JCA string for the hash algorithm * @param sc the parameter L represented as ScalarOps * @param B the parameter B * @throws IllegalArgumentException if hash algorithm is unsupported or length is wrong */ public EdDSAParameterSpec(Curve curve, String hashAlgo, ScalarOps sc, GroupElement B) { try { MessageDigest hash = MessageDigest.getInstance(hashAlgo); // EdDSA hash function must produce 2b-bit output if (curve.getField().getb()/4 != hash.getDigestLength()) throw new IllegalArgumentException("Hash output is not 2b-bit"); } catch (NoSuchAlgorithmException e) { throw new IllegalArgumentException("Unsupported hash algorithm"); } this.curve = curve; this.hashAlgo = hashAlgo; this.sc = sc; this.B = B; } public Curve getCurve() { return curve; } public String getHashAlgorithm() { return hashAlgo; } public ScalarOps getScalarOps() { return sc; } /** * @return the base (generator) */ public GroupElement getB() { return B; } @Override public int hashCode() { return hashAlgo.hashCode() ^ curve.hashCode() ^ B.hashCode(); } @Override public boolean equals(Object o) { if (o == this) return true; if (!(o instanceof EdDSAParameterSpec)) return false; EdDSAParameterSpec s = (EdDSAParameterSpec) o; return hashAlgo.equals(s.getHashAlgorithm()) && curve.equals(s.getCurve()) && B.equals(s.getB()); } } ed25519-1.2.4/ext/ed25519_jruby/net/i2p/crypto/eddsa/spec/EdDSAPublicKeySpec.java0000644000004100000410000000314713260523700026540 0ustar www-datawww-data/** * EdDSA-Java by str4d * * To the extent possible under law, the person who associated CC0 with * EdDSA-Java has waived all copyright and related or neighboring rights * to EdDSA-Java. * * You should have received a copy of the CC0 legalcode along with this * work. If not, see . * */ package net.i2p.crypto.eddsa.spec; import java.security.spec.KeySpec; import net.i2p.crypto.eddsa.math.GroupElement; /** * @author str4d * */ public class EdDSAPublicKeySpec implements KeySpec { private final GroupElement A; private final GroupElement Aneg; private final EdDSAParameterSpec spec; /** * @param pk the public key * @param spec the parameter specification for this key * @throws IllegalArgumentException if key length is wrong */ public EdDSAPublicKeySpec(byte[] pk, EdDSAParameterSpec spec) { if (pk.length != spec.getCurve().getField().getb()/8) throw new IllegalArgumentException("public-key length is wrong"); this.A = new GroupElement(spec.getCurve(), pk); // Precompute -A for use in verification. this.Aneg = A.negate(); Aneg.precompute(false); this.spec = spec; } public EdDSAPublicKeySpec(GroupElement A, EdDSAParameterSpec spec) { this.A = A; this.Aneg = A.negate(); Aneg.precompute(false); this.spec = spec; } public GroupElement getA() { return A; } public GroupElement getNegativeA() { return Aneg; } public EdDSAParameterSpec getParams() { return spec; } } ed25519-1.2.4/ext/ed25519_jruby/net/i2p/crypto/eddsa/EdDSAKey.java0000644000004100000410000000143613260523700023633 0ustar www-datawww-data/** * EdDSA-Java by str4d * * To the extent possible under law, the person who associated CC0 with * EdDSA-Java has waived all copyright and related or neighboring rights * to EdDSA-Java. * * You should have received a copy of the CC0 legalcode along with this * work. If not, see . * */ package net.i2p.crypto.eddsa; import net.i2p.crypto.eddsa.spec.EdDSAParameterSpec; /** * Common interface for all EdDSA keys. * @author str4d */ public interface EdDSAKey { /** * The reported key algorithm for all EdDSA keys */ String KEY_ALGORITHM = "EdDSA"; /** * @return a parameter specification representing the EdDSA domain * parameters for the key. */ EdDSAParameterSpec getParams(); } ed25519-1.2.4/ext/ed25519_jruby/net/i2p/crypto/eddsa/EdDSAEngine.java0000644000004100000410000004177413260523700024321 0ustar www-datawww-data/** * EdDSA-Java by str4d * * To the extent possible under law, the person who associated CC0 with * EdDSA-Java has waived all copyright and related or neighboring rights * to EdDSA-Java. * * You should have received a copy of the CC0 legalcode along with this * work. If not, see . * */ package net.i2p.crypto.eddsa; import java.io.ByteArrayOutputStream; import java.nio.ByteBuffer; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; import java.security.SignatureException; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.InvalidKeySpecException; import java.security.spec.X509EncodedKeySpec; import java.util.Arrays; import net.i2p.crypto.eddsa.math.Curve; import net.i2p.crypto.eddsa.math.GroupElement; import net.i2p.crypto.eddsa.math.ScalarOps; import sun.security.x509.X509Key; /** * Signing and verification for EdDSA. *

* The EdDSA sign and verify algorithms do not interact well with * the Java Signature API, as one or more update() methods must be * called before sign() or verify(). Using the standard API, * this implementation must copy and buffer all data passed in * via update(). *

* This implementation offers two ways to avoid this copying, * but only if all data to be signed or verified is available * in a single byte array. *

*Option 1: *

    *
  1. Call initSign() or initVerify() as usual. *
  2. Call setParameter(ONE_SHOT_MODE) *
  3. Call update(byte[]) or update(byte[], int, int) exactly once *
  4. Call sign() or verify() as usual. *
  5. If doing additional one-shot signs or verifies with this object, you must * call setParameter(ONE_SHOT_MODE) each time *
* *

*Option 2: *

    *
  1. Call initSign() or initVerify() as usual. *
  2. Call one of the signOneShot() or verifyOneShot() methods. *
  3. If doing additional one-shot signs or verifies with this object, * just call signOneShot() or verifyOneShot() again. *
* * @author str4d * */ public final class EdDSAEngine extends Signature { public static final String SIGNATURE_ALGORITHM = "NONEwithEdDSA"; private MessageDigest digest; private ByteArrayOutputStream baos; private EdDSAKey key; private boolean oneShotMode; private byte[] oneShotBytes; private int oneShotOffset; private int oneShotLength; /** * To efficiently sign or verify data in one shot, pass this to setParameters() * after initSign() or initVerify() but BEFORE THE FIRST AND ONLY * update(data) or update(data, off, len). The data reference will be saved * and then used in sign() or verify() without copying the data. * Violate these rules and you will get a SignatureException. */ public static final AlgorithmParameterSpec ONE_SHOT_MODE = new OneShotSpec(); private static class OneShotSpec implements AlgorithmParameterSpec {} /** * No specific EdDSA-internal hash requested, allows any EdDSA key. */ public EdDSAEngine() { super(SIGNATURE_ALGORITHM); } /** * Specific EdDSA-internal hash requested, only matching keys will be allowed. * @param digest the hash algorithm that keys must have to sign or verify. */ public EdDSAEngine(MessageDigest digest) { this(); this.digest = digest; } private void reset() { if (digest != null) digest.reset(); if (baos != null) baos.reset(); oneShotMode = false; oneShotBytes = null; } @Override protected void engineInitSign(PrivateKey privateKey) throws InvalidKeyException { reset(); if (privateKey instanceof EdDSAPrivateKey) { EdDSAPrivateKey privKey = (EdDSAPrivateKey) privateKey; key = privKey; if (digest == null) { // Instantiate the digest from the key parameters try { digest = MessageDigest.getInstance(key.getParams().getHashAlgorithm()); } catch (NoSuchAlgorithmException e) { throw new InvalidKeyException("cannot get required digest " + key.getParams().getHashAlgorithm() + " for private key."); } } else if (!key.getParams().getHashAlgorithm().equals(digest.getAlgorithm())) throw new InvalidKeyException("Key hash algorithm does not match chosen digest"); digestInitSign(privKey); } else { throw new InvalidKeyException("cannot identify EdDSA private key: " + privateKey.getClass()); } } private void digestInitSign(EdDSAPrivateKey privKey) { // Preparing for hash // r = H(h_b,...,h_2b-1,M) int b = privKey.getParams().getCurve().getField().getb(); digest.update(privKey.getH(), b/8, b/4 - b/8); } @Override protected void engineInitVerify(PublicKey publicKey) throws InvalidKeyException { reset(); if (publicKey instanceof EdDSAPublicKey) { key = (EdDSAPublicKey) publicKey; if (digest == null) { // Instantiate the digest from the key parameters try { digest = MessageDigest.getInstance(key.getParams().getHashAlgorithm()); } catch (NoSuchAlgorithmException e) { throw new InvalidKeyException("cannot get required digest " + key.getParams().getHashAlgorithm() + " for private key."); } } else if (!key.getParams().getHashAlgorithm().equals(digest.getAlgorithm())) throw new InvalidKeyException("Key hash algorithm does not match chosen digest"); } else if (publicKey instanceof X509Key) { // X509Certificate will sometimes contain an X509Key rather than the EdDSAPublicKey itself; the contained // key is valid but needs to be instanced as an EdDSAPublicKey before it can be used. EdDSAPublicKey parsedPublicKey; try { parsedPublicKey = new EdDSAPublicKey(new X509EncodedKeySpec(publicKey.getEncoded())); } catch (InvalidKeySpecException ex) { throw new InvalidKeyException("cannot handle X.509 EdDSA public key: " + publicKey.getAlgorithm()); } engineInitVerify(parsedPublicKey); } else { throw new InvalidKeyException("cannot identify EdDSA public key: " + publicKey.getClass()); } } /** * @throws SignatureException if in one-shot mode */ @Override protected void engineUpdate(byte b) throws SignatureException { if (oneShotMode) throw new SignatureException("unsupported in one-shot mode"); if (baos == null) baos = new ByteArrayOutputStream(256); baos.write(b); } /** * @throws SignatureException if one-shot rules are violated */ @Override protected void engineUpdate(byte[] b, int off, int len) throws SignatureException { if (oneShotMode) { if (oneShotBytes != null) throw new SignatureException("update() already called"); oneShotBytes = b; oneShotOffset = off; oneShotLength = len; } else { if (baos == null) baos = new ByteArrayOutputStream(256); baos.write(b, off, len); } } @Override protected byte[] engineSign() throws SignatureException { try { return x_engineSign(); } finally { reset(); // must leave the object ready to sign again with // the same key, as required by the API EdDSAPrivateKey privKey = (EdDSAPrivateKey) key; digestInitSign(privKey); } } private byte[] x_engineSign() throws SignatureException { Curve curve = key.getParams().getCurve(); ScalarOps sc = key.getParams().getScalarOps(); byte[] a = ((EdDSAPrivateKey) key).geta(); byte[] message; int offset, length; if (oneShotMode) { if (oneShotBytes == null) throw new SignatureException("update() not called first"); message = oneShotBytes; offset = oneShotOffset; length = oneShotLength; } else { if (baos == null) message = new byte[0]; else message = baos.toByteArray(); offset = 0; length = message.length; } // r = H(h_b,...,h_2b-1,M) digest.update(message, offset, length); byte[] r = digest.digest(); // r mod l // Reduces r from 64 bytes to 32 bytes r = sc.reduce(r); // R = rB GroupElement R = key.getParams().getB().scalarMultiply(r); byte[] Rbyte = R.toByteArray(); // S = (r + H(Rbar,Abar,M)*a) mod l digest.update(Rbyte); digest.update(((EdDSAPrivateKey) key).getAbyte()); digest.update(message, offset, length); byte[] h = digest.digest(); h = sc.reduce(h); byte[] S = sc.multiplyAndAdd(h, a, r); // R+S int b = curve.getField().getb(); ByteBuffer out = ByteBuffer.allocate(b/4); out.put(Rbyte).put(S); return out.array(); } @Override protected boolean engineVerify(byte[] sigBytes) throws SignatureException { try { return x_engineVerify(sigBytes); } finally { reset(); } } private boolean x_engineVerify(byte[] sigBytes) throws SignatureException { Curve curve = key.getParams().getCurve(); int b = curve.getField().getb(); if (sigBytes.length != b/4) throw new SignatureException("signature length is wrong"); // R is first b/8 bytes of sigBytes, S is second b/8 bytes digest.update(sigBytes, 0, b/8); digest.update(((EdDSAPublicKey) key).getAbyte()); // h = H(Rbar,Abar,M) byte[] message; int offset, length; if (oneShotMode) { if (oneShotBytes == null) throw new SignatureException("update() not called first"); message = oneShotBytes; offset = oneShotOffset; length = oneShotLength; } else { if (baos == null) message = new byte[0]; else message = baos.toByteArray(); offset = 0; length = message.length; } digest.update(message, offset, length); byte[] h = digest.digest(); // h mod l h = key.getParams().getScalarOps().reduce(h); byte[] Sbyte = Arrays.copyOfRange(sigBytes, b/8, b/4); // R = SB - H(Rbar,Abar,M)A GroupElement R = key.getParams().getB().doubleScalarMultiplyVariableTime( ((EdDSAPublicKey) key).getNegativeA(), h, Sbyte); // Variable time. This should be okay, because there are no secret // values used anywhere in verification. byte[] Rcalc = R.toByteArray(); for (int i = 0; i < Rcalc.length; i++) { if (Rcalc[i] != sigBytes[i]) return false; } return true; } /** * To efficiently sign all the data in one shot, if it is available, * use this method, which will avoid copying the data. * * Same as: *
     *  setParameter(ONE_SHOT_MODE)
     *  update(data)
     *  sig = sign()
     *
* * @param data the message to be signed * @return the signature * @throws SignatureException if update() already called * @see #ONE_SHOT_MODE */ public byte[] signOneShot(byte[] data) throws SignatureException { return signOneShot(data, 0, data.length); } /** * To efficiently sign all the data in one shot, if it is available, * use this method, which will avoid copying the data. * * Same as: *
     *  setParameter(ONE_SHOT_MODE)
     *  update(data, off, len)
     *  sig = sign()
     *
* * @param data byte array containing the message to be signed * @param off the start of the message inside data * @param len the length of the message * @return the signature * @throws SignatureException if update() already called * @see #ONE_SHOT_MODE */ public byte[] signOneShot(byte[] data, int off, int len) throws SignatureException { oneShotMode = true; update(data, off, len); return sign(); } /** * To efficiently verify all the data in one shot, if it is available, * use this method, which will avoid copying the data. * * Same as: *
     *  setParameter(ONE_SHOT_MODE)
     *  update(data)
     *  ok = verify(signature)
     *
* * @param data the message that was signed * @param signature of the message * @return true if the signature is valid, false otherwise * @throws SignatureException if update() already called * @see #ONE_SHOT_MODE */ public boolean verifyOneShot(byte[] data, byte[] signature) throws SignatureException { return verifyOneShot(data, 0, data.length, signature, 0, signature.length); } /** * To efficiently verify all the data in one shot, if it is available, * use this method, which will avoid copying the data. * * Same as: *
     *  setParameter(ONE_SHOT_MODE)
     *  update(data, off, len)
     *  ok = verify(signature)
     *
* * @param data byte array containing the message that was signed * @param off the start of the message inside data * @param len the length of the message * @param signature of the message * @return true if the signature is valid, false otherwise * @throws SignatureException if update() already called * @see #ONE_SHOT_MODE */ public boolean verifyOneShot(byte[] data, int off, int len, byte[] signature) throws SignatureException { return verifyOneShot(data, off, len, signature, 0, signature.length); } /** * To efficiently verify all the data in one shot, if it is available, * use this method, which will avoid copying the data. * * Same as: *
     *  setParameter(ONE_SHOT_MODE)
     *  update(data)
     *  ok = verify(signature, sigoff, siglen)
     *
* * @param data the message that was signed * @param signature byte array containing the signature * @param sigoff the start of the signature * @param siglen the length of the signature * @return true if the signature is valid, false otherwise * @throws SignatureException if update() already called * @see #ONE_SHOT_MODE */ public boolean verifyOneShot(byte[] data, byte[] signature, int sigoff, int siglen) throws SignatureException { return verifyOneShot(data, 0, data.length, signature, sigoff, siglen); } /** * To efficiently verify all the data in one shot, if it is available, * use this method, which will avoid copying the data. * * Same as: *
     *  setParameter(ONE_SHOT_MODE)
     *  update(data, off, len)
     *  ok = verify(signature, sigoff, siglen)
     *
* * @param data byte array containing the message that was signed * @param off the start of the message inside data * @param len the length of the message * @param signature byte array containing the signature * @param sigoff the start of the signature * @param siglen the length of the signature * @return true if the signature is valid, false otherwise * @throws SignatureException if update() already called * @see #ONE_SHOT_MODE */ public boolean verifyOneShot(byte[] data, int off, int len, byte[] signature, int sigoff, int siglen) throws SignatureException { oneShotMode = true; update(data, off, len); return verify(signature, sigoff, siglen); } /** * @throws InvalidAlgorithmParameterException if spec is ONE_SHOT_MODE and update() already called * @see #ONE_SHOT_MODE */ @Override protected void engineSetParameter(AlgorithmParameterSpec spec) throws InvalidAlgorithmParameterException { if (spec.equals(ONE_SHOT_MODE)) { if (oneShotBytes != null || (baos != null && baos.size() > 0)) throw new InvalidAlgorithmParameterException("update() already called"); oneShotMode = true; } else { super.engineSetParameter(spec); } } /** * @deprecated */ @Override protected void engineSetParameter(String param, Object value) { throw new UnsupportedOperationException("engineSetParameter unsupported"); } /** * @deprecated */ @Override protected Object engineGetParameter(String param) { throw new UnsupportedOperationException("engineSetParameter unsupported"); } } ed25519-1.2.4/ext/ed25519_jruby/net/i2p/crypto/eddsa/EdDSAPublicKey.java0000644000004100000410000002145013260523700024770 0ustar www-datawww-data/** * EdDSA-Java by str4d * * To the extent possible under law, the person who associated CC0 with * EdDSA-Java has waived all copyright and related or neighboring rights * to EdDSA-Java. * * You should have received a copy of the CC0 legalcode along with this * work. If not, see . * */ package net.i2p.crypto.eddsa; import java.security.PublicKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.X509EncodedKeySpec; import java.util.Arrays; import net.i2p.crypto.eddsa.math.GroupElement; import net.i2p.crypto.eddsa.spec.EdDSANamedCurveTable; import net.i2p.crypto.eddsa.spec.EdDSAParameterSpec; import net.i2p.crypto.eddsa.spec.EdDSAPublicKeySpec; /** * An EdDSA public key. *

* Warning: Public key encoding is is based on the current curdle WG draft, * and is subject to change. See getEncoded(). *

* For compatibility with older releases, decoding supports both the old and new * draft specifications. See decode(). *

* Ref: https://tools.ietf.org/html/draft-ietf-curdle-pkix-04 *

* Old Ref: https://tools.ietf.org/html/draft-josefsson-pkix-eddsa-04 *

* @author str4d * */ public class EdDSAPublicKey implements EdDSAKey, PublicKey { private static final long serialVersionUID = 9837459837498475L; private final GroupElement A; private final GroupElement Aneg; private final byte[] Abyte; private final EdDSAParameterSpec edDsaSpec; // OID 1.3.101.xxx private static final int OID_OLD = 100; private static final int OID_ED25519 = 112; private static final int OID_BYTE = 8; private static final int IDLEN_BYTE = 3; public EdDSAPublicKey(EdDSAPublicKeySpec spec) { this.A = spec.getA(); this.Aneg = spec.getNegativeA(); this.Abyte = this.A.toByteArray(); this.edDsaSpec = spec.getParams(); } public EdDSAPublicKey(X509EncodedKeySpec spec) throws InvalidKeySpecException { this(new EdDSAPublicKeySpec(decode(spec.getEncoded()), EdDSANamedCurveTable.getByName(EdDSANamedCurveTable.ED_25519))); } @Override public String getAlgorithm() { return KEY_ALGORITHM; } @Override public String getFormat() { return "X.509"; } /** * Returns the public key in its canonical encoding. *

* This implements the following specs: *

  • * General encoding: https://tools.ietf.org/html/draft-ietf-curdle-pkix-04 *
  • * Key encoding: https://tools.ietf.org/html/rfc8032 *
*

* For keys in older formats, decoding and then re-encoding is sufficient to * migrate them to the canonical encoding. *

* Relevant spec quotes: *
     *  In the X.509 certificate, the subjectPublicKeyInfo field has the
     *  SubjectPublicKeyInfo type, which has the following ASN.1 syntax:
     *
     *  SubjectPublicKeyInfo  ::=  SEQUENCE  {
     *    algorithm         AlgorithmIdentifier,
     *    subjectPublicKey  BIT STRING
     *  }
     *
* *
     *  AlgorithmIdentifier  ::=  SEQUENCE  {
     *    algorithm   OBJECT IDENTIFIER,
     *    parameters  ANY DEFINED BY algorithm OPTIONAL
     *  }
     *
     *  For all of the OIDs, the parameters MUST be absent.
     *
* *
     *  id-Ed25519   OBJECT IDENTIFIER ::= { 1 3 101 112 }
     *
* * @return 44 bytes for Ed25519, null for other curves */ @Override public byte[] getEncoded() { if (!edDsaSpec.equals(EdDSANamedCurveTable.getByName(EdDSANamedCurveTable.ED_25519))) return null; int totlen = 12 + Abyte.length; byte[] rv = new byte[totlen]; int idx = 0; // sequence rv[idx++] = 0x30; rv[idx++] = (byte) (totlen - 2); // Algorithm Identifier // sequence rv[idx++] = 0x30; rv[idx++] = 5; // OID // https://msdn.microsoft.com/en-us/library/windows/desktop/bb540809%28v=vs.85%29.aspx rv[idx++] = 0x06; rv[idx++] = 3; rv[idx++] = (1 * 40) + 3; rv[idx++] = 101; rv[idx++] = (byte) OID_ED25519; // params - absent // the key rv[idx++] = 0x03; // bit string rv[idx++] = (byte) (1 + Abyte.length); rv[idx++] = 0; // number of trailing unused bits System.arraycopy(Abyte, 0, rv, idx, Abyte.length); return rv; } /** * Extracts the public key bytes from the provided encoding. *

* This will decode data conforming to the current spec at * https://tools.ietf.org/html/draft-ietf-curdle-pkix-04 * or the old spec at * https://tools.ietf.org/html/draft-josefsson-pkix-eddsa-04. *

* Contrary to draft-ietf-curdle-pkix-04, it WILL accept a parameter value * of NULL, as it is required for interoperability with the default Java * keystore. Other implementations MUST NOT copy this behaviour from here * unless they also need to read keys from the default Java keystore. *

* This is really dumb for now. It does not use a general-purpose ASN.1 decoder. * See also getEncoded(). *

* * @return 32 bytes for Ed25519, throws for other curves */ private static byte[] decode(byte[] d) throws InvalidKeySpecException { try { // // Setup and OID check // int totlen = 44; int idlen = 5; int doid = d[OID_BYTE]; if (doid == OID_OLD) { totlen = 47; idlen = 8; } else if (doid == OID_ED25519) { // Detect parameter value of NULL if (d[IDLEN_BYTE] == 7) { totlen = 46; idlen = 7; } } else { throw new InvalidKeySpecException("unsupported key spec"); } // // Pre-decoding check // if (d.length != totlen) { throw new InvalidKeySpecException("invalid key spec length"); } // // Decoding // int idx = 0; if (d[idx++] != 0x30 || d[idx++] != (totlen - 2) || d[idx++] != 0x30 || d[idx++] != idlen || d[idx++] != 0x06 || d[idx++] != 3 || d[idx++] != (1 * 40) + 3 || d[idx++] != 101) { throw new InvalidKeySpecException("unsupported key spec"); } idx++; // OID, checked above // parameters only with old OID if (doid == OID_OLD) { if (d[idx++] != 0x0a || d[idx++] != 1 || d[idx++] != 1) { throw new InvalidKeySpecException("unsupported key spec"); } } else { // Handle parameter value of NULL // // Quote https://tools.ietf.org/html/draft-ietf-curdle-pkix-04 : // For all of the OIDs, the parameters MUST be absent. // Regardless of the defect in the original 1997 syntax, // implementations MUST NOT accept a parameters value of NULL. // // But Java's default keystore puts it in (when decoding as // PKCS8 and then re-encoding to pass on), so we must accept it. if (idlen == 7) { if (d[idx++] != 0x05 || d[idx++] != 0) { throw new InvalidKeySpecException("unsupported key spec"); } } } if (d[idx++] != 0x03 || d[idx++] != 33 || d[idx++] != 0) { throw new InvalidKeySpecException("unsupported key spec"); } byte[] rv = new byte[32]; System.arraycopy(d, idx, rv, 0, 32); return rv; } catch (IndexOutOfBoundsException ioobe) { throw new InvalidKeySpecException(ioobe); } } @Override public EdDSAParameterSpec getParams() { return edDsaSpec; } public GroupElement getA() { return A; } public GroupElement getNegativeA() { return Aneg; } public byte[] getAbyte() { return Abyte; } @Override public int hashCode() { return Arrays.hashCode(Abyte); } @Override public boolean equals(Object o) { if (o == this) return true; if (!(o instanceof EdDSAPublicKey)) return false; EdDSAPublicKey pk = (EdDSAPublicKey) o; return Arrays.equals(Abyte, pk.getAbyte()) && edDsaSpec.equals(pk.getParams()); } } ed25519-1.2.4/ext/ed25519_jruby/net/i2p/crypto/eddsa/EdDSAPrivateKey.java0000644000004100000410000002475513260523700025177 0ustar www-datawww-data/** * EdDSA-Java by str4d * * To the extent possible under law, the person who associated CC0 with * EdDSA-Java has waived all copyright and related or neighboring rights * to EdDSA-Java. * * You should have received a copy of the CC0 legalcode along with this * work. If not, see . * */ package net.i2p.crypto.eddsa; import java.security.PrivateKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.util.Arrays; import net.i2p.crypto.eddsa.math.GroupElement; import net.i2p.crypto.eddsa.spec.EdDSANamedCurveTable; import net.i2p.crypto.eddsa.spec.EdDSAParameterSpec; import net.i2p.crypto.eddsa.spec.EdDSAPrivateKeySpec; /** * An EdDSA private key. *

* Warning: Private key encoding is based on the current curdle WG draft, * and is subject to change. See getEncoded(). *

* For compatibility with older releases, decoding supports both the old and new * draft specifications. See decode(). *

* Ref: https://tools.ietf.org/html/draft-ietf-curdle-pkix-04 *

* Old Ref: https://tools.ietf.org/html/draft-josefsson-pkix-eddsa-04 *

* @author str4d * */ public class EdDSAPrivateKey implements EdDSAKey, PrivateKey { private static final long serialVersionUID = 23495873459878957L; private final byte[] seed; private final byte[] h; private final byte[] a; private final GroupElement A; private final byte[] Abyte; private final EdDSAParameterSpec edDsaSpec; // OID 1.3.101.xxx private static final int OID_OLD = 100; private static final int OID_ED25519 = 112; private static final int OID_BYTE = 11; private static final int IDLEN_BYTE = 6; public EdDSAPrivateKey(EdDSAPrivateKeySpec spec) { this.seed = spec.getSeed(); this.h = spec.getH(); this.a = spec.geta(); this.A = spec.getA(); this.Abyte = this.A.toByteArray(); this.edDsaSpec = spec.getParams(); } public EdDSAPrivateKey(PKCS8EncodedKeySpec spec) throws InvalidKeySpecException { this(new EdDSAPrivateKeySpec(decode(spec.getEncoded()), EdDSANamedCurveTable.getByName(EdDSANamedCurveTable.ED_25519))); } @Override public String getAlgorithm() { return KEY_ALGORITHM; } @Override public String getFormat() { return "PKCS#8"; } /** * Returns the public key in its canonical encoding. *

* This implements the following specs: *

  • * General encoding: https://tools.ietf.org/html/draft-ietf-curdle-pkix-04 *
  • * Key encoding: https://tools.ietf.org/html/rfc8032 *
*

* This encodes the seed. It will return null if constructed from * a spec which was directly constructed from H, in which case seed is null. *

* For keys in older formats, decoding and then re-encoding is sufficient to * migrate them to the canonical encoding. *

* Relevant spec quotes: *
     *  OneAsymmetricKey ::= SEQUENCE {
     *    version Version,
     *    privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
     *    privateKey PrivateKey,
     *    attributes [0] Attributes OPTIONAL,
     *    ...,
     *    [[2: publicKey [1] PublicKey OPTIONAL ]],
     *    ...
     *  }
     *
     *  Version ::= INTEGER
     *  PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
     *  PrivateKey ::= OCTET STRING
     *  PublicKey ::= OCTET STRING
     *  Attributes ::= SET OF Attribute
     *
* *
     *  ... when encoding a OneAsymmetricKey object, the private key is wrapped
     *  in a CurvePrivateKey object and wrapped by the OCTET STRING of the
     *  'privateKey' field.
     *
     *  CurvePrivateKey ::= OCTET STRING
     *
* *
     *  AlgorithmIdentifier  ::=  SEQUENCE  {
     *    algorithm   OBJECT IDENTIFIER,
     *    parameters  ANY DEFINED BY algorithm OPTIONAL
     *  }
     *
     *  For all of the OIDs, the parameters MUST be absent.
     *
* *
     *  id-Ed25519   OBJECT IDENTIFIER ::= { 1 3 101 112 }
     *
* * @return 48 bytes for Ed25519, null for other curves */ @Override public byte[] getEncoded() { if (!edDsaSpec.equals(EdDSANamedCurveTable.getByName(EdDSANamedCurveTable.ED_25519))) return null; if (seed == null) return null; int totlen = 16 + seed.length; byte[] rv = new byte[totlen]; int idx = 0; // sequence rv[idx++] = 0x30; rv[idx++] = (byte) (totlen - 2); // version rv[idx++] = 0x02; rv[idx++] = 1; // v1 - no public key included rv[idx++] = 0; // Algorithm Identifier // sequence rv[idx++] = 0x30; rv[idx++] = 5; // OID // https://msdn.microsoft.com/en-us/library/windows/desktop/bb540809%28v=vs.85%29.aspx rv[idx++] = 0x06; rv[idx++] = 3; rv[idx++] = (1 * 40) + 3; rv[idx++] = 101; rv[idx++] = (byte) OID_ED25519; // params - absent // PrivateKey rv[idx++] = 0x04; // octet string rv[idx++] = (byte) (2 + seed.length); // CurvePrivateKey rv[idx++] = 0x04; // octet string rv[idx++] = (byte) seed.length; // the key System.arraycopy(seed, 0, rv, idx, seed.length); return rv; } /** * Extracts the private key bytes from the provided encoding. *

* This will decode data conforming to the current spec at * https://tools.ietf.org/html/draft-ietf-curdle-pkix-04 * or as inferred from the old spec at * https://tools.ietf.org/html/draft-josefsson-pkix-eddsa-04. *

* Contrary to draft-ietf-curdle-pkix-04, it WILL accept a parameter value * of NULL, as it is required for interoperability with the default Java * keystore. Other implementations MUST NOT copy this behaviour from here * unless they also need to read keys from the default Java keystore. *

* This is really dumb for now. It does not use a general-purpose ASN.1 decoder. * See also getEncoded(). * * @return 32 bytes for Ed25519, throws for other curves */ private static byte[] decode(byte[] d) throws InvalidKeySpecException { try { // // Setup and OID check // int totlen = 48; int idlen = 5; int doid = d[OID_BYTE]; if (doid == OID_OLD) { totlen = 49; idlen = 8; } else if (doid == OID_ED25519) { // Detect parameter value of NULL if (d[IDLEN_BYTE] == 7) { totlen = 50; idlen = 7; } } else { throw new InvalidKeySpecException("unsupported key spec"); } // // Pre-decoding check // if (d.length != totlen) { throw new InvalidKeySpecException("invalid key spec length"); } // // Decoding // int idx = 0; if (d[idx++] != 0x30 || d[idx++] != (totlen - 2) || d[idx++] != 0x02 || d[idx++] != 1 || d[idx++] != 0 || d[idx++] != 0x30 || d[idx++] != idlen || d[idx++] != 0x06 || d[idx++] != 3 || d[idx++] != (1 * 40) + 3 || d[idx++] != 101) { throw new InvalidKeySpecException("unsupported key spec"); } idx++; // OID, checked above // parameters only with old OID if (doid == OID_OLD) { if (d[idx++] != 0x0a || d[idx++] != 1 || d[idx++] != 1) { throw new InvalidKeySpecException("unsupported key spec"); } } else { // Handle parameter value of NULL // // Quote https://tools.ietf.org/html/draft-ietf-curdle-pkix-04 : // For all of the OIDs, the parameters MUST be absent. // Regardless of the defect in the original 1997 syntax, // implementations MUST NOT accept a parameters value of NULL. // // But Java's default keystore puts it in (when decoding as // PKCS8 and then re-encoding to pass on), so we must accept it. if (idlen == 7) { if (d[idx++] != 0x05 || d[idx++] != 0) { throw new InvalidKeySpecException("unsupported key spec"); } } // PrivateKey wrapping the CurvePrivateKey if (d[idx++] != 0x04 || d[idx++] != 34) { throw new InvalidKeySpecException("unsupported key spec"); } } if (d[idx++] != 0x04 || d[idx++] != 32) { throw new InvalidKeySpecException("unsupported key spec"); } byte[] rv = new byte[32]; System.arraycopy(d, idx, rv, 0, 32); return rv; } catch (IndexOutOfBoundsException ioobe) { throw new InvalidKeySpecException(ioobe); } } @Override public EdDSAParameterSpec getParams() { return edDsaSpec; } /** * @return will be null if constructed from a spec which was * directly constructed from H */ public byte[] getSeed() { return seed; } /** * @return the hash of the seed */ public byte[] getH() { return h; } /** * @return the private key */ public byte[] geta() { return a; } /** * @return the public key */ public GroupElement getA() { return A; } /** * @return the public key */ public byte[] getAbyte() { return Abyte; } @Override public int hashCode() { return Arrays.hashCode(seed); } @Override public boolean equals(Object o) { if (o == this) return true; if (!(o instanceof EdDSAPrivateKey)) return false; EdDSAPrivateKey pk = (EdDSAPrivateKey) o; return Arrays.equals(seed, pk.getSeed()) && edDsaSpec.equals(pk.getParams()); } } ed25519-1.2.4/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/0000755000004100000410000000000013260523700022364 5ustar www-datawww-dataed25519-1.2.4/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/bigint/0000755000004100000410000000000013260523700023640 5ustar www-datawww-dataed25519-1.2.4/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/bigint/BigIntegerLittleEndianEncoding.java0000644000004100000410000000643413260523700032475 0ustar www-datawww-data/** * EdDSA-Java by str4d * * To the extent possible under law, the person who associated CC0 with * EdDSA-Java has waived all copyright and related or neighboring rights * to EdDSA-Java. * * You should have received a copy of the CC0 legalcode along with this * work. If not, see . * */ package net.i2p.crypto.eddsa.math.bigint; import java.io.Serializable; import java.math.BigInteger; import net.i2p.crypto.eddsa.math.Encoding; import net.i2p.crypto.eddsa.math.Field; import net.i2p.crypto.eddsa.math.FieldElement; public class BigIntegerLittleEndianEncoding extends Encoding implements Serializable { private static final long serialVersionUID = 3984579843759837L; /** * Mask where only the first b-1 bits are set. */ private BigInteger mask; @Override public synchronized void setField(Field f) { super.setField(f); mask = BigInteger.ONE.shiftLeft(f.getb()-1).subtract(BigInteger.ONE); } public byte[] encode(FieldElement x) { return encode(((BigIntegerFieldElement)x).bi.and(mask)); } /** * Convert $x$ to little endian. * Constant time. * * @param x the BigInteger value to encode * @return array of length $b/8$ * @throws IllegalStateException if field not set */ public byte[] encode(BigInteger x) { if (f == null) throw new IllegalStateException("field not set"); byte[] in = x.toByteArray(); byte[] out = new byte[f.getb()/8]; for (int i = 0; i < in.length; i++) { out[i] = in[in.length-1-i]; } for (int i = in.length; i < out.length; i++) { out[i] = 0; } return out; } /** * Decode a FieldElement from its $(b-1)$-bit encoding. * The highest bit is masked out. * * @param in the $(b-1)$-bit encoding of a FieldElement. * @return the FieldElement represented by 'val'. * @throws IllegalStateException if field not set * @throws IllegalArgumentException if encoding is invalid */ public FieldElement decode(byte[] in) { if (f == null) throw new IllegalStateException("field not set"); if (in.length != f.getb()/8) throw new IllegalArgumentException("Not a valid encoding"); return new BigIntegerFieldElement(f, toBigInteger(in).and(mask)); } /** * Convert in to big endian * * @param in the $(b-1)$-bit encoding of a FieldElement. * @return the decoded value as a BigInteger */ public BigInteger toBigInteger(byte[] in) { byte[] out = new byte[in.length]; for (int i = 0; i < in.length; i++) { out[i] = in[in.length-1-i]; } return new BigInteger(1, out); } /** * From the Ed25519 paper:
* $x$ is negative if the $(b-1)$-bit encoding of $x$ is lexicographically larger * than the $(b-1)$-bit encoding of $-x$. If $q$ is an odd prime and the encoding * is the little-endian representation of $\{0, 1,\dots, q-1\}$ then the negative * elements of $F_q$ are $\{1, 3, 5,\dots, q-2\}$. * @return true if negative */ public boolean isNegative(FieldElement x) { return ((BigIntegerFieldElement)x).bi.testBit(0); } } ed25519-1.2.4/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/bigint/BigIntegerFieldElement.java0000644000004100000410000000733113260523700031004 0ustar www-datawww-data/** * EdDSA-Java by str4d * * To the extent possible under law, the person who associated CC0 with * EdDSA-Java has waived all copyright and related or neighboring rights * to EdDSA-Java. * * You should have received a copy of the CC0 legalcode along with this * work. If not, see . * */ package net.i2p.crypto.eddsa.math.bigint; import java.io.Serializable; import java.math.BigInteger; import net.i2p.crypto.eddsa.math.Field; import net.i2p.crypto.eddsa.math.FieldElement; /** * A particular element of the field \Z/(2^255-19). * @author str4d * */ public class BigIntegerFieldElement extends FieldElement implements Serializable { private static final long serialVersionUID = 4890398908392808L; /** * Variable is package private for encoding. */ final BigInteger bi; public BigIntegerFieldElement(Field f, BigInteger bi) { super(f); this.bi = bi; } public boolean isNonZero() { return !bi.equals(BigInteger.ZERO); } public FieldElement add(FieldElement val) { return new BigIntegerFieldElement(f, bi.add(((BigIntegerFieldElement)val).bi)).mod(f.getQ()); } @Override public FieldElement addOne() { return new BigIntegerFieldElement(f, bi.add(BigInteger.ONE)).mod(f.getQ()); } public FieldElement subtract(FieldElement val) { return new BigIntegerFieldElement(f, bi.subtract(((BigIntegerFieldElement)val).bi)).mod(f.getQ()); } @Override public FieldElement subtractOne() { return new BigIntegerFieldElement(f, bi.subtract(BigInteger.ONE)).mod(f.getQ()); } public FieldElement negate() { return f.getQ().subtract(this); } @Override public FieldElement divide(FieldElement val) { return divide(((BigIntegerFieldElement)val).bi); } public FieldElement divide(BigInteger val) { return new BigIntegerFieldElement(f, bi.divide(val)).mod(f.getQ()); } public FieldElement multiply(FieldElement val) { return new BigIntegerFieldElement(f, bi.multiply(((BigIntegerFieldElement)val).bi)).mod(f.getQ()); } public FieldElement square() { return multiply(this); } public FieldElement squareAndDouble() { FieldElement sq = square(); return sq.add(sq); } public FieldElement invert() { // Euler's theorem //return modPow(f.getQm2(), f.getQ()); return new BigIntegerFieldElement(f, bi.modInverse(((BigIntegerFieldElement)f.getQ()).bi)); } public FieldElement mod(FieldElement m) { return new BigIntegerFieldElement(f, bi.mod(((BigIntegerFieldElement)m).bi)); } public FieldElement modPow(FieldElement e, FieldElement m) { return new BigIntegerFieldElement(f, bi.modPow(((BigIntegerFieldElement)e).bi, ((BigIntegerFieldElement)m).bi)); } public FieldElement pow(FieldElement e){ return modPow(e, f.getQ()); } public FieldElement pow22523(){ return pow(f.getQm5d8()); } @Override public FieldElement cmov(FieldElement val, int b) { // Not constant-time, but it doesn't really matter because none of the underlying BigInteger operations // are either, so there's not much point in trying hard here ... return b == 0 ? this : val; } @Override public int hashCode() { return bi.hashCode(); } @Override public boolean equals(Object obj) { if (!(obj instanceof BigIntegerFieldElement)) return false; BigIntegerFieldElement fe = (BigIntegerFieldElement) obj; return bi.equals(fe.bi); } @Override public String toString() { return "[BigIntegerFieldElement val="+bi+"]"; } } ed25519-1.2.4/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/bigint/BigIntegerScalarOps.java0000644000004100000410000000210613260523700030331 0ustar www-datawww-data/** * EdDSA-Java by str4d * * To the extent possible under law, the person who associated CC0 with * EdDSA-Java has waived all copyright and related or neighboring rights * to EdDSA-Java. * * You should have received a copy of the CC0 legalcode along with this * work. If not, see . * */ package net.i2p.crypto.eddsa.math.bigint; import java.math.BigInteger; import net.i2p.crypto.eddsa.math.Field; import net.i2p.crypto.eddsa.math.ScalarOps; public class BigIntegerScalarOps implements ScalarOps { private final BigInteger l; private final BigIntegerLittleEndianEncoding enc; public BigIntegerScalarOps(Field f, BigInteger l) { this.l = l; enc = new BigIntegerLittleEndianEncoding(); enc.setField(f); } public byte[] reduce(byte[] s) { return enc.encode(enc.toBigInteger(s).mod(l)); } public byte[] multiplyAndAdd(byte[] a, byte[] b, byte[] c) { return enc.encode(enc.toBigInteger(a).multiply(enc.toBigInteger(b)).add(enc.toBigInteger(c)).mod(l)); } } ed25519-1.2.4/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/bigint/package.html0000644000004100000410000000032213260523700026116 0ustar www-datawww-data

Low-level, non-optimized implementation using BigIntegers for any curve. See the ed25519 implementation for Curve 25519.

ed25519-1.2.4/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/Curve.java0000644000004100000410000000471213260523700024317 0ustar www-datawww-data/** * EdDSA-Java by str4d * * To the extent possible under law, the person who associated CC0 with * EdDSA-Java has waived all copyright and related or neighboring rights * to EdDSA-Java. * * You should have received a copy of the CC0 legalcode along with this * work. If not, see . * */ package net.i2p.crypto.eddsa.math; import java.io.Serializable; /** * A twisted Edwards curve. * Points on the curve satisfy $-x^2 + y^2 = 1 + d x^2y^2$ * @author str4d * */ public class Curve implements Serializable { private static final long serialVersionUID = 4578920872509827L; private final Field f; private final FieldElement d; private final FieldElement d2; private final FieldElement I; private final GroupElement zeroP2; private final GroupElement zeroP3; private final GroupElement zeroPrecomp; public Curve(Field f, byte[] d, FieldElement I) { this.f = f; this.d = f.fromByteArray(d); this.d2 = this.d.add(this.d); this.I = I; FieldElement zero = f.ZERO; FieldElement one = f.ONE; zeroP2 = GroupElement.p2(this, zero, one, one); zeroP3 = GroupElement.p3(this, zero, one, one, zero); zeroPrecomp = GroupElement.precomp(this, one, one, zero); } public Field getField() { return f; } public FieldElement getD() { return d; } public FieldElement get2D() { return d2; } public FieldElement getI() { return I; } public GroupElement getZero(GroupElement.Representation repr) { switch (repr) { case P2: return zeroP2; case P3: return zeroP3; case PRECOMP: return zeroPrecomp; default: return null; } } public GroupElement createPoint(byte[] P, boolean precompute) { GroupElement ge = new GroupElement(this, P); if (precompute) ge.precompute(true); return ge; } @Override public int hashCode() { return f.hashCode() ^ d.hashCode() ^ I.hashCode(); } @Override public boolean equals(Object o) { if (o == this) return true; if (!(o instanceof Curve)) return false; Curve c = (Curve) o; return f.equals(c.getField()) && d.equals(c.getD()) && I.equals(c.getI()); } } ed25519-1.2.4/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/Constants.java0000644000004100000410000000224713260523700025210 0ustar www-datawww-data/** * EdDSA-Java by str4d * * To the extent possible under law, the person who associated CC0 with * EdDSA-Java has waived all copyright and related or neighboring rights * to EdDSA-Java. * * You should have received a copy of the CC0 legalcode along with this * work. If not, see . * */ package net.i2p.crypto.eddsa.math; import net.i2p.crypto.eddsa.Utils; final class Constants { public static final byte[] ZERO = Utils.hexToBytes("0000000000000000000000000000000000000000000000000000000000000000"); public static final byte[] ONE = Utils.hexToBytes("0100000000000000000000000000000000000000000000000000000000000000"); public static final byte[] TWO = Utils.hexToBytes("0200000000000000000000000000000000000000000000000000000000000000"); public static final byte[] FOUR = Utils.hexToBytes("0400000000000000000000000000000000000000000000000000000000000000"); public static final byte[] FIVE = Utils.hexToBytes("0500000000000000000000000000000000000000000000000000000000000000"); public static final byte[] EIGHT = Utils.hexToBytes("0800000000000000000000000000000000000000000000000000000000000000"); } ed25519-1.2.4/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/Field.java0000644000004100000410000000441413260523700024255 0ustar www-datawww-data/** * EdDSA-Java by str4d * * To the extent possible under law, the person who associated CC0 with * EdDSA-Java has waived all copyright and related or neighboring rights * to EdDSA-Java. * * You should have received a copy of the CC0 legalcode along with this * work. If not, see . * */ package net.i2p.crypto.eddsa.math; import java.io.Serializable; /** * An EdDSA finite field. Includes several pre-computed values. * @author str4d * */ public class Field implements Serializable { private static final long serialVersionUID = 8746587465875676L; public final FieldElement ZERO; public final FieldElement ONE; public final FieldElement TWO; public final FieldElement FOUR; public final FieldElement FIVE; public final FieldElement EIGHT; private final int b; private final FieldElement q; /** * q-2 */ private final FieldElement qm2; /** * (q-5) / 8 */ private final FieldElement qm5d8; private final Encoding enc; public Field(int b, byte[] q, Encoding enc) { this.b = b; this.enc = enc; this.enc.setField(this); this.q = fromByteArray(q); // Set up constants ZERO = fromByteArray(Constants.ZERO); ONE = fromByteArray(Constants.ONE); TWO = fromByteArray(Constants.TWO); FOUR = fromByteArray(Constants.FOUR); FIVE = fromByteArray(Constants.FIVE); EIGHT = fromByteArray(Constants.EIGHT); // Precompute values qm2 = this.q.subtract(TWO); qm5d8 = this.q.subtract(FIVE).divide(EIGHT); } public FieldElement fromByteArray(byte[] x) { return enc.decode(x); } public int getb() { return b; } public FieldElement getQ() { return q; } public FieldElement getQm2() { return qm2; } public FieldElement getQm5d8() { return qm5d8; } public Encoding getEncoding(){ return enc; } @Override public int hashCode() { return q.hashCode(); } @Override public boolean equals(Object obj) { if (!(obj instanceof Field)) return false; Field f = (Field) obj; return b == f.b && q.equals(f.q); } } ed25519-1.2.4/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/Encoding.java0000644000004100000410000000330313260523700024754 0ustar www-datawww-data/** * EdDSA-Java by str4d * * To the extent possible under law, the person who associated CC0 with * EdDSA-Java has waived all copyright and related or neighboring rights * to EdDSA-Java. * * You should have received a copy of the CC0 legalcode along with this * work. If not, see . * */ package net.i2p.crypto.eddsa.math; /** * Common interface for all $(b-1)$-bit encodings of elements * of EdDSA finite fields. * @author str4d * */ public abstract class Encoding { protected Field f; public synchronized void setField(Field f) { if (this.f != null) throw new IllegalStateException("already set"); this.f = f; } /** * Encode a FieldElement in its $(b-1)$-bit encoding. * @param x the FieldElement to encode * @return the $(b-1)$-bit encoding of this FieldElement. */ public abstract byte[] encode(FieldElement x); /** * Decode a FieldElement from its $(b-1)$-bit encoding. * The highest bit is masked out. * @param in the $(b-1)$-bit encoding of a FieldElement. * @return the FieldElement represented by 'val'. */ public abstract FieldElement decode(byte[] in); /** * From the Ed25519 paper:
* $x$ is negative if the $(b-1)$-bit encoding of $x$ is lexicographically larger * than the $(b-1)$-bit encoding of -x. If $q$ is an odd prime and the encoding * is the little-endian representation of $\{0, 1,\dots, q-1\}$ then the negative * elements of $F_q$ are $\{1, 3, 5,\dots, q-2\}$. * @param x the FieldElement to check * @return true if negative */ public abstract boolean isNegative(FieldElement x); } ed25519-1.2.4/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/ed25519/0000755000004100000410000000000013260523700023362 5ustar www-datawww-dataed25519-1.2.4/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/ed25519/Ed25519LittleEndianEncoding.java0000644000004100000410000002133113260523700031127 0ustar www-datawww-data/** * EdDSA-Java by str4d * * To the extent possible under law, the person who associated CC0 with * EdDSA-Java has waived all copyright and related or neighboring rights * to EdDSA-Java. * * You should have received a copy of the CC0 legalcode along with this * work. If not, see . * */ package net.i2p.crypto.eddsa.math.ed25519; import net.i2p.crypto.eddsa.math.*; /** * Helper class for encoding/decoding from/to the 32 byte representation. *

* Reviewed/commented by Bloody Rookie (nemproject@gmx.de) */ public class Ed25519LittleEndianEncoding extends Encoding { /** * Encodes a given field element in its 32 byte representation. This is done in two steps: *

    *
  1. Reduce the value of the field element modulo $p$. *
  2. Convert the field element to the 32 byte representation. *

* The idea for the modulo $p$ reduction algorithm is as follows: *

*

Assumption:

*
    *
  • $p = 2^{255} - 19$ *
  • $h = h_0 + 2^{25} * h_1 + 2^{(26+25)} * h_2 + \dots + 2^{230} * h_9$ where $0 \le |h_i| \lt 2^{27}$ for all $i=0,\dots,9$. *
  • $h \cong r \mod p$, i.e. $h = r + q * p$ for some suitable $0 \le r \lt p$ and an integer $q$. *

* Then $q = [2^{-255} * (h + 19 * 2^{-25} * h_9 + 1/2)]$ where $[x] = floor(x)$. *

*

Proof:

*

* We begin with some very raw estimation for the bounds of some expressions: *

* $$ * \begin{equation} * |h| \lt 2^{230} * 2^{30} = 2^{260} \Rightarrow |r + q * p| \lt 2^{260} \Rightarrow |q| \lt 2^{10}. \\ * \Rightarrow -1/4 \le a := 19^2 * 2^{-255} * q \lt 1/4. \\ * |h - 2^{230} * h_9| = |h_0 + \dots + 2^{204} * h_8| \lt 2^{204} * 2^{30} = 2^{234}. \\ * \Rightarrow -1/4 \le b := 19 * 2^{-255} * (h - 2^{230} * h_9) \lt 1/4 * \end{equation} * $$ *

* Therefore $0 \lt 1/2 - a - b \lt 1$. *

* Set $x := r + 19 * 2^{-255} * r + 1/2 - a - b$. Then: *

* $$ * 0 \le x \lt 255 - 20 + 19 + 1 = 2^{255} \\ * \Rightarrow 0 \le 2^{-255} * x \lt 1. * $$ *

* Since $q$ is an integer we have *

* $$ * [q + 2^{-255} * x] = q \quad (1) * $$ *

* Have a closer look at $x$: *

* $$ * \begin{align} * x &= h - q * (2^{255} - 19) + 19 * 2^{-255} * (h - q * (2^{255} - 19)) + 1/2 - 19^2 * 2^{-255} * q - 19 * 2^{-255} * (h - 2^{230} * h_9) \\ * &= h - q * 2^{255} + 19 * q + 19 * 2^{-255} * h - 19 * q + 19^2 * 2^{-255} * q + 1/2 - 19^2 * 2^{-255} * q - 19 * 2^{-255} * h + 19 * 2^{-25} * h_9 \\ * &= h + 19 * 2^{-25} * h_9 + 1/2 - q^{255}. * \end{align} * $$ *

* Inserting the expression for $x$ into $(1)$ we get the desired expression for $q$. */ public byte[] encode(FieldElement x) { int[] h = ((Ed25519FieldElement)x).t; int h0 = h[0]; int h1 = h[1]; int h2 = h[2]; int h3 = h[3]; int h4 = h[4]; int h5 = h[5]; int h6 = h[6]; int h7 = h[7]; int h8 = h[8]; int h9 = h[9]; int q; int carry0; int carry1; int carry2; int carry3; int carry4; int carry5; int carry6; int carry7; int carry8; int carry9; // Step 1: // Calculate q q = (19 * h9 + (1 << 24)) >> 25; q = (h0 + q) >> 26; q = (h1 + q) >> 25; q = (h2 + q) >> 26; q = (h3 + q) >> 25; q = (h4 + q) >> 26; q = (h5 + q) >> 25; q = (h6 + q) >> 26; q = (h7 + q) >> 25; q = (h8 + q) >> 26; q = (h9 + q) >> 25; // r = h - q * p = h - 2^255 * q + 19 * q // First add 19 * q then discard the bit 255 h0 += 19 * q; carry0 = h0 >> 26; h1 += carry0; h0 -= carry0 << 26; carry1 = h1 >> 25; h2 += carry1; h1 -= carry1 << 25; carry2 = h2 >> 26; h3 += carry2; h2 -= carry2 << 26; carry3 = h3 >> 25; h4 += carry3; h3 -= carry3 << 25; carry4 = h4 >> 26; h5 += carry4; h4 -= carry4 << 26; carry5 = h5 >> 25; h6 += carry5; h5 -= carry5 << 25; carry6 = h6 >> 26; h7 += carry6; h6 -= carry6 << 26; carry7 = h7 >> 25; h8 += carry7; h7 -= carry7 << 25; carry8 = h8 >> 26; h9 += carry8; h8 -= carry8 << 26; carry9 = h9 >> 25; h9 -= carry9 << 25; // Step 2 (straight forward conversion): byte[] s = new byte[32]; s[0] = (byte) h0; s[1] = (byte) (h0 >> 8); s[2] = (byte) (h0 >> 16); s[3] = (byte) ((h0 >> 24) | (h1 << 2)); s[4] = (byte) (h1 >> 6); s[5] = (byte) (h1 >> 14); s[6] = (byte) ((h1 >> 22) | (h2 << 3)); s[7] = (byte) (h2 >> 5); s[8] = (byte) (h2 >> 13); s[9] = (byte) ((h2 >> 21) | (h3 << 5)); s[10] = (byte) (h3 >> 3); s[11] = (byte) (h3 >> 11); s[12] = (byte) ((h3 >> 19) | (h4 << 6)); s[13] = (byte) (h4 >> 2); s[14] = (byte) (h4 >> 10); s[15] = (byte) (h4 >> 18); s[16] = (byte) h5; s[17] = (byte) (h5 >> 8); s[18] = (byte) (h5 >> 16); s[19] = (byte) ((h5 >> 24) | (h6 << 1)); s[20] = (byte) (h6 >> 7); s[21] = (byte) (h6 >> 15); s[22] = (byte) ((h6 >> 23) | (h7 << 3)); s[23] = (byte) (h7 >> 5); s[24] = (byte) (h7 >> 13); s[25] = (byte) ((h7 >> 21) | (h8 << 4)); s[26] = (byte) (h8 >> 4); s[27] = (byte) (h8 >> 12); s[28] = (byte) ((h8 >> 20) | (h9 << 6)); s[29] = (byte) (h9 >> 2); s[30] = (byte) (h9 >> 10); s[31] = (byte) (h9 >> 18); return s; } static int load_3(byte[] in, int offset) { int result = in[offset++] & 0xff; result |= (in[offset++] & 0xff) << 8; result |= (in[offset] & 0xff) << 16; return result; } static long load_4(byte[] in, int offset) { int result = in[offset++] & 0xff; result |= (in[offset++] & 0xff) << 8; result |= (in[offset++] & 0xff) << 16; result |= in[offset] << 24; return ((long)result) & 0xffffffffL; } /** * Decodes a given field element in its 10 byte $2^{25.5}$ representation. * * @param in The 32 byte representation. * @return The field element in its $2^{25.5}$ bit representation. */ public FieldElement decode(byte[] in) { long h0 = load_4(in, 0); long h1 = load_3(in, 4) << 6; long h2 = load_3(in, 7) << 5; long h3 = load_3(in, 10) << 3; long h4 = load_3(in, 13) << 2; long h5 = load_4(in, 16); long h6 = load_3(in, 20) << 7; long h7 = load_3(in, 23) << 5; long h8 = load_3(in, 26) << 4; long h9 = (load_3(in, 29) & 0x7FFFFF) << 2; long carry0; long carry1; long carry2; long carry3; long carry4; long carry5; long carry6; long carry7; long carry8; long carry9; // Remember: 2^255 congruent 19 modulo p carry9 = (h9 + (long) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; carry1 = (h1 + (long) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25; carry3 = (h3 + (long) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25; carry5 = (h5 + (long) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25; carry7 = (h7 + (long) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25; carry0 = (h0 + (long) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; carry2 = (h2 + (long) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26; carry4 = (h4 + (long) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; carry6 = (h6 + (long) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26; carry8 = (h8 + (long) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26; int[] h = new int[10]; h[0] = (int) h0; h[1] = (int) h1; h[2] = (int) h2; h[3] = (int) h3; h[4] = (int) h4; h[5] = (int) h5; h[6] = (int) h6; h[7] = (int) h7; h[8] = (int) h8; h[9] = (int) h9; return new Ed25519FieldElement(f, h); } /** * Is the FieldElement negative in this encoding? *

* Return true if $x$ is in $\{1,3,5,\dots,q-2\}$
* Return false if $x$ is in $\{0,2,4,\dots,q-1\}$ *

* Preconditions: *

    *
  • $|x|$ bounded by $1.1*2^{26},1.1*2^{25},1.1*2^{26},1.1*2^{25}$, etc. *
* * @return true if $x$ is in $\{1,3,5,\dots,q-2\}$, false otherwise. */ public boolean isNegative(FieldElement x) { byte[] s = encode(x); return (s[0] & 1) != 0; } } ed25519-1.2.4/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/ed25519/Ed25519FieldElement.java0000644000004100000410000010106513260523700027444 0ustar www-datawww-data/** * EdDSA-Java by str4d * * To the extent possible under law, the person who associated CC0 with * EdDSA-Java has waived all copyright and related or neighboring rights * to EdDSA-Java. * * You should have received a copy of the CC0 legalcode along with this * work. If not, see . * */ package net.i2p.crypto.eddsa.math.ed25519; import net.i2p.crypto.eddsa.Utils; import net.i2p.crypto.eddsa.math.*; import java.util.Arrays; /** * Class to represent a field element of the finite field $p = 2^{255} - 19$ elements. *

* An element $t$, entries $t[0] \dots t[9]$, represents the integer * $t[0]+2^{26} t[1]+2^{51} t[2]+2^{77} t[3]+2^{102} t[4]+\dots+2^{230} t[9]$. * Bounds on each $t[i]$ vary depending on context. *

* Reviewed/commented by Bloody Rookie (nemproject@gmx.de) */ public class Ed25519FieldElement extends FieldElement { /** * Variable is package private for encoding. */ final int[] t; /** * Creates a field element. * * @param f The underlying field, must be the finite field with $p = 2^{255} - 19$ elements * @param t The $2^{25.5}$ bit representation of the field element. */ public Ed25519FieldElement(Field f, int[] t) { super(f); if (t.length != 10) throw new IllegalArgumentException("Invalid radix-2^51 representation"); this.t = t; } private static final byte[] ZERO = new byte[32]; /** * Gets a value indicating whether or not the field element is non-zero. * * @return 1 if it is non-zero, 0 otherwise. */ public boolean isNonZero() { final byte[] s = toByteArray(); return Utils.equal(s, ZERO) == 0; } /** * $h = f + g$ *

* TODO-CR BR: $h$ is allocated via new, probably not a good idea. Do we need the copying into temp variables if we do that? *

* Preconditions: *

    *
  • $|f|$ bounded by $1.1*2^{25},1.1*2^{24},1.1*2^{25},1.1*2^{24},$ etc. *
  • $|g|$ bounded by $1.1*2^{25},1.1*2^{24},1.1*2^{25},1.1*2^{24},$ etc. *

* Postconditions: *

    *
  • $|h|$ bounded by $1.1*2^{26},1.1*2^{25},1.1*2^{26},1.1*2^{25},$ etc. *
* * @param val The field element to add. * @return The field element this + val. */ public FieldElement add(FieldElement val) { int[] g = ((Ed25519FieldElement)val).t; int[] h = new int[10]; for (int i = 0; i < 10; i++) { h[i] = t[i] + g[i]; } return new Ed25519FieldElement(f, h); } /** * $h = f - g$ *

* Can overlap $h$ with $f$ or $g$. *

* TODO-CR BR: See above. *

* Preconditions: *

    *
  • $|f|$ bounded by $1.1*2^{25},1.1*2^{24},1.1*2^{25},1.1*2^{24},$ etc. *
  • $|g|$ bounded by $1.1*2^{25},1.1*2^{24},1.1*2^{25},1.1*2^{24},$ etc. *

* Postconditions: *

    *
  • $|h|$ bounded by $1.1*2^{26},1.1*2^{25},1.1*2^{26},1.1*2^{25},$ etc. *
* * @param val The field element to subtract. * @return The field element this - val. **/ public FieldElement subtract(FieldElement val) { int[] g = ((Ed25519FieldElement)val).t; int[] h = new int[10]; for (int i = 0; i < 10; i++) { h[i] = t[i] - g[i]; } return new Ed25519FieldElement(f, h); } /** * $h = -f$ *

* TODO-CR BR: see above. *

* Preconditions: *

    *
  • $|f|$ bounded by $1.1*2^{25},1.1*2^{24},1.1*2^{25},1.1*2^{24},$ etc. *

* Postconditions: *

    *
  • $|h|$ bounded by $1.1*2^{25},1.1*2^{24},1.1*2^{25},1.1*2^{24},$ etc. *
* * @return The field element (-1) * this. */ public FieldElement negate() { int[] h = new int[10]; for (int i = 0; i < 10; i++) { h[i] = - t[i]; } return new Ed25519FieldElement(f, h); } /** * $h = f * g$ *

* Can overlap $h$ with $f$ or $g$. *

* Preconditions: *

    *
  • $|f|$ bounded by * $1.65*2^{26},1.65*2^{25},1.65*2^{26},1.65*2^{25},$ etc. *
  • $|g|$ bounded by * $1.65*2^{26},1.65*2^{25},1.65*2^{26},1.65*2^{25},$ etc. *

* Postconditions: *

    *
  • $|h|$ bounded by * $1.01*2^{25},1.01*2^{24},1.01*2^{25},1.01*2^{24},$ etc. *

* Notes on implementation strategy: *

* Using schoolbook multiplication. Karatsuba would save a little in some * cost models. *

* Most multiplications by 2 and 19 are 32-bit precomputations; cheaper than * 64-bit postcomputations. *

* There is one remaining multiplication by 19 in the carry chain; one *19 * precomputation can be merged into this, but the resulting data flow is * considerably less clean. *

* There are 12 carries below. 10 of them are 2-way parallelizable and * vectorizable. Can get away with 11 carries, but then data flow is much * deeper. *

* With tighter constraints on inputs can squeeze carries into int32. * * @param val The field element to multiply. * @return The (reasonably reduced) field element this * val. */ public FieldElement multiply(FieldElement val) { int[] g = ((Ed25519FieldElement)val).t; int g1_19 = 19 * g[1]; /* 1.959375*2^29 */ int g2_19 = 19 * g[2]; /* 1.959375*2^30; still ok */ int g3_19 = 19 * g[3]; int g4_19 = 19 * g[4]; int g5_19 = 19 * g[5]; int g6_19 = 19 * g[6]; int g7_19 = 19 * g[7]; int g8_19 = 19 * g[8]; int g9_19 = 19 * g[9]; int f1_2 = 2 * t[1]; int f3_2 = 2 * t[3]; int f5_2 = 2 * t[5]; int f7_2 = 2 * t[7]; int f9_2 = 2 * t[9]; long f0g0 = t[0] * (long) g[0]; long f0g1 = t[0] * (long) g[1]; long f0g2 = t[0] * (long) g[2]; long f0g3 = t[0] * (long) g[3]; long f0g4 = t[0] * (long) g[4]; long f0g5 = t[0] * (long) g[5]; long f0g6 = t[0] * (long) g[6]; long f0g7 = t[0] * (long) g[7]; long f0g8 = t[0] * (long) g[8]; long f0g9 = t[0] * (long) g[9]; long f1g0 = t[1] * (long) g[0]; long f1g1_2 = f1_2 * (long) g[1]; long f1g2 = t[1] * (long) g[2]; long f1g3_2 = f1_2 * (long) g[3]; long f1g4 = t[1] * (long) g[4]; long f1g5_2 = f1_2 * (long) g[5]; long f1g6 = t[1] * (long) g[6]; long f1g7_2 = f1_2 * (long) g[7]; long f1g8 = t[1] * (long) g[8]; long f1g9_38 = f1_2 * (long) g9_19; long f2g0 = t[2] * (long) g[0]; long f2g1 = t[2] * (long) g[1]; long f2g2 = t[2] * (long) g[2]; long f2g3 = t[2] * (long) g[3]; long f2g4 = t[2] * (long) g[4]; long f2g5 = t[2] * (long) g[5]; long f2g6 = t[2] * (long) g[6]; long f2g7 = t[2] * (long) g[7]; long f2g8_19 = t[2] * (long) g8_19; long f2g9_19 = t[2] * (long) g9_19; long f3g0 = t[3] * (long) g[0]; long f3g1_2 = f3_2 * (long) g[1]; long f3g2 = t[3] * (long) g[2]; long f3g3_2 = f3_2 * (long) g[3]; long f3g4 = t[3] * (long) g[4]; long f3g5_2 = f3_2 * (long) g[5]; long f3g6 = t[3] * (long) g[6]; long f3g7_38 = f3_2 * (long) g7_19; long f3g8_19 = t[3] * (long) g8_19; long f3g9_38 = f3_2 * (long) g9_19; long f4g0 = t[4] * (long) g[0]; long f4g1 = t[4] * (long) g[1]; long f4g2 = t[4] * (long) g[2]; long f4g3 = t[4] * (long) g[3]; long f4g4 = t[4] * (long) g[4]; long f4g5 = t[4] * (long) g[5]; long f4g6_19 = t[4] * (long) g6_19; long f4g7_19 = t[4] * (long) g7_19; long f4g8_19 = t[4] * (long) g8_19; long f4g9_19 = t[4] * (long) g9_19; long f5g0 = t[5] * (long) g[0]; long f5g1_2 = f5_2 * (long) g[1]; long f5g2 = t[5] * (long) g[2]; long f5g3_2 = f5_2 * (long) g[3]; long f5g4 = t[5] * (long) g[4]; long f5g5_38 = f5_2 * (long) g5_19; long f5g6_19 = t[5] * (long) g6_19; long f5g7_38 = f5_2 * (long) g7_19; long f5g8_19 = t[5] * (long) g8_19; long f5g9_38 = f5_2 * (long) g9_19; long f6g0 = t[6] * (long) g[0]; long f6g1 = t[6] * (long) g[1]; long f6g2 = t[6] * (long) g[2]; long f6g3 = t[6] * (long) g[3]; long f6g4_19 = t[6] * (long) g4_19; long f6g5_19 = t[6] * (long) g5_19; long f6g6_19 = t[6] * (long) g6_19; long f6g7_19 = t[6] * (long) g7_19; long f6g8_19 = t[6] * (long) g8_19; long f6g9_19 = t[6] * (long) g9_19; long f7g0 = t[7] * (long) g[0]; long f7g1_2 = f7_2 * (long) g[1]; long f7g2 = t[7] * (long) g[2]; long f7g3_38 = f7_2 * (long) g3_19; long f7g4_19 = t[7] * (long) g4_19; long f7g5_38 = f7_2 * (long) g5_19; long f7g6_19 = t[7] * (long) g6_19; long f7g7_38 = f7_2 * (long) g7_19; long f7g8_19 = t[7] * (long) g8_19; long f7g9_38 = f7_2 * (long) g9_19; long f8g0 = t[8] * (long) g[0]; long f8g1 = t[8] * (long) g[1]; long f8g2_19 = t[8] * (long) g2_19; long f8g3_19 = t[8] * (long) g3_19; long f8g4_19 = t[8] * (long) g4_19; long f8g5_19 = t[8] * (long) g5_19; long f8g6_19 = t[8] * (long) g6_19; long f8g7_19 = t[8] * (long) g7_19; long f8g8_19 = t[8] * (long) g8_19; long f8g9_19 = t[8] * (long) g9_19; long f9g0 = t[9] * (long) g[0]; long f9g1_38 = f9_2 * (long) g1_19; long f9g2_19 = t[9] * (long) g2_19; long f9g3_38 = f9_2 * (long) g3_19; long f9g4_19 = t[9] * (long) g4_19; long f9g5_38 = f9_2 * (long) g5_19; long f9g6_19 = t[9] * (long) g6_19; long f9g7_38 = f9_2 * (long) g7_19; long f9g8_19 = t[9] * (long) g8_19; long f9g9_38 = f9_2 * (long) g9_19; /** * Remember: 2^255 congruent 19 modulo p. * h = h0 * 2^0 + h1 * 2^26 + h2 * 2^(26+25) + h3 * 2^(26+25+26) + ... + h9 * 2^(5*26+5*25). * So to get the real number we would have to multiply the coefficients with the corresponding powers of 2. * To get an idea what is going on below, look at the calculation of h0: * h0 is the coefficient to the power 2^0 so it collects (sums) all products that have the power 2^0. * f0 * g0 really is f0 * 2^0 * g0 * 2^0 = (f0 * g0) * 2^0. * f1 * g9 really is f1 * 2^26 * g9 * 2^230 = f1 * g9 * 2^256 = 2 * f1 * g9 * 2^255 congruent 2 * 19 * f1 * g9 * 2^0 modulo p. * f2 * g8 really is f2 * 2^51 * g8 * 2^204 = f2 * g8 * 2^255 congruent 19 * f2 * g8 * 2^0 modulo p. * and so on... */ long h0 = f0g0 + f1g9_38 + f2g8_19 + f3g7_38 + f4g6_19 + f5g5_38 + f6g4_19 + f7g3_38 + f8g2_19 + f9g1_38; long h1 = f0g1 + f1g0 + f2g9_19 + f3g8_19 + f4g7_19 + f5g6_19 + f6g5_19 + f7g4_19 + f8g3_19 + f9g2_19; long h2 = f0g2 + f1g1_2 + f2g0 + f3g9_38 + f4g8_19 + f5g7_38 + f6g6_19 + f7g5_38 + f8g4_19 + f9g3_38; long h3 = f0g3 + f1g2 + f2g1 + f3g0 + f4g9_19 + f5g8_19 + f6g7_19 + f7g6_19 + f8g5_19 + f9g4_19; long h4 = f0g4 + f1g3_2 + f2g2 + f3g1_2 + f4g0 + f5g9_38 + f6g8_19 + f7g7_38 + f8g6_19 + f9g5_38; long h5 = f0g5 + f1g4 + f2g3 + f3g2 + f4g1 + f5g0 + f6g9_19 + f7g8_19 + f8g7_19 + f9g6_19; long h6 = f0g6 + f1g5_2 + f2g4 + f3g3_2 + f4g2 + f5g1_2 + f6g0 + f7g9_38 + f8g8_19 + f9g7_38; long h7 = f0g7 + f1g6 + f2g5 + f3g4 + f4g3 + f5g2 + f6g1 + f7g0 + f8g9_19 + f9g8_19; long h8 = f0g8 + f1g7_2 + f2g6 + f3g5_2 + f4g4 + f5g3_2 + f6g2 + f7g1_2 + f8g0 + f9g9_38; long h9 = f0g9 + f1g8 + f2g7 + f3g6 + f4g5 + f5g4 + f6g3 + f7g2 + f8g1 + f9g0; long carry0; long carry1; long carry2; long carry3; long carry4; long carry5; long carry6; long carry7; long carry8; long carry9; /* |h0| <= (1.65*1.65*2^52*(1+19+19+19+19)+1.65*1.65*2^50*(38+38+38+38+38)) i.e. |h0| <= 1.4*2^60; narrower ranges for h2, h4, h6, h8 |h1| <= (1.65*1.65*2^51*(1+1+19+19+19+19+19+19+19+19)) i.e. |h1| <= 1.7*2^59; narrower ranges for h3, h5, h7, h9 */ carry0 = (h0 + (long) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; carry4 = (h4 + (long) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; /* |h0| <= 2^25 */ /* |h4| <= 2^25 */ /* |h1| <= 1.71*2^59 */ /* |h5| <= 1.71*2^59 */ carry1 = (h1 + (long) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25; carry5 = (h5 + (long) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25; /* |h1| <= 2^24; from now on fits into int32 */ /* |h5| <= 2^24; from now on fits into int32 */ /* |h2| <= 1.41*2^60 */ /* |h6| <= 1.41*2^60 */ carry2 = (h2 + (long) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26; carry6 = (h6 + (long) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26; /* |h2| <= 2^25; from now on fits into int32 unchanged */ /* |h6| <= 2^25; from now on fits into int32 unchanged */ /* |h3| <= 1.71*2^59 */ /* |h7| <= 1.71*2^59 */ carry3 = (h3 + (long) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25; carry7 = (h7 + (long) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25; /* |h3| <= 2^24; from now on fits into int32 unchanged */ /* |h7| <= 2^24; from now on fits into int32 unchanged */ /* |h4| <= 1.72*2^34 */ /* |h8| <= 1.41*2^60 */ carry4 = (h4 + (long) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; carry8 = (h8 + (long) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26; /* |h4| <= 2^25; from now on fits into int32 unchanged */ /* |h8| <= 2^25; from now on fits into int32 unchanged */ /* |h5| <= 1.01*2^24 */ /* |h9| <= 1.71*2^59 */ carry9 = (h9 + (long) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; /* |h9| <= 2^24; from now on fits into int32 unchanged */ /* |h0| <= 1.1*2^39 */ carry0 = (h0 + (long) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; /* |h0| <= 2^25; from now on fits into int32 unchanged */ /* |h1| <= 1.01*2^24 */ int[] h = new int[10]; h[0] = (int) h0; h[1] = (int) h1; h[2] = (int) h2; h[3] = (int) h3; h[4] = (int) h4; h[5] = (int) h5; h[6] = (int) h6; h[7] = (int) h7; h[8] = (int) h8; h[9] = (int) h9; return new Ed25519FieldElement(f, h); } /** * $h = f * f$ *

* Can overlap $h$ with $f$. *

* Preconditions: *

    *
  • $|f|$ bounded by $1.65*2^{26},1.65*2^{25},1.65*2^{26},1.65*2^{25},$ etc. *

* Postconditions: *

    *
  • $|h|$ bounded by $1.01*2^{25},1.01*2^{24},1.01*2^{25},1.01*2^{24},$ etc. *

* See {@link #multiply(FieldElement)} for discussion * of implementation strategy. * * @return The (reasonably reduced) square of this field element. */ public FieldElement square() { int f0 = t[0]; int f1 = t[1]; int f2 = t[2]; int f3 = t[3]; int f4 = t[4]; int f5 = t[5]; int f6 = t[6]; int f7 = t[7]; int f8 = t[8]; int f9 = t[9]; int f0_2 = 2 * f0; int f1_2 = 2 * f1; int f2_2 = 2 * f2; int f3_2 = 2 * f3; int f4_2 = 2 * f4; int f5_2 = 2 * f5; int f6_2 = 2 * f6; int f7_2 = 2 * f7; int f5_38 = 38 * f5; /* 1.959375*2^30 */ int f6_19 = 19 * f6; /* 1.959375*2^30 */ int f7_38 = 38 * f7; /* 1.959375*2^30 */ int f8_19 = 19 * f8; /* 1.959375*2^30 */ int f9_38 = 38 * f9; /* 1.959375*2^30 */ long f0f0 = f0 * (long) f0; long f0f1_2 = f0_2 * (long) f1; long f0f2_2 = f0_2 * (long) f2; long f0f3_2 = f0_2 * (long) f3; long f0f4_2 = f0_2 * (long) f4; long f0f5_2 = f0_2 * (long) f5; long f0f6_2 = f0_2 * (long) f6; long f0f7_2 = f0_2 * (long) f7; long f0f8_2 = f0_2 * (long) f8; long f0f9_2 = f0_2 * (long) f9; long f1f1_2 = f1_2 * (long) f1; long f1f2_2 = f1_2 * (long) f2; long f1f3_4 = f1_2 * (long) f3_2; long f1f4_2 = f1_2 * (long) f4; long f1f5_4 = f1_2 * (long) f5_2; long f1f6_2 = f1_2 * (long) f6; long f1f7_4 = f1_2 * (long) f7_2; long f1f8_2 = f1_2 * (long) f8; long f1f9_76 = f1_2 * (long) f9_38; long f2f2 = f2 * (long) f2; long f2f3_2 = f2_2 * (long) f3; long f2f4_2 = f2_2 * (long) f4; long f2f5_2 = f2_2 * (long) f5; long f2f6_2 = f2_2 * (long) f6; long f2f7_2 = f2_2 * (long) f7; long f2f8_38 = f2_2 * (long) f8_19; long f2f9_38 = f2 * (long) f9_38; long f3f3_2 = f3_2 * (long) f3; long f3f4_2 = f3_2 * (long) f4; long f3f5_4 = f3_2 * (long) f5_2; long f3f6_2 = f3_2 * (long) f6; long f3f7_76 = f3_2 * (long) f7_38; long f3f8_38 = f3_2 * (long) f8_19; long f3f9_76 = f3_2 * (long) f9_38; long f4f4 = f4 * (long) f4; long f4f5_2 = f4_2 * (long) f5; long f4f6_38 = f4_2 * (long) f6_19; long f4f7_38 = f4 * (long) f7_38; long f4f8_38 = f4_2 * (long) f8_19; long f4f9_38 = f4 * (long) f9_38; long f5f5_38 = f5 * (long) f5_38; long f5f6_38 = f5_2 * (long) f6_19; long f5f7_76 = f5_2 * (long) f7_38; long f5f8_38 = f5_2 * (long) f8_19; long f5f9_76 = f5_2 * (long) f9_38; long f6f6_19 = f6 * (long) f6_19; long f6f7_38 = f6 * (long) f7_38; long f6f8_38 = f6_2 * (long) f8_19; long f6f9_38 = f6 * (long) f9_38; long f7f7_38 = f7 * (long) f7_38; long f7f8_38 = f7_2 * (long) f8_19; long f7f9_76 = f7_2 * (long) f9_38; long f8f8_19 = f8 * (long) f8_19; long f8f9_38 = f8 * (long) f9_38; long f9f9_38 = f9 * (long) f9_38; /** * Same procedure as in multiply, but this time we have a higher symmetry leading to less summands. * e.g. f1f9_76 really stands for f1 * 2^26 * f9 * 2^230 + f9 * 2^230 + f1 * 2^26 congruent 2 * 2 * 19 * f1 * f9 2^0 modulo p. */ long h0 = f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38; long h1 = f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38; long h2 = f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19; long h3 = f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38; long h4 = f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38; long h5 = f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38; long h6 = f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19; long h7 = f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38; long h8 = f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38; long h9 = f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2; long carry0; long carry1; long carry2; long carry3; long carry4; long carry5; long carry6; long carry7; long carry8; long carry9; carry0 = (h0 + (long) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; carry4 = (h4 + (long) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; carry1 = (h1 + (long) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25; carry5 = (h5 + (long) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25; carry2 = (h2 + (long) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26; carry6 = (h6 + (long) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26; carry3 = (h3 + (long) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25; carry7 = (h7 + (long) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25; carry4 = (h4 + (long) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; carry8 = (h8 + (long) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26; carry9 = (h9 + (long) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; carry0 = (h0 + (long) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; int[] h = new int[10]; h[0] = (int) h0; h[1] = (int) h1; h[2] = (int) h2; h[3] = (int) h3; h[4] = (int) h4; h[5] = (int) h5; h[6] = (int) h6; h[7] = (int) h7; h[8] = (int) h8; h[9] = (int) h9; return new Ed25519FieldElement(f, h); } /** * $h = 2 * f * f$ *

* Can overlap $h$ with $f$. *

* Preconditions: *

    *
  • $|f|$ bounded by $1.65*2^{26},1.65*2^{25},1.65*2^{26},1.65*2^{25},$ etc. *

* Postconditions: *

    *
  • $|h|$ bounded by $1.01*2^{25},1.01*2^{24},1.01*2^{25},1.01*2^{24},$ etc. *

* See {@link #multiply(FieldElement)} for discussion * of implementation strategy. * * @return The (reasonably reduced) square of this field element times 2. */ public FieldElement squareAndDouble() { int f0 = t[0]; int f1 = t[1]; int f2 = t[2]; int f3 = t[3]; int f4 = t[4]; int f5 = t[5]; int f6 = t[6]; int f7 = t[7]; int f8 = t[8]; int f9 = t[9]; int f0_2 = 2 * f0; int f1_2 = 2 * f1; int f2_2 = 2 * f2; int f3_2 = 2 * f3; int f4_2 = 2 * f4; int f5_2 = 2 * f5; int f6_2 = 2 * f6; int f7_2 = 2 * f7; int f5_38 = 38 * f5; /* 1.959375*2^30 */ int f6_19 = 19 * f6; /* 1.959375*2^30 */ int f7_38 = 38 * f7; /* 1.959375*2^30 */ int f8_19 = 19 * f8; /* 1.959375*2^30 */ int f9_38 = 38 * f9; /* 1.959375*2^30 */ long f0f0 = f0 * (long) f0; long f0f1_2 = f0_2 * (long) f1; long f0f2_2 = f0_2 * (long) f2; long f0f3_2 = f0_2 * (long) f3; long f0f4_2 = f0_2 * (long) f4; long f0f5_2 = f0_2 * (long) f5; long f0f6_2 = f0_2 * (long) f6; long f0f7_2 = f0_2 * (long) f7; long f0f8_2 = f0_2 * (long) f8; long f0f9_2 = f0_2 * (long) f9; long f1f1_2 = f1_2 * (long) f1; long f1f2_2 = f1_2 * (long) f2; long f1f3_4 = f1_2 * (long) f3_2; long f1f4_2 = f1_2 * (long) f4; long f1f5_4 = f1_2 * (long) f5_2; long f1f6_2 = f1_2 * (long) f6; long f1f7_4 = f1_2 * (long) f7_2; long f1f8_2 = f1_2 * (long) f8; long f1f9_76 = f1_2 * (long) f9_38; long f2f2 = f2 * (long) f2; long f2f3_2 = f2_2 * (long) f3; long f2f4_2 = f2_2 * (long) f4; long f2f5_2 = f2_2 * (long) f5; long f2f6_2 = f2_2 * (long) f6; long f2f7_2 = f2_2 * (long) f7; long f2f8_38 = f2_2 * (long) f8_19; long f2f9_38 = f2 * (long) f9_38; long f3f3_2 = f3_2 * (long) f3; long f3f4_2 = f3_2 * (long) f4; long f3f5_4 = f3_2 * (long) f5_2; long f3f6_2 = f3_2 * (long) f6; long f3f7_76 = f3_2 * (long) f7_38; long f3f8_38 = f3_2 * (long) f8_19; long f3f9_76 = f3_2 * (long) f9_38; long f4f4 = f4 * (long) f4; long f4f5_2 = f4_2 * (long) f5; long f4f6_38 = f4_2 * (long) f6_19; long f4f7_38 = f4 * (long) f7_38; long f4f8_38 = f4_2 * (long) f8_19; long f4f9_38 = f4 * (long) f9_38; long f5f5_38 = f5 * (long) f5_38; long f5f6_38 = f5_2 * (long) f6_19; long f5f7_76 = f5_2 * (long) f7_38; long f5f8_38 = f5_2 * (long) f8_19; long f5f9_76 = f5_2 * (long) f9_38; long f6f6_19 = f6 * (long) f6_19; long f6f7_38 = f6 * (long) f7_38; long f6f8_38 = f6_2 * (long) f8_19; long f6f9_38 = f6 * (long) f9_38; long f7f7_38 = f7 * (long) f7_38; long f7f8_38 = f7_2 * (long) f8_19; long f7f9_76 = f7_2 * (long) f9_38; long f8f8_19 = f8 * (long) f8_19; long f8f9_38 = f8 * (long) f9_38; long f9f9_38 = f9 * (long) f9_38; long h0 = f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38; long h1 = f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38; long h2 = f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19; long h3 = f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38; long h4 = f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38; long h5 = f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38; long h6 = f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19; long h7 = f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38; long h8 = f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38; long h9 = f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2; long carry0; long carry1; long carry2; long carry3; long carry4; long carry5; long carry6; long carry7; long carry8; long carry9; h0 += h0; h1 += h1; h2 += h2; h3 += h3; h4 += h4; h5 += h5; h6 += h6; h7 += h7; h8 += h8; h9 += h9; carry0 = (h0 + (long) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; carry4 = (h4 + (long) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; carry1 = (h1 + (long) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25; carry5 = (h5 + (long) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25; carry2 = (h2 + (long) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26; carry6 = (h6 + (long) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26; carry3 = (h3 + (long) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25; carry7 = (h7 + (long) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25; carry4 = (h4 + (long) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; carry8 = (h8 + (long) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26; carry9 = (h9 + (long) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; carry0 = (h0 + (long) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; int[] h = new int[10]; h[0] = (int) h0; h[1] = (int) h1; h[2] = (int) h2; h[3] = (int) h3; h[4] = (int) h4; h[5] = (int) h5; h[6] = (int) h6; h[7] = (int) h7; h[8] = (int) h8; h[9] = (int) h9; return new Ed25519FieldElement(f, h); } /** * Invert this field element. *

* The inverse is found via Fermat's little theorem:
* $a^p \cong a \mod p$ and therefore $a^{(p-2)} \cong a^{-1} \mod p$ * * @return The inverse of this field element. */ public FieldElement invert() { FieldElement t0, t1, t2, t3; // 2 == 2 * 1 t0 = square(); // 4 == 2 * 2 t1 = t0.square(); // 8 == 2 * 4 t1 = t1.square(); // 9 == 8 + 1 t1 = multiply(t1); // 11 == 9 + 2 t0 = t0.multiply(t1); // 22 == 2 * 11 t2 = t0.square(); // 31 == 22 + 9 t1 = t1.multiply(t2); // 2^6 - 2^1 t2 = t1.square(); // 2^10 - 2^5 for (int i = 1; i < 5; ++i) { t2 = t2.square(); } // 2^10 - 2^0 t1 = t2.multiply(t1); // 2^11 - 2^1 t2 = t1.square(); // 2^20 - 2^10 for (int i = 1; i < 10; ++i) { t2 = t2.square(); } // 2^20 - 2^0 t2 = t2.multiply(t1); // 2^21 - 2^1 t3 = t2.square(); // 2^40 - 2^20 for (int i = 1; i < 20; ++i) { t3 = t3.square(); } // 2^40 - 2^0 t2 = t3.multiply(t2); // 2^41 - 2^1 t2 = t2.square(); // 2^50 - 2^10 for (int i = 1; i < 10; ++i) { t2 = t2.square(); } // 2^50 - 2^0 t1 = t2.multiply(t1); // 2^51 - 2^1 t2 = t1.square(); // 2^100 - 2^50 for (int i = 1; i < 50; ++i) { t2 = t2.square(); } // 2^100 - 2^0 t2 = t2.multiply(t1); // 2^101 - 2^1 t3 = t2.square(); // 2^200 - 2^100 for (int i = 1; i < 100; ++i) { t3 = t3.square(); } // 2^200 - 2^0 t2 = t3.multiply(t2); // 2^201 - 2^1 t2 = t2.square(); // 2^250 - 2^50 for (int i = 1; i < 50; ++i) { t2 = t2.square(); } // 2^250 - 2^0 t1 = t2.multiply(t1); // 2^251 - 2^1 t1 = t1.square(); // 2^255 - 2^5 for (int i = 1; i < 5; ++i) { t1 = t1.square(); } // 2^255 - 21 return t1.multiply(t0); } /** * Gets this field element to the power of $(2^{252} - 3)$. * This is a helper function for calculating the square root. *

* TODO-CR BR: I think it makes sense to have a sqrt function. * * @return This field element to the power of $(2^{252} - 3)$. */ public FieldElement pow22523() { FieldElement t0, t1, t2; // 2 == 2 * 1 t0 = square(); // 4 == 2 * 2 t1 = t0.square(); // 8 == 2 * 4 t1 = t1.square(); // z9 = z1*z8 t1 = multiply(t1); // 11 == 9 + 2 t0 = t0.multiply(t1); // 22 == 2 * 11 t0 = t0.square(); // 31 == 22 + 9 t0 = t1.multiply(t0); // 2^6 - 2^1 t1 = t0.square(); // 2^10 - 2^5 for (int i = 1; i < 5; ++i) { t1 = t1.square(); } // 2^10 - 2^0 t0 = t1.multiply(t0); // 2^11 - 2^1 t1 = t0.square(); // 2^20 - 2^10 for (int i = 1; i < 10; ++i) { t1 = t1.square(); } // 2^20 - 2^0 t1 = t1.multiply(t0); // 2^21 - 2^1 t2 = t1.square(); // 2^40 - 2^20 for (int i = 1; i < 20; ++i) { t2 = t2.square(); } // 2^40 - 2^0 t1 = t2.multiply(t1); // 2^41 - 2^1 t1 = t1.square(); // 2^50 - 2^10 for (int i = 1; i < 10; ++i) { t1 = t1.square(); } // 2^50 - 2^0 t0 = t1.multiply(t0); // 2^51 - 2^1 t1 = t0.square(); // 2^100 - 2^50 for (int i = 1; i < 50; ++i) { t1 = t1.square(); } // 2^100 - 2^0 t1 = t1.multiply(t0); // 2^101 - 2^1 t2 = t1.square(); // 2^200 - 2^100 for (int i = 1; i < 100; ++i) { t2 = t2.square(); } // 2^200 - 2^0 t1 = t2.multiply(t1); // 2^201 - 2^1 t1 = t1.square(); // 2^250 - 2^50 for (int i = 1; i < 50; ++i) { t1 = t1.square(); } // 2^250 - 2^0 t0 = t1.multiply(t0); // 2^251 - 2^1 t0 = t0.square(); // 2^252 - 2^2 t0 = t0.square(); // 2^252 - 3 return multiply(t0); } /** * Constant-time conditional move. Well, actually it is a conditional copy. * Logic is inspired by the SUPERCOP implementation at: * https://github.com/floodyberry/supercop/blob/master/crypto_sign/ed25519/ref10/fe_cmov.c * * @param val the other field element. * @param b must be 0 or 1, otherwise results are undefined. * @return a copy of this if $b == 0$, or a copy of val if $b == 1$. */ @Override public FieldElement cmov(FieldElement val, int b) { Ed25519FieldElement that = (Ed25519FieldElement) val; b = -b; int[] result = new int[10]; for (int i = 0; i < 10; i++) { result[i] = this.t[i]; int x = this.t[i] ^ that.t[i]; x &= b; result[i] ^= x; } return new Ed25519FieldElement(this.f, result); } @Override public int hashCode() { return Arrays.hashCode(t); } @Override public boolean equals(Object obj) { if (!(obj instanceof Ed25519FieldElement)) return false; Ed25519FieldElement fe = (Ed25519FieldElement) obj; return 1==Utils.equal(toByteArray(), fe.toByteArray()); } @Override public String toString() { return "[Ed25519FieldElement val="+Utils.bytesToHex(toByteArray())+"]"; } } ed25519-1.2.4/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/ed25519/Ed25519ScalarOps.java0000644000004100000410000006356613260523700027013 0ustar www-datawww-data/** * EdDSA-Java by str4d * * To the extent possible under law, the person who associated CC0 with * EdDSA-Java has waived all copyright and related or neighboring rights * to EdDSA-Java. * * You should have received a copy of the CC0 legalcode along with this * work. If not, see . * */ package net.i2p.crypto.eddsa.math.ed25519; import net.i2p.crypto.eddsa.math.ScalarOps; import static net.i2p.crypto.eddsa.math.ed25519.Ed25519LittleEndianEncoding.load_3; import static net.i2p.crypto.eddsa.math.ed25519.Ed25519LittleEndianEncoding.load_4; /** * Class for reducing a huge integer modulo the group order q and * doing a combined multiply plus add plus reduce operation. *

* $q = 2^{252} + 27742317777372353535851937790883648493$. *

* Reviewed/commented by Bloody Rookie (nemproject@gmx.de) */ public class Ed25519ScalarOps implements ScalarOps { /** * Reduction modulo the group order $q$. *

* Input: * $s[0]+256*s[1]+\dots+256^{63}*s[63] = s$ *

* Output: * $s[0]+256*s[1]+\dots+256^{31}*s[31] = s \bmod q$ * where $q = 2^{252} + 27742317777372353535851937790883648493$. */ public byte[] reduce(byte[] s) { // s0,..., s22 have 21 bits, s23 has 29 bits long s0 = 0x1FFFFF & load_3(s, 0); long s1 = 0x1FFFFF & (load_4(s, 2) >> 5); long s2 = 0x1FFFFF & (load_3(s, 5) >> 2); long s3 = 0x1FFFFF & (load_4(s, 7) >> 7); long s4 = 0x1FFFFF & (load_4(s, 10) >> 4); long s5 = 0x1FFFFF & (load_3(s, 13) >> 1); long s6 = 0x1FFFFF & (load_4(s, 15) >> 6); long s7 = 0x1FFFFF & (load_3(s, 18) >> 3); long s8 = 0x1FFFFF & load_3(s, 21); long s9 = 0x1FFFFF & (load_4(s, 23) >> 5); long s10 = 0x1FFFFF & (load_3(s, 26) >> 2); long s11 = 0x1FFFFF & (load_4(s, 28) >> 7); long s12 = 0x1FFFFF & (load_4(s, 31) >> 4); long s13 = 0x1FFFFF & (load_3(s, 34) >> 1); long s14 = 0x1FFFFF & (load_4(s, 36) >> 6); long s15 = 0x1FFFFF & (load_3(s, 39) >> 3); long s16 = 0x1FFFFF & load_3(s, 42); long s17 = 0x1FFFFF & (load_4(s, 44) >> 5); long s18 = 0x1FFFFF & (load_3(s, 47) >> 2); long s19 = 0x1FFFFF & (load_4(s, 49) >> 7); long s20 = 0x1FFFFF & (load_4(s, 52) >> 4); long s21 = 0x1FFFFF & (load_3(s, 55) >> 1); long s22 = 0x1FFFFF & (load_4(s, 57) >> 6); long s23 = (load_4(s, 60) >> 3); long carry0; long carry1; long carry2; long carry3; long carry4; long carry5; long carry6; long carry7; long carry8; long carry9; long carry10; long carry11; long carry12; long carry13; long carry14; long carry15; long carry16; /** * Lots of magic numbers :) * To understand what's going on below, note that * * (1) q = 2^252 + q0 where q0 = 27742317777372353535851937790883648493. * (2) s11 is the coefficient of 2^(11*21), s23 is the coefficient of 2^(^23*21) and 2^252 = 2^((23-11) * 21)). * (3) 2^252 congruent -q0 modulo q. * (4) -q0 = 666643 * 2^0 + 470296 * 2^21 + 654183 * 2^(2*21) - 997805 * 2^(3*21) + 136657 * 2^(4*21) - 683901 * 2^(5*21) * * Thus * s23 * 2^(23*11) = s23 * 2^(12*21) * 2^(11*21) = s3 * 2^252 * 2^(11*21) congruent * s23 * (666643 * 2^0 + 470296 * 2^21 + 654183 * 2^(2*21) - 997805 * 2^(3*21) + 136657 * 2^(4*21) - 683901 * 2^(5*21)) * 2^(11*21) modulo q = * s23 * (666643 * 2^(11*21) + 470296 * 2^(12*21) + 654183 * 2^(13*21) - 997805 * 2^(14*21) + 136657 * 2^(15*21) - 683901 * 2^(16*21)). * * The same procedure is then applied for s22,...,s18. */ s11 += s23 * 666643; s12 += s23 * 470296; s13 += s23 * 654183; s14 -= s23 * 997805; s15 += s23 * 136657; s16 -= s23 * 683901; // not used again //s23 = 0; s10 += s22 * 666643; s11 += s22 * 470296; s12 += s22 * 654183; s13 -= s22 * 997805; s14 += s22 * 136657; s15 -= s22 * 683901; // not used again //s22 = 0; s9 += s21 * 666643; s10 += s21 * 470296; s11 += s21 * 654183; s12 -= s21 * 997805; s13 += s21 * 136657; s14 -= s21 * 683901; // not used again //s21 = 0; s8 += s20 * 666643; s9 += s20 * 470296; s10 += s20 * 654183; s11 -= s20 * 997805; s12 += s20 * 136657; s13 -= s20 * 683901; // not used again //s20 = 0; s7 += s19 * 666643; s8 += s19 * 470296; s9 += s19 * 654183; s10 -= s19 * 997805; s11 += s19 * 136657; s12 -= s19 * 683901; // not used again //s19 = 0; s6 += s18 * 666643; s7 += s18 * 470296; s8 += s18 * 654183; s9 -= s18 * 997805; s10 += s18 * 136657; s11 -= s18 * 683901; // not used again //s18 = 0; /** * Time to reduce the coefficient in order not to get an overflow. */ carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21; carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21; carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21; carry12 = (s12 + (1<<20)) >> 21; s13 += carry12; s12 -= carry12 << 21; carry14 = (s14 + (1<<20)) >> 21; s15 += carry14; s14 -= carry14 << 21; carry16 = (s16 + (1<<20)) >> 21; s17 += carry16; s16 -= carry16 << 21; carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21; carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21; carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21; carry13 = (s13 + (1<<20)) >> 21; s14 += carry13; s13 -= carry13 << 21; carry15 = (s15 + (1<<20)) >> 21; s16 += carry15; s15 -= carry15 << 21; /** * Continue with above procedure. */ s5 += s17 * 666643; s6 += s17 * 470296; s7 += s17 * 654183; s8 -= s17 * 997805; s9 += s17 * 136657; s10 -= s17 * 683901; // not used again //s17 = 0; s4 += s16 * 666643; s5 += s16 * 470296; s6 += s16 * 654183; s7 -= s16 * 997805; s8 += s16 * 136657; s9 -= s16 * 683901; // not used again //s16 = 0; s3 += s15 * 666643; s4 += s15 * 470296; s5 += s15 * 654183; s6 -= s15 * 997805; s7 += s15 * 136657; s8 -= s15 * 683901; // not used again //s15 = 0; s2 += s14 * 666643; s3 += s14 * 470296; s4 += s14 * 654183; s5 -= s14 * 997805; s6 += s14 * 136657; s7 -= s14 * 683901; // not used again //s14 = 0; s1 += s13 * 666643; s2 += s13 * 470296; s3 += s13 * 654183; s4 -= s13 * 997805; s5 += s13 * 136657; s6 -= s13 * 683901; // not used again //s13 = 0; s0 += s12 * 666643; s1 += s12 * 470296; s2 += s12 * 654183; s3 -= s12 * 997805; s4 += s12 * 136657; s5 -= s12 * 683901; // set below //s12 = 0; /** * Reduce coefficients again. */ carry0 = (s0 + (1<<20)) >> 21; s1 += carry0; s0 -= carry0 << 21; carry2 = (s2 + (1<<20)) >> 21; s3 += carry2; s2 -= carry2 << 21; carry4 = (s4 + (1<<20)) >> 21; s5 += carry4; s4 -= carry4 << 21; carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21; carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21; carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21; carry1 = (s1 + (1<<20)) >> 21; s2 += carry1; s1 -= carry1 << 21; carry3 = (s3 + (1<<20)) >> 21; s4 += carry3; s3 -= carry3 << 21; carry5 = (s5 + (1<<20)) >> 21; s6 += carry5; s5 -= carry5 << 21; carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21; carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21; //carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21; carry11 = (s11 + (1<<20)) >> 21; s12 = carry11; s11 -= carry11 << 21; s0 += s12 * 666643; s1 += s12 * 470296; s2 += s12 * 654183; s3 -= s12 * 997805; s4 += s12 * 136657; s5 -= s12 * 683901; // set below //s12 = 0; carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21; carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21; carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21; carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21; carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21; carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21; //carry11 = s11 >> 21; s12 += carry11; s11 -= carry11 << 21; carry11 = s11 >> 21; s12 = carry11; s11 -= carry11 << 21; // TODO-CR BR: Is it really needed to do it TWO times? (it doesn't hurt, just a question). s0 += s12 * 666643; s1 += s12 * 470296; s2 += s12 * 654183; s3 -= s12 * 997805; s4 += s12 * 136657; s5 -= s12 * 683901; // not used again //s12 = 0; carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21; carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21; carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21; carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21; carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21; carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21; // s0, ..., s11 got 21 bits each. byte[] result = new byte[32]; result[0] = (byte) s0; result[1] = (byte) (s0 >> 8); result[2] = (byte) ((s0 >> 16) | (s1 << 5)); result[3] = (byte) (s1 >> 3); result[4] = (byte) (s1 >> 11); result[5] = (byte) ((s1 >> 19) | (s2 << 2)); result[6] = (byte) (s2 >> 6); result[7] = (byte) ((s2 >> 14) | (s3 << 7)); result[8] = (byte) (s3 >> 1); result[9] = (byte) (s3 >> 9); result[10] = (byte) ((s3 >> 17) | (s4 << 4)); result[11] = (byte) (s4 >> 4); result[12] = (byte) (s4 >> 12); result[13] = (byte) ((s4 >> 20) | (s5 << 1)); result[14] = (byte) (s5 >> 7); result[15] = (byte) ((s5 >> 15) | (s6 << 6)); result[16] = (byte) (s6 >> 2); result[17] = (byte) (s6 >> 10); result[18] = (byte) ((s6 >> 18) | (s7 << 3)); result[19] = (byte) (s7 >> 5); result[20] = (byte) (s7 >> 13); result[21] = (byte) s8; result[22] = (byte) (s8 >> 8); result[23] = (byte) ((s8 >> 16) | (s9 << 5)); result[24] = (byte) (s9 >> 3); result[25] = (byte) (s9 >> 11); result[26] = (byte) ((s9 >> 19) | (s10 << 2)); result[27] = (byte) (s10 >> 6); result[28] = (byte) ((s10 >> 14) | (s11 << 7)); result[29] = (byte) (s11 >> 1); result[30] = (byte) (s11 >> 9); result[31] = (byte) (s11 >> 17); return result; } /** * $(ab+c) \bmod q$ *

* Input: *

    *
  • $a[0]+256*a[1]+\dots+256^{31}*a[31] = a$ *
  • $b[0]+256*b[1]+\dots+256^{31}*b[31] = b$ *
  • $c[0]+256*c[1]+\dots+256^{31}*c[31] = c$ *

* Output: * $result[0]+256*result[1]+\dots+256^{31}*result[31] = (ab+c) \bmod q$ * where $q = 2^{252} + 27742317777372353535851937790883648493$. *

* See the comments in {@link #reduce(byte[])} for an explanation of the algorithm. */ public byte[] multiplyAndAdd(byte[] a, byte[] b, byte[] c) { long a0 = 0x1FFFFF & load_3(a, 0); long a1 = 0x1FFFFF & (load_4(a, 2) >> 5); long a2 = 0x1FFFFF & (load_3(a, 5) >> 2); long a3 = 0x1FFFFF & (load_4(a, 7) >> 7); long a4 = 0x1FFFFF & (load_4(a, 10) >> 4); long a5 = 0x1FFFFF & (load_3(a, 13) >> 1); long a6 = 0x1FFFFF & (load_4(a, 15) >> 6); long a7 = 0x1FFFFF & (load_3(a, 18) >> 3); long a8 = 0x1FFFFF & load_3(a, 21); long a9 = 0x1FFFFF & (load_4(a, 23) >> 5); long a10 = 0x1FFFFF & (load_3(a, 26) >> 2); long a11 = (load_4(a, 28) >> 7); long b0 = 0x1FFFFF & load_3(b, 0); long b1 = 0x1FFFFF & (load_4(b, 2) >> 5); long b2 = 0x1FFFFF & (load_3(b, 5) >> 2); long b3 = 0x1FFFFF & (load_4(b, 7) >> 7); long b4 = 0x1FFFFF & (load_4(b, 10) >> 4); long b5 = 0x1FFFFF & (load_3(b, 13) >> 1); long b6 = 0x1FFFFF & (load_4(b, 15) >> 6); long b7 = 0x1FFFFF & (load_3(b, 18) >> 3); long b8 = 0x1FFFFF & load_3(b, 21); long b9 = 0x1FFFFF & (load_4(b, 23) >> 5); long b10 = 0x1FFFFF & (load_3(b, 26) >> 2); long b11 = (load_4(b, 28) >> 7); long c0 = 0x1FFFFF & load_3(c, 0); long c1 = 0x1FFFFF & (load_4(c, 2) >> 5); long c2 = 0x1FFFFF & (load_3(c, 5) >> 2); long c3 = 0x1FFFFF & (load_4(c, 7) >> 7); long c4 = 0x1FFFFF & (load_4(c, 10) >> 4); long c5 = 0x1FFFFF & (load_3(c, 13) >> 1); long c6 = 0x1FFFFF & (load_4(c, 15) >> 6); long c7 = 0x1FFFFF & (load_3(c, 18) >> 3); long c8 = 0x1FFFFF & load_3(c, 21); long c9 = 0x1FFFFF & (load_4(c, 23) >> 5); long c10 = 0x1FFFFF & (load_3(c, 26) >> 2); long c11 = (load_4(c, 28) >> 7); long s0; long s1; long s2; long s3; long s4; long s5; long s6; long s7; long s8; long s9; long s10; long s11; long s12; long s13; long s14; long s15; long s16; long s17; long s18; long s19; long s20; long s21; long s22; long s23; long carry0; long carry1; long carry2; long carry3; long carry4; long carry5; long carry6; long carry7; long carry8; long carry9; long carry10; long carry11; long carry12; long carry13; long carry14; long carry15; long carry16; long carry17; long carry18; long carry19; long carry20; long carry21; long carry22; s0 = c0 + a0*b0; s1 = c1 + a0*b1 + a1*b0; s2 = c2 + a0*b2 + a1*b1 + a2*b0; s3 = c3 + a0*b3 + a1*b2 + a2*b1 + a3*b0; s4 = c4 + a0*b4 + a1*b3 + a2*b2 + a3*b1 + a4*b0; s5 = c5 + a0*b5 + a1*b4 + a2*b3 + a3*b2 + a4*b1 + a5*b0; s6 = c6 + a0*b6 + a1*b5 + a2*b4 + a3*b3 + a4*b2 + a5*b1 + a6*b0; s7 = c7 + a0*b7 + a1*b6 + a2*b5 + a3*b4 + a4*b3 + a5*b2 + a6*b1 + a7*b0; s8 = c8 + a0*b8 + a1*b7 + a2*b6 + a3*b5 + a4*b4 + a5*b3 + a6*b2 + a7*b1 + a8*b0; s9 = c9 + a0*b9 + a1*b8 + a2*b7 + a3*b6 + a4*b5 + a5*b4 + a6*b3 + a7*b2 + a8*b1 + a9*b0; s10 = c10 + a0*b10 + a1*b9 + a2*b8 + a3*b7 + a4*b6 + a5*b5 + a6*b4 + a7*b3 + a8*b2 + a9*b1 + a10*b0; s11 = c11 + a0*b11 + a1*b10 + a2*b9 + a3*b8 + a4*b7 + a5*b6 + a6*b5 + a7*b4 + a8*b3 + a9*b2 + a10*b1 + a11*b0; s12 = a1*b11 + a2*b10 + a3*b9 + a4*b8 + a5*b7 + a6*b6 + a7*b5 + a8*b4 + a9*b3 + a10*b2 + a11*b1; s13 = a2*b11 + a3*b10 + a4*b9 + a5*b8 + a6*b7 + a7*b6 + a8*b5 + a9*b4 + a10*b3 + a11*b2; s14 = a3*b11 + a4*b10 + a5*b9 + a6*b8 + a7*b7 + a8*b6 + a9*b5 + a10*b4 + a11*b3; s15 = a4*b11 + a5*b10 + a6*b9 + a7*b8 + a8*b7 + a9*b6 + a10*b5 + a11*b4; s16 = a5*b11 + a6*b10 + a7*b9 + a8*b8 + a9*b7 + a10*b6 + a11*b5; s17 = a6*b11 + a7*b10 + a8*b9 + a9*b8 + a10*b7 + a11*b6; s18 = a7*b11 + a8*b10 + a9*b9 + a10*b8 + a11*b7; s19 = a8*b11 + a9*b10 + a10*b9 + a11*b8; s20 = a9*b11 + a10*b10 + a11*b9; s21 = a10*b11 + a11*b10; s22 = a11*b11; // set below //s23 = 0; carry0 = (s0 + (1<<20)) >> 21; s1 += carry0; s0 -= carry0 << 21; carry2 = (s2 + (1<<20)) >> 21; s3 += carry2; s2 -= carry2 << 21; carry4 = (s4 + (1<<20)) >> 21; s5 += carry4; s4 -= carry4 << 21; carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21; carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21; carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21; carry12 = (s12 + (1<<20)) >> 21; s13 += carry12; s12 -= carry12 << 21; carry14 = (s14 + (1<<20)) >> 21; s15 += carry14; s14 -= carry14 << 21; carry16 = (s16 + (1<<20)) >> 21; s17 += carry16; s16 -= carry16 << 21; carry18 = (s18 + (1<<20)) >> 21; s19 += carry18; s18 -= carry18 << 21; carry20 = (s20 + (1<<20)) >> 21; s21 += carry20; s20 -= carry20 << 21; //carry22 = (s22 + (1<<20)) >> 21; s23 += carry22; s22 -= carry22 << 21; carry22 = (s22 + (1<<20)) >> 21; s23 = carry22; s22 -= carry22 << 21; carry1 = (s1 + (1<<20)) >> 21; s2 += carry1; s1 -= carry1 << 21; carry3 = (s3 + (1<<20)) >> 21; s4 += carry3; s3 -= carry3 << 21; carry5 = (s5 + (1<<20)) >> 21; s6 += carry5; s5 -= carry5 << 21; carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21; carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21; carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21; carry13 = (s13 + (1<<20)) >> 21; s14 += carry13; s13 -= carry13 << 21; carry15 = (s15 + (1<<20)) >> 21; s16 += carry15; s15 -= carry15 << 21; carry17 = (s17 + (1<<20)) >> 21; s18 += carry17; s17 -= carry17 << 21; carry19 = (s19 + (1<<20)) >> 21; s20 += carry19; s19 -= carry19 << 21; carry21 = (s21 + (1<<20)) >> 21; s22 += carry21; s21 -= carry21 << 21; s11 += s23 * 666643; s12 += s23 * 470296; s13 += s23 * 654183; s14 -= s23 * 997805; s15 += s23 * 136657; s16 -= s23 * 683901; // not used again //s23 = 0; s10 += s22 * 666643; s11 += s22 * 470296; s12 += s22 * 654183; s13 -= s22 * 997805; s14 += s22 * 136657; s15 -= s22 * 683901; // not used again //s22 = 0; s9 += s21 * 666643; s10 += s21 * 470296; s11 += s21 * 654183; s12 -= s21 * 997805; s13 += s21 * 136657; s14 -= s21 * 683901; // not used again //s21 = 0; s8 += s20 * 666643; s9 += s20 * 470296; s10 += s20 * 654183; s11 -= s20 * 997805; s12 += s20 * 136657; s13 -= s20 * 683901; // not used again //s20 = 0; s7 += s19 * 666643; s8 += s19 * 470296; s9 += s19 * 654183; s10 -= s19 * 997805; s11 += s19 * 136657; s12 -= s19 * 683901; // not used again //s19 = 0; s6 += s18 * 666643; s7 += s18 * 470296; s8 += s18 * 654183; s9 -= s18 * 997805; s10 += s18 * 136657; s11 -= s18 * 683901; // not used again //s18 = 0; carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21; carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21; carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21; carry12 = (s12 + (1<<20)) >> 21; s13 += carry12; s12 -= carry12 << 21; carry14 = (s14 + (1<<20)) >> 21; s15 += carry14; s14 -= carry14 << 21; carry16 = (s16 + (1<<20)) >> 21; s17 += carry16; s16 -= carry16 << 21; carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21; carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21; carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21; carry13 = (s13 + (1<<20)) >> 21; s14 += carry13; s13 -= carry13 << 21; carry15 = (s15 + (1<<20)) >> 21; s16 += carry15; s15 -= carry15 << 21; s5 += s17 * 666643; s6 += s17 * 470296; s7 += s17 * 654183; s8 -= s17 * 997805; s9 += s17 * 136657; s10 -= s17 * 683901; // not used again //s17 = 0; s4 += s16 * 666643; s5 += s16 * 470296; s6 += s16 * 654183; s7 -= s16 * 997805; s8 += s16 * 136657; s9 -= s16 * 683901; // not used again //s16 = 0; s3 += s15 * 666643; s4 += s15 * 470296; s5 += s15 * 654183; s6 -= s15 * 997805; s7 += s15 * 136657; s8 -= s15 * 683901; // not used again //s15 = 0; s2 += s14 * 666643; s3 += s14 * 470296; s4 += s14 * 654183; s5 -= s14 * 997805; s6 += s14 * 136657; s7 -= s14 * 683901; // not used again //s14 = 0; s1 += s13 * 666643; s2 += s13 * 470296; s3 += s13 * 654183; s4 -= s13 * 997805; s5 += s13 * 136657; s6 -= s13 * 683901; // not used again //s13 = 0; s0 += s12 * 666643; s1 += s12 * 470296; s2 += s12 * 654183; s3 -= s12 * 997805; s4 += s12 * 136657; s5 -= s12 * 683901; // set below //s12 = 0; carry0 = (s0 + (1<<20)) >> 21; s1 += carry0; s0 -= carry0 << 21; carry2 = (s2 + (1<<20)) >> 21; s3 += carry2; s2 -= carry2 << 21; carry4 = (s4 + (1<<20)) >> 21; s5 += carry4; s4 -= carry4 << 21; carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21; carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21; carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21; carry1 = (s1 + (1<<20)) >> 21; s2 += carry1; s1 -= carry1 << 21; carry3 = (s3 + (1<<20)) >> 21; s4 += carry3; s3 -= carry3 << 21; carry5 = (s5 + (1<<20)) >> 21; s6 += carry5; s5 -= carry5 << 21; carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21; carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21; //carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21; carry11 = (s11 + (1<<20)) >> 21; s12 = carry11; s11 -= carry11 << 21; s0 += s12 * 666643; s1 += s12 * 470296; s2 += s12 * 654183; s3 -= s12 * 997805; s4 += s12 * 136657; s5 -= s12 * 683901; // set below //s12 = 0; carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21; carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21; carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21; carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21; carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21; carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21; //carry11 = s11 >> 21; s12 += carry11; s11 -= carry11 << 21; carry11 = s11 >> 21; s12 = carry11; s11 -= carry11 << 21; s0 += s12 * 666643; s1 += s12 * 470296; s2 += s12 * 654183; s3 -= s12 * 997805; s4 += s12 * 136657; s5 -= s12 * 683901; // not used again //s12 = 0; carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21; carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21; carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21; carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21; carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21; carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21; byte[] result = new byte[32]; result[0] = (byte) s0; result[1] = (byte) (s0 >> 8); result[2] = (byte) ((s0 >> 16) | (s1 << 5)); result[3] = (byte) (s1 >> 3); result[4] = (byte) (s1 >> 11); result[5] = (byte) ((s1 >> 19) | (s2 << 2)); result[6] = (byte) (s2 >> 6); result[7] = (byte) ((s2 >> 14) | (s3 << 7)); result[8] = (byte) (s3 >> 1); result[9] = (byte) (s3 >> 9); result[10] = (byte) ((s3 >> 17) | (s4 << 4)); result[11] = (byte) (s4 >> 4); result[12] = (byte) (s4 >> 12); result[13] = (byte) ((s4 >> 20) | (s5 << 1)); result[14] = (byte) (s5 >> 7); result[15] = (byte) ((s5 >> 15) | (s6 << 6)); result[16] = (byte) (s6 >> 2); result[17] = (byte) (s6 >> 10); result[18] = (byte) ((s6 >> 18) | (s7 << 3)); result[19] = (byte) (s7 >> 5); result[20] = (byte) (s7 >> 13); result[21] = (byte) s8; result[22] = (byte) (s8 >> 8); result[23] = (byte) ((s8 >> 16) | (s9 << 5)); result[24] = (byte) (s9 >> 3); result[25] = (byte) (s9 >> 11); result[26] = (byte) ((s9 >> 19) | (s10 << 2)); result[27] = (byte) (s10 >> 6); result[28] = (byte) ((s10 >> 14) | (s11 << 7)); result[29] = (byte) (s11 >> 1); result[30] = (byte) (s11 >> 9); result[31] = (byte) (s11 >> 17); return result; } } ed25519-1.2.4/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/FieldElement.java0000644000004100000410000000367113260523700025573 0ustar www-datawww-data/** * EdDSA-Java by str4d * * To the extent possible under law, the person who associated CC0 with * EdDSA-Java has waived all copyright and related or neighboring rights * to EdDSA-Java. * * You should have received a copy of the CC0 legalcode along with this * work. If not, see . * */ package net.i2p.crypto.eddsa.math; import java.io.Serializable; /** * Note: concrete subclasses must implement hashCode() and equals() */ public abstract class FieldElement implements Serializable { private static final long serialVersionUID = 1239527465875676L; protected final Field f; public FieldElement(Field f) { if (null == f) { throw new IllegalArgumentException("field cannot be null"); } this.f = f; } /** * Encode a FieldElement in its $(b-1)$-bit encoding. * @return the $(b-1)$-bit encoding of this FieldElement. */ public byte[] toByteArray() { return f.getEncoding().encode(this); } public abstract boolean isNonZero(); public boolean isNegative() { return f.getEncoding().isNegative(this); } public abstract FieldElement add(FieldElement val); public FieldElement addOne() { return add(f.ONE); } public abstract FieldElement subtract(FieldElement val); public FieldElement subtractOne() { return subtract(f.ONE); } public abstract FieldElement negate(); public FieldElement divide(FieldElement val) { return multiply(val.invert()); } public abstract FieldElement multiply(FieldElement val); public abstract FieldElement square(); public abstract FieldElement squareAndDouble(); public abstract FieldElement invert(); public abstract FieldElement pow22523(); public abstract FieldElement cmov(FieldElement val, final int b); // Note: concrete subclasses must implement hashCode() and equals() } ed25519-1.2.4/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/GroupElement.java0000644000004100000410000010676713260523700025656 0ustar www-datawww-data/** * EdDSA-Java by str4d * * To the extent possible under law, the person who associated CC0 with * EdDSA-Java has waived all copyright and related or neighboring rights * to EdDSA-Java. * * You should have received a copy of the CC0 legalcode along with this * work. If not, see . * */ package net.i2p.crypto.eddsa.math; import net.i2p.crypto.eddsa.Utils; import java.io.Serializable; import java.util.Arrays; /** * A point $(x,y)$ on an EdDSA curve. *

* Reviewed/commented by Bloody Rookie (nemproject@gmx.de) *

* Literature:
* [1] Daniel J. Bernstein, Niels Duif, Tanja Lange, Peter Schwabe and Bo-Yin Yang : High-speed high-security signatures
* [2] Huseyin Hisil, Kenneth Koon-Ho Wong, Gary Carter, Ed Dawson: Twisted Edwards Curves Revisited
* [3] Daniel J. Bernsteina, Tanja Lange: A complete set of addition laws for incomplete Edwards curves
* [4] Daniel J. Bernstein, Peter Birkner, Marc Joye, Tanja Lange and Christiane Peters: Twisted Edwards Curves
* [5] Christiane Pascale Peters: Curves, Codes, and Cryptography (PhD thesis)
* [6] Daniel J. Bernstein, Peter Birkner, Tanja Lange and Christiane Peters: Optimizing double-base elliptic-curve single-scalar multiplication
* * @author str4d */ public class GroupElement implements Serializable { private static final long serialVersionUID = 2395879087349587L; /** * Available representations for a group element. *

    *
  • P2: Projective representation $(X:Y:Z)$ satisfying $x=X/Z, y=Y/Z$. *
  • P3: Extended projective representation $(X:Y:Z:T)$ satisfying $x=X/Z, y=Y/Z, XY=ZT$. *
  • P1P1: Completed representation $((X:Z), (Y:T))$ satisfying $x=X/Z, y=Y/T$. *
  • PRECOMP: Precomputed representation $(y+x, y-x, 2dxy)$. *
  • CACHED: Cached representation $(Y+X, Y-X, Z, 2dT)$ *
*/ public enum Representation { /** Projective ($P^2$): $(X:Y:Z)$ satisfying $x=X/Z, y=Y/Z$ */ P2, /** Extended ($P^3$): $(X:Y:Z:T)$ satisfying $x=X/Z, y=Y/Z, XY=ZT$ */ P3, /** Completed ($P \times P$): $((X:Z),(Y:T))$ satisfying $x=X/Z, y=Y/T$ */ P1P1, /** Precomputed (Duif): $(y+x,y-x,2dxy)$ */ PRECOMP, /** Cached: $(Y+X,Y-X,Z,2dT)$ */ CACHED } /** * Creates a new group element in P2 representation. * * @param curve The curve. * @param X The $X$ coordinate. * @param Y The $Y$ coordinate. * @param Z The $Z$ coordinate. * @return The group element in P2 representation. */ public static GroupElement p2( final Curve curve, final FieldElement X, final FieldElement Y, final FieldElement Z) { return new GroupElement(curve, Representation.P2, X, Y, Z, null); } /** * Creates a new group element in P3 representation. * * @param curve The curve. * @param X The $X$ coordinate. * @param Y The $Y$ coordinate. * @param Z The $Z$ coordinate. * @param T The $T$ coordinate. * @return The group element in P3 representation. */ public static GroupElement p3( final Curve curve, final FieldElement X, final FieldElement Y, final FieldElement Z, final FieldElement T) { return new GroupElement(curve, Representation.P3, X, Y, Z, T); } /** * Creates a new group element in P1P1 representation. * * @param curve The curve. * @param X The $X$ coordinate. * @param Y The $Y$ coordinate. * @param Z The $Z$ coordinate. * @param T The $T$ coordinate. * @return The group element in P1P1 representation. */ public static GroupElement p1p1( final Curve curve, final FieldElement X, final FieldElement Y, final FieldElement Z, final FieldElement T) { return new GroupElement(curve, Representation.P1P1, X, Y, Z, T); } /** * Creates a new group element in PRECOMP representation. * * @param curve The curve. * @param ypx The $y + x$ value. * @param ymx The $y - x$ value. * @param xy2d The $2 * d * x * y$ value. * @return The group element in PRECOMP representation. */ public static GroupElement precomp( final Curve curve, final FieldElement ypx, final FieldElement ymx, final FieldElement xy2d) { return new GroupElement(curve, Representation.PRECOMP, ypx, ymx, xy2d, null); } /** * Creates a new group element in CACHED representation. * * @param curve The curve. * @param YpX The $Y + X$ value. * @param YmX The $Y - X$ value. * @param Z The $Z$ coordinate. * @param T2d The $2 * d * T$ value. * @return The group element in CACHED representation. */ public static GroupElement cached( final Curve curve, final FieldElement YpX, final FieldElement YmX, final FieldElement Z, final FieldElement T2d) { return new GroupElement(curve, Representation.CACHED, YpX, YmX, Z, T2d); } /** * Variable is package private only so that tests run. */ final Curve curve; /** * Variable is package private only so that tests run. */ final Representation repr; /** * Variable is package private only so that tests run. */ final FieldElement X; /** * Variable is package private only so that tests run. */ final FieldElement Y; /** * Variable is package private only so that tests run. */ final FieldElement Z; /** * Variable is package private only so that tests run. */ final FieldElement T; /** * Precomputed table for {@link #scalarMultiply(byte[])}, * filled if necessary. *

* Variable is package private only so that tests run. */ GroupElement[][] precmp; /** * Precomputed table for {@link #doubleScalarMultiplyVariableTime(GroupElement, byte[], byte[])}, * filled if necessary. *

* Variable is package private only so that tests run. */ GroupElement[] dblPrecmp; /** * Creates a group element for a curve. * * @param curve The curve. * @param repr The representation used to represent the group element. * @param X The $X$ coordinate. * @param Y The $Y$ coordinate. * @param Z The $Z$ coordinate. * @param T The $T$ coordinate. */ public GroupElement( final Curve curve, final Representation repr, final FieldElement X, final FieldElement Y, final FieldElement Z, final FieldElement T) { this.curve = curve; this.repr = repr; this.X = X; this.Y = Y; this.Z = Z; this.T = T; } /** * Creates a group element for a curve from a given encoded point. *

* A point $(x,y)$ is encoded by storing $y$ in bit 0 to bit 254 and the sign of $x$ in bit 255. * $x$ is recovered in the following way: *

    *
  • $x = sign(x) * \sqrt{(y^2 - 1) / (d * y^2 + 1)} = sign(x) * \sqrt{u / v}$ with $u = y^2 - 1$ and $v = d * y^2 + 1$. *
  • Setting $β = (u * v^3) * (u * v^7)^{((q - 5) / 8)}$ one has $β^2 = \pm(u / v)$. *
  • If $v * β = -u$ multiply $β$ with $i=\sqrt{-1}$. *
  • Set $x := β$. *
  • If $sign(x) \ne$ bit 255 of $s$ then negate $x$. *
* * @param curve The curve. * @param s The encoded point. */ public GroupElement(final Curve curve, final byte[] s) { FieldElement x, y, yy, u, v, v3, vxx, check; y = curve.getField().fromByteArray(s); yy = y.square(); // u = y^2-1 u = yy.subtractOne(); // v = dy^2+1 v = yy.multiply(curve.getD()).addOne(); // v3 = v^3 v3 = v.square().multiply(v); // x = (v3^2)vu, aka x = uv^7 x = v3.square().multiply(v).multiply(u); // x = (uv^7)^((q-5)/8) x = x.pow22523(); // x = uv^3(uv^7)^((q-5)/8) x = v3.multiply(u).multiply(x); vxx = x.square().multiply(v); check = vxx.subtract(u); // vx^2-u if (check.isNonZero()) { check = vxx.add(u); // vx^2+u if (check.isNonZero()) throw new IllegalArgumentException("not a valid GroupElement"); x = x.multiply(curve.getI()); } if ((x.isNegative() ? 1 : 0) != Utils.bit(s, curve.getField().getb()-1)) { x = x.negate(); } this.curve = curve; this.repr = Representation.P3; this.X = x; this.Y = y; this.Z = curve.getField().ONE; this.T = this.X.multiply(this.Y); } /** * Gets the curve of the group element. * * @return The curve. */ public Curve getCurve() { return this.curve; } /** * Gets the representation of the group element. * * @return The representation. */ public Representation getRepresentation() { return this.repr; } /** * Gets the $X$ value of the group element. * This is for most representation the projective $X$ coordinate. * * @return The $X$ value. */ public FieldElement getX() { return this.X; } /** * Gets the $Y$ value of the group element. * This is for most representation the projective $Y$ coordinate. * * @return The $Y$ value. */ public FieldElement getY() { return this.Y; } /** * Gets the $Z$ value of the group element. * This is for most representation the projective $Z$ coordinate. * * @return The $Z$ value. */ public FieldElement getZ() { return this.Z; } /** * Gets the $T$ value of the group element. * This is for most representation the projective $T$ coordinate. * * @return The $T$ value. */ public FieldElement getT() { return this.T; } /** * Converts the group element to an encoded point on the curve. * * @return The encoded point as byte array. */ public byte[] toByteArray() { switch (this.repr) { case P2: case P3: FieldElement recip = Z.invert(); FieldElement x = X.multiply(recip); FieldElement y = Y.multiply(recip); byte[] s = y.toByteArray(); s[s.length-1] |= (x.isNegative() ? (byte) 0x80 : 0); return s; default: return toP2().toByteArray(); } } /** * Converts the group element to the P2 representation. * * @return The group element in the P2 representation. */ public GroupElement toP2() { return toRep(Representation.P2); } /** * Converts the group element to the P3 representation. * * @return The group element in the P3 representation. */ public GroupElement toP3() { return toRep(Representation.P3); } /** * Converts the group element to the CACHED representation. * * @return The group element in the CACHED representation. */ public GroupElement toCached() { return toRep(Representation.CACHED); } /** * Convert a GroupElement from one Representation to another. * TODO-CR: Add additional conversion? * $r = p$ *

* Supported conversions: *

    *
  • P3 $\rightarrow$ P2 *
  • P3 $\rightarrow$ CACHED (1 multiply, 1 add, 1 subtract) *
  • P1P1 $\rightarrow$ P2 (3 multiply) *
  • P1P1 $\rightarrow$ P3 (4 multiply) * * @param repr The representation to convert to. * @return A new group element in the given representation. */ private GroupElement toRep(final Representation repr) { switch (this.repr) { case P2: switch (repr) { case P2: return p2(this.curve, this.X, this.Y, this.Z); default: throw new IllegalArgumentException(); } case P3: switch (repr) { case P2: return p2(this.curve, this.X, this.Y, this.Z); case P3: return p3(this.curve, this.X, this.Y, this.Z, this.T); case CACHED: return cached(this.curve, this.Y.add(this.X), this.Y.subtract(this.X), this.Z, this.T.multiply(this.curve.get2D())); default: throw new IllegalArgumentException(); } case P1P1: switch (repr) { case P2: return p2(this.curve, this.X.multiply(this.T), Y.multiply(this.Z), this.Z.multiply(this.T)); case P3: return p3(this.curve, this.X.multiply(this.T), Y.multiply(this.Z), this.Z.multiply(this.T), this.X.multiply(this.Y)); case P1P1: return p1p1(this.curve, this.X, this.Y, this.Z, this.T); default: throw new IllegalArgumentException(); } case PRECOMP: switch (repr) { case PRECOMP: return precomp(this.curve, this.X, this.Y, this.Z); default: throw new IllegalArgumentException(); } case CACHED: switch (repr) { case CACHED: return cached(this.curve, this.X, this.Y, this.Z, this.T); default: throw new IllegalArgumentException(); } default: throw new UnsupportedOperationException(); } } /** * Precomputes several tables. *

    * The precomputed tables are used for {@link #scalarMultiply(byte[])} * and {@link #doubleScalarMultiplyVariableTime(GroupElement, byte[], byte[])}. * * @param precomputeSingle should the matrix for scalarMultiply() be precomputed? */ public synchronized void precompute(final boolean precomputeSingle) { GroupElement Bi; if (precomputeSingle && this.precmp == null) { // Precomputation for single scalar multiplication. this.precmp = new GroupElement[32][8]; // TODO-CR BR: check that this == base point when the method is called. Bi = this; for (int i = 0; i < 32; i++) { GroupElement Bij = Bi; for (int j = 0; j < 8; j++) { final FieldElement recip = Bij.Z.invert(); final FieldElement x = Bij.X.multiply(recip); final FieldElement y = Bij.Y.multiply(recip); this.precmp[i][j] = precomp(this.curve, y.add(x), y.subtract(x), x.multiply(y).multiply(this.curve.get2D())); Bij = Bij.add(Bi.toCached()).toP3(); } // Only every second summand is precomputed (16^2 = 256) for (int k = 0; k < 8; k++) { Bi = Bi.add(Bi.toCached()).toP3(); } } } // Precomputation for double scalar multiplication. // P,3P,5P,7P,9P,11P,13P,15P if (this.dblPrecmp != null) return; this.dblPrecmp = new GroupElement[8]; Bi = this; for (int i = 0; i < 8; i++) { final FieldElement recip = Bi.Z.invert(); final FieldElement x = Bi.X.multiply(recip); final FieldElement y = Bi.Y.multiply(recip); this.dblPrecmp[i] = precomp(this.curve, y.add(x), y.subtract(x), x.multiply(y).multiply(this.curve.get2D())); // Bi = edwards(B,edwards(B,Bi)) Bi = this.add(this.add(Bi.toCached()).toP3().toCached()).toP3(); } } /** * Doubles a given group element $p$ in $P^2$ or $P^3$ representation and returns the result in $P \times P$ representation. * $r = 2 * p$ where $p = (X : Y : Z)$ or $p = (X : Y : Z : T)$ *

    * $r$ in $P \times P$ representation: *

    * $r = ((X' : Z'), (Y' : T'))$ where *

      *
    • $X' = (X + Y)^2 - (Y^2 + X^2)$ *
    • $Y' = Y^2 + X^2$ *
    • $Z' = y^2 - X^2$ *
    • $T' = 2 * Z^2 - (y^2 - X^2)$ *

    * $r$ converted from $P \times P$ to $P^2$ representation: *

    * $r = (X'' : Y'' : Z'')$ where *

      *
    • $X'' = X' * Z' = ((X + Y)^2 - Y^2 - X^2) * (2 * Z^2 - (y^2 - X^2))$ *
    • $Y'' = Y' * T' = (Y^2 + X^2) * (2 * Z^2 - (y^2 - X^2))$ *
    • $Z'' = Z' * T' = (y^2 - X^2) * (2 * Z^2 - (y^2 - X^2))$ *

    * Formula for the $P^2$ representation is in agreement with the formula given in [4] page 12 (with $a = -1$) * up to a common factor -1 which does not matter: *

    * $$ * B = (X + Y)^2; C = X^2; D = Y^2; E = -C = -X^2; F := E + D = Y^2 - X^2; H = Z^2; J = F − 2 * H; \\ * X3 = (B − C − D) · J = X' * (-T'); \\ * Y3 = F · (E − D) = Z' * (-Y'); \\ * Z3 = F · J = Z' * (-T'). * $$ * * @return The P1P1 representation */ public GroupElement dbl() { switch (this.repr) { case P2: case P3: // Ignore T for P3 representation FieldElement XX, YY, B, A, AA, Yn, Zn; XX = this.X.square(); YY = this.Y.square(); B = this.Z.squareAndDouble(); A = this.X.add(this.Y); AA = A.square(); Yn = YY.add(XX); Zn = YY.subtract(XX); return p1p1(this.curve, AA.subtract(Yn), Yn, Zn, B.subtract(Zn)); default: throw new UnsupportedOperationException(); } } /** * GroupElement addition using the twisted Edwards addition law with * extended coordinates (Hisil2008). *

    * this must be in $P^3$ representation and $q$ in PRECOMP representation. * $r = p + q$ where $p = this = (X1 : Y1 : Z1 : T1), q = (q.X, q.Y, q.Z) = (Y2/Z2 + X2/Z2, Y2/Z2 - X2/Z2, 2 * d * X2/Z2 * Y2/Z2)$ *

    * $r$ in $P \times P$ representation: *

    * $r = ((X' : Z'), (Y' : T'))$ where *

      *
    • $X' = (Y1 + X1) * q.X - (Y1 - X1) * q.Y = ((Y1 + X1) * (Y2 + X2) - (Y1 - X1) * (Y2 - X2)) * 1/Z2$ *
    • $Y' = (Y1 + X1) * q.X + (Y1 - X1) * q.Y = ((Y1 + X1) * (Y2 + X2) + (Y1 - X1) * (Y2 - X2)) * 1/Z2$ *
    • $Z' = 2 * Z1 + T1 * q.Z = 2 * Z1 + T1 * 2 * d * X2 * Y2 * 1/Z2^2 = (2 * Z1 * Z2 + 2 * d * T1 * T2) * 1/Z2$ *
    • $T' = 2 * Z1 - T1 * q.Z = 2 * Z1 - T1 * 2 * d * X2 * Y2 * 1/Z2^2 = (2 * Z1 * Z2 - 2 * d * T1 * T2) * 1/Z2$ *

    * Setting $A = (Y1 - X1) * (Y2 - X2), B = (Y1 + X1) * (Y2 + X2), C = 2 * d * T1 * T2, D = 2 * Z1 * Z2$ we get *

      *
    • $X' = (B - A) * 1/Z2$ *
    • $Y' = (B + A) * 1/Z2$ *
    • $Z' = (D + C) * 1/Z2$ *
    • $T' = (D - C) * 1/Z2$ *

    * $r$ converted from $P \times P$ to $P^2$ representation: *

    * $r = (X'' : Y'' : Z'' : T'')$ where *

      *
    • $X'' = X' * Z' = (B - A) * (D + C) * 1/Z2^2$ *
    • $Y'' = Y' * T' = (B + A) * (D - C) * 1/Z2^2$ *
    • $Z'' = Z' * T' = (D + C) * (D - C) * 1/Z2^2$ *
    • $T'' = X' * Y' = (B - A) * (B + A) * 1/Z2^2$ *

    * TODO-CR BR: Formula for the $P^2$ representation is not in agreement with the formula given in [2] page 6
    * TODO-CR BR: (the common factor $1/Z2^2$ does not matter):
    * $$ * E = B - A, F = D - C, G = D + C, H = B + A \\ * X3 = E * F = (B - A) * (D - C); \\ * Y3 = G * H = (D + C) * (B + A); \\ * Z3 = F * G = (D - C) * (D + C); \\ * T3 = E * H = (B - A) * (B + A); * $$ * * @param q the PRECOMP representation of the GroupElement to add. * @return the P1P1 representation of the result. */ private GroupElement madd(GroupElement q) { if (this.repr != Representation.P3) throw new UnsupportedOperationException(); if (q.repr != Representation.PRECOMP) throw new IllegalArgumentException(); FieldElement YpX, YmX, A, B, C, D; YpX = this.Y.add(this.X); YmX = this.Y.subtract(this.X); A = YpX.multiply(q.X); // q->y+x B = YmX.multiply(q.Y); // q->y-x C = q.Z.multiply(this.T); // q->2dxy D = this.Z.add(this.Z); return p1p1(this.curve, A.subtract(B), A.add(B), D.add(C), D.subtract(C)); } /** * GroupElement subtraction using the twisted Edwards addition law with * extended coordinates (Hisil2008). *

    * this must be in $P^3$ representation and $q$ in PRECOMP representation. * $r = p - q$ where $p = this = (X1 : Y1 : Z1 : T1), q = (q.X, q.Y, q.Z) = (Y2/Z2 + X2/Z2, Y2/Z2 - X2/Z2, 2 * d * X2/Z2 * Y2/Z2)$ *

    * Negating $q$ means negating the value of $X2$ and $T2$ (the latter is irrelevant here). * The formula is in accordance to {@link #madd the above addition}. * * @param q the PRECOMP representation of the GroupElement to subtract. * @return the P1P1 representation of the result. */ private GroupElement msub(GroupElement q) { if (this.repr != Representation.P3) throw new UnsupportedOperationException(); if (q.repr != Representation.PRECOMP) throw new IllegalArgumentException(); FieldElement YpX, YmX, A, B, C, D; YpX = this.Y.add(this.X); YmX = this.Y.subtract(this.X); A = YpX.multiply(q.Y); // q->y-x B = YmX.multiply(q.X); // q->y+x C = q.Z.multiply(this.T); // q->2dxy D = this.Z.add(this.Z); return p1p1(this.curve, A.subtract(B), A.add(B), D.subtract(C), D.add(C)); } /** * GroupElement addition using the twisted Edwards addition law with * extended coordinates (Hisil2008). *

    * this must be in $P^3$ representation and $q$ in CACHED representation. * $r = p + q$ where $p = this = (X1 : Y1 : Z1 : T1), q = (q.X, q.Y, q.Z, q.T) = (Y2 + X2, Y2 - X2, Z2, 2 * d * T2)$ *

    * $r$ in $P \times P$ representation: *

      *
    • $X' = (Y1 + X1) * (Y2 + X2) - (Y1 - X1) * (Y2 - X2)$ *
    • $Y' = (Y1 + X1) * (Y2 + X2) + (Y1 - X1) * (Y2 - X2)$ *
    • $Z' = 2 * Z1 * Z2 + 2 * d * T1 * T2$ *
    • $T' = 2 * Z1 * T2 - 2 * d * T1 * T2$ *

    * Setting $A = (Y1 - X1) * (Y2 - X2), B = (Y1 + X1) * (Y2 + X2), C = 2 * d * T1 * T2, D = 2 * Z1 * Z2$ we get *

      *
    • $X' = (B - A)$ *
    • $Y' = (B + A)$ *
    • $Z' = (D + C)$ *
    • $T' = (D - C)$ *

    * Same result as in {@link #madd} (up to a common factor which does not matter). * * @param q the CACHED representation of the GroupElement to add. * @return the P1P1 representation of the result. */ public GroupElement add(GroupElement q) { if (this.repr != Representation.P3) throw new UnsupportedOperationException(); if (q.repr != Representation.CACHED) throw new IllegalArgumentException(); FieldElement YpX, YmX, A, B, C, ZZ, D; YpX = this.Y.add(this.X); YmX = this.Y.subtract(this.X); A = YpX.multiply(q.X); // q->Y+X B = YmX.multiply(q.Y); // q->Y-X C = q.T.multiply(this.T); // q->2dT ZZ = this.Z.multiply(q.Z); D = ZZ.add(ZZ); return p1p1(this.curve, A.subtract(B), A.add(B), D.add(C), D.subtract(C)); } /** * GroupElement subtraction using the twisted Edwards addition law with * extended coordinates (Hisil2008). *

    * $r = p - q$ *

    * Negating $q$ means negating the value of the coordinate $X2$ and $T2$. * The formula is in accordance to {@link #add the above addition}. * * @param q the PRECOMP representation of the GroupElement to subtract. * @return the P1P1 representation of the result. */ public GroupElement sub(GroupElement q) { if (this.repr != Representation.P3) throw new UnsupportedOperationException(); if (q.repr != Representation.CACHED) throw new IllegalArgumentException(); FieldElement YpX, YmX, A, B, C, ZZ, D; YpX = Y.add(X); YmX = Y.subtract(X); A = YpX.multiply(q.Y); // q->Y-X B = YmX.multiply(q.X); // q->Y+X C = q.T.multiply(T); // q->2dT ZZ = Z.multiply(q.Z); D = ZZ.add(ZZ); return p1p1(curve, A.subtract(B), A.add(B), D.subtract(C), D.add(C)); } /** * Negates this group element by subtracting it from the neutral group element. *

    * TODO-CR BR: why not simply negate the coordinates $X$ and $T$? * * @return The negative of this group element. */ public GroupElement negate() { if (this.repr != Representation.P3) throw new UnsupportedOperationException(); return this.curve.getZero(Representation.P3).sub(toCached()).toP3(); } @Override public int hashCode() { return Arrays.hashCode(this.toByteArray()); } @Override public boolean equals(Object obj) { if (obj == this) return true; if (!(obj instanceof GroupElement)) return false; GroupElement ge = (GroupElement) obj; if (!this.repr.equals(ge.repr)) { try { ge = ge.toRep(this.repr); } catch (RuntimeException e) { return false; } } switch (this.repr) { case P2: case P3: // Try easy way first if (this.Z.equals(ge.Z)) return this.X.equals(ge.X) && this.Y.equals(ge.Y); // X1/Z1 = X2/Z2 --> X1*Z2 = X2*Z1 final FieldElement x1 = this.X.multiply(ge.Z); final FieldElement y1 = this.Y.multiply(ge.Z); final FieldElement x2 = ge.X.multiply(this.Z); final FieldElement y2 = ge.Y.multiply(this.Z); return x1.equals(x2) && y1.equals(y2); case P1P1: return toP2().equals(ge); case PRECOMP: // Compare directly, PRECOMP is derived directly from x and y return this.X.equals(ge.X) && this.Y.equals(ge.Y) && this.Z.equals(ge.Z); case CACHED: // Try easy way first if (this.Z.equals(ge.Z)) return this.X.equals(ge.X) && this.Y.equals(ge.Y) && this.T.equals(ge.T); // (Y+X)/Z = y+x etc. final FieldElement x3 = this.X.multiply(ge.Z); final FieldElement y3 = this.Y.multiply(ge.Z); final FieldElement t3 = this.T.multiply(ge.Z); final FieldElement x4 = ge.X.multiply(this.Z); final FieldElement y4 = ge.Y.multiply(this.Z); final FieldElement t4 = ge.T.multiply(this.Z); return x3.equals(x4) && y3.equals(y4) && t3.equals(t4); default: return false; } } /** * Convert a to radix 16. *

    * Method is package private only so that tests run. * * @param a $= a[0]+256*a[1]+...+256^{31} a[31]$ * @return 64 bytes, each between -8 and 7 */ static byte[] toRadix16(final byte[] a) { final byte[] e = new byte[64]; int i; // Radix 16 notation for (i = 0; i < 32; i++) { e[2*i+0] = (byte) (a[i] & 15); e[2*i+1] = (byte) ((a[i] >> 4) & 15); } /* each e[i] is between 0 and 15 */ /* e[63] is between 0 and 7 */ int carry = 0; for (i = 0; i < 63; i++) { e[i] += carry; carry = e[i] + 8; carry >>= 4; e[i] -= carry << 4; } e[63] += carry; /* each e[i] is between -8 and 7 */ return e; } /** * Constant-time conditional move. *

    * Replaces this with $u$ if $b == 1$.
    * Replaces this with this if $b == 0$. *

    * Method is package private only so that tests run. * * @param u The group element to return if $b == 1$. * @param b in $\{0, 1\}$ * @return $u$ if $b == 1$; this if $b == 0$. Results undefined if $b$ is not in $\{0, 1\}$. */ GroupElement cmov(final GroupElement u, final int b) { return precomp(curve, X.cmov(u.X, b), Y.cmov(u.Y, b), Z.cmov(u.Z, b)); } /** * Look up $16^i r_i B$ in the precomputed table. *

    * No secret array indices, no secret branching. * Constant time. *

    * Must have previously precomputed. *

    * Method is package private only so that tests run. * * @param pos $= i/2$ for $i$ in $\{0, 2, 4,..., 62\}$ * @param b $= r_i$ * @return the GroupElement */ GroupElement select(final int pos, final int b) { // Is r_i negative? final int bnegative = Utils.negative(b); // |r_i| final int babs = b - (((-bnegative) & b) << 1); // 16^i |r_i| B final GroupElement t = this.curve.getZero(Representation.PRECOMP) .cmov(this.precmp[pos][0], Utils.equal(babs, 1)) .cmov(this.precmp[pos][1], Utils.equal(babs, 2)) .cmov(this.precmp[pos][2], Utils.equal(babs, 3)) .cmov(this.precmp[pos][3], Utils.equal(babs, 4)) .cmov(this.precmp[pos][4], Utils.equal(babs, 5)) .cmov(this.precmp[pos][5], Utils.equal(babs, 6)) .cmov(this.precmp[pos][6], Utils.equal(babs, 7)) .cmov(this.precmp[pos][7], Utils.equal(babs, 8)); // -16^i |r_i| B final GroupElement tminus = precomp(curve, t.Y, t.X, t.Z.negate()); // 16^i r_i B return t.cmov(tminus, bnegative); } /** * $h = a * B$ where $a = a[0]+256*a[1]+\dots+256^{31} a[31]$ and * $B$ is this point. If its lookup table has not been precomputed, it * will be at the start of the method (and cached for later calls). * Constant time. *

    * Preconditions: (TODO: Check this applies here) * $a[31] \le 127$ * @param a $= a[0]+256*a[1]+\dots+256^{31} a[31]$ * @return the GroupElement */ public GroupElement scalarMultiply(final byte[] a) { GroupElement t; int i; final byte[] e = toRadix16(a); GroupElement h = this.curve.getZero(Representation.P3); synchronized(this) { // TODO: Get opinion from a crypto professional. // This should in practice never be necessary, the only point that // this should get called on is EdDSA's B. //precompute(); for (i = 1; i < 64; i += 2) { t = select(i/2, e[i]); h = h.madd(t).toP3(); } h = h.dbl().toP2().dbl().toP2().dbl().toP2().dbl().toP3(); for (i = 0; i < 64; i += 2) { t = select(i/2, e[i]); h = h.madd(t).toP3(); } } return h; } /** * Calculates a sliding-windows base 2 representation for a given value $a$. * To learn more about it see [6] page 8. *

    * Output: $r$ which satisfies * $a = r0 * 2^0 + r1 * 2^1 + \dots + r255 * 2^{255}$ with $ri$ in $\{-15, -13, -11, -9, -7, -5, -3, -1, 0, 1, 3, 5, 7, 9, 11, 13, 15\}$ *

    * Method is package private only so that tests run. * * @param a $= a[0]+256*a[1]+\dots+256^{31} a[31]$. * @return The byte array $r$ in the above described form. */ static byte[] slide(final byte[] a) { byte[] r = new byte[256]; // Put each bit of 'a' into a separate byte, 0 or 1 for (int i = 0; i < 256; ++i) { r[i] = (byte) (1 & (a[i >> 3] >> (i & 7))); } // Note: r[i] will always be odd. for (int i = 0; i < 256; ++i) { if (r[i] != 0) { for (int b = 1; b <= 6 && i + b < 256; ++b) { // Accumulate bits if possible if (r[i + b] != 0) { if (r[i] + (r[i + b] << b) <= 15) { r[i] += r[i + b] << b; r[i + b] = 0; } else if (r[i] - (r[i + b] << b) >= -15) { r[i] -= r[i + b] << b; for (int k = i + b; k < 256; ++k) { if (r[k] == 0) { r[k] = 1; break; } r[k] = 0; } } else break; } } } } return r; } /** * $r = a * A + b * B$ where $a = a[0]+256*a[1]+\dots+256^{31} a[31]$, * $b = b[0]+256*b[1]+\dots+256^{31} b[31]$ and $B$ is this point. *

    * $A$ must have been previously precomputed. * * @param A in P3 representation. * @param a $= a[0]+256*a[1]+\dots+256^{31} a[31]$ * @param b $= b[0]+256*b[1]+\dots+256^{31} b[31]$ * @return the GroupElement */ public GroupElement doubleScalarMultiplyVariableTime(final GroupElement A, final byte[] a, final byte[] b) { // TODO-CR BR: A check that this is the base point is needed. final byte[] aslide = slide(a); final byte[] bslide = slide(b); GroupElement r = this.curve.getZero(Representation.P2); int i; for (i = 255; i >= 0; --i) { if (aslide[i] != 0 || bslide[i] != 0) break; } synchronized(this) { // TODO-CR BR strange comment below. // TODO: Get opinion from a crypto professional. // This should in practice never be necessary, the only point that // this should get called on is EdDSA's B. //precompute(); for (; i >= 0; --i) { GroupElement t = r.dbl(); if (aslide[i] > 0) { t = t.toP3().madd(A.dblPrecmp[aslide[i]/2]); } else if(aslide[i] < 0) { t = t.toP3().msub(A.dblPrecmp[(-aslide[i])/2]); } if (bslide[i] > 0) { t = t.toP3().madd(this.dblPrecmp[bslide[i]/2]); } else if(bslide[i] < 0) { t = t.toP3().msub(this.dblPrecmp[(-bslide[i])/2]); } r = t.toP2(); } } return r; } /** * Verify that a point is on its curve. * @return true if the point lies on its curve. */ public boolean isOnCurve() { return isOnCurve(curve); } /** * Verify that a point is on the curve. * @param curve The curve to check. * @return true if the point lies on the curve. */ public boolean isOnCurve(Curve curve) { switch (repr) { case P2: case P3: FieldElement recip = Z.invert(); FieldElement x = X.multiply(recip); FieldElement y = Y.multiply(recip); FieldElement xx = x.square(); FieldElement yy = y.square(); FieldElement dxxyy = curve.getD().multiply(xx).multiply(yy); return curve.getField().ONE.add(dxxyy).add(xx).equals(yy); default: return toP2().isOnCurve(curve); } } @Override public String toString() { return "[GroupElement\nX="+X+"\nY="+Y+"\nZ="+Z+"\nT="+T+"\n]"; } } ed25519-1.2.4/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/ScalarOps.java0000644000004100000410000000167513260523700025127 0ustar www-datawww-data/** * EdDSA-Java by str4d * * To the extent possible under law, the person who associated CC0 with * EdDSA-Java has waived all copyright and related or neighboring rights * to EdDSA-Java. * * You should have received a copy of the CC0 legalcode along with this * work. If not, see . * */ package net.i2p.crypto.eddsa.math; public interface ScalarOps { /** * Reduce the given scalar mod $l$. *

    * From the Ed25519 paper:
    * Here we interpret $2b$-bit strings in little-endian form as integers in * $\{0, 1,..., 2^{(2b)}-1\}$. * @param s the scalar to reduce * @return $s \bmod l$ */ public byte[] reduce(byte[] s); /** * $r = (a * b + c) \bmod l$ * @param a a scalar * @param b a scalar * @param c a scalar * @return $(a*b + c) \bmod l$ */ public byte[] multiplyAndAdd(byte[] a, byte[] b, byte[] c); } ed25519-1.2.4/ext/ed25519_jruby/net/i2p/crypto/eddsa/EdDSASecurityProvider.java0000644000004100000410000000455513260523700026432 0ustar www-datawww-data/** * EdDSA-Java by str4d * * To the extent possible under law, the person who associated CC0 with * EdDSA-Java has waived all copyright and related or neighboring rights * to EdDSA-Java. * * You should have received a copy of the CC0 legalcode along with this * work. If not, see . * */ package net.i2p.crypto.eddsa; import java.security.AccessController; import java.security.PrivilegedAction; import java.security.Provider; import java.security.Security; /** * A security {@link Provider} that can be registered via {@link Security#addProvider(Provider)} * * @author str4d */ public class EdDSASecurityProvider extends Provider { private static final long serialVersionUID = 1210027906682292307L; public static final String PROVIDER_NAME = "EdDSA"; public EdDSASecurityProvider() { super(PROVIDER_NAME, 0.2 /* should match POM major.minor version */, "str4d " + PROVIDER_NAME + " security provider wrapper"); AccessController.doPrivileged(new PrivilegedAction() { @Override public Object run() { setup(); return null; } }); } protected void setup() { // See https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/HowToImplAProvider.html put("KeyFactory." + EdDSAKey.KEY_ALGORITHM, "net.i2p.crypto.eddsa.KeyFactory"); put("KeyPairGenerator." + EdDSAKey.KEY_ALGORITHM, "net.i2p.crypto.eddsa.KeyPairGenerator"); put("Signature." + EdDSAEngine.SIGNATURE_ALGORITHM, "net.i2p.crypto.eddsa.EdDSAEngine"); // OID Mappings // See section "Mapping from OID to name". // The Key* -> OID mappings correspond to the default algorithm in KeyPairGenerator. // // From draft-ieft-curdle-pkix-04: // id-Ed25519 OBJECT IDENTIFIER ::= { 1 3 101 112 } put("Alg.Alias.KeyFactory.1.3.101.112", EdDSAKey.KEY_ALGORITHM); put("Alg.Alias.KeyFactory.OID.1.3.101.112", EdDSAKey.KEY_ALGORITHM); put("Alg.Alias.KeyPairGenerator.1.3.101.112", EdDSAKey.KEY_ALGORITHM); put("Alg.Alias.KeyPairGenerator.OID.1.3.101.112", EdDSAKey.KEY_ALGORITHM); put("Alg.Alias.Signature.1.3.101.112", EdDSAEngine.SIGNATURE_ALGORITHM); put("Alg.Alias.Signature.OID.1.3.101.112", EdDSAEngine.SIGNATURE_ALGORITHM); } } ed25519-1.2.4/ext/ed25519_jruby/LICENSE.txt0000644000004100000410000001573513260523700017411 0ustar www-datawww-dataCreative Commons Legal Code CC0 1.0 Universal CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED HEREUNDER. Statement of Purpose The laws of most jurisdictions throughout the world automatically confer exclusive Copyright and Related Rights (defined below) upon the creator and subsequent owner(s) (each and all, an "owner") of an original work of authorship and/or a database (each, a "Work"). Certain owners wish to permanently relinquish those rights to a Work for the purpose of contributing to a commons of creative, cultural and scientific works ("Commons") that the public can reliably and without fear of later claims of infringement build upon, modify, incorporate in other works, reuse and redistribute as freely as possible in any form whatsoever and for any purposes, including without limitation commercial purposes. These owners may contribute to the Commons to promote the ideal of a free culture and the further production of creative, cultural and scientific works, or to gain reputation or greater distribution for their Work in part through the use and efforts of others. For these and/or other purposes and motivations, and without any expectation of additional consideration or compensation, the person associating CC0 with a Work (the "Affirmer"), to the extent that he or she is an owner of Copyright and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and publicly distribute the Work under its terms, with knowledge of his or her Copyright and Related Rights in the Work and the meaning and intended legal effect of CC0 on those rights. 1. Copyright and Related Rights. A Work made available under CC0 may be protected by copyright and related or neighboring rights ("Copyright and Related Rights"). Copyright and Related Rights include, but are not limited to, the following: i. the right to reproduce, adapt, distribute, perform, display, communicate, and translate a Work; ii. moral rights retained by the original author(s) and/or performer(s); iii. publicity and privacy rights pertaining to a person's image or likeness depicted in a Work; iv. rights protecting against unfair competition in regards to a Work, subject to the limitations in paragraph 4(a), below; v. rights protecting the extraction, dissemination, use and reuse of data in a Work; vi. database rights (such as those arising under Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, and under any national implementation thereof, including any amended or successor version of such directive); and vii. other similar, equivalent or corresponding rights throughout the world based on applicable law or treaty, and any national implementations thereof. 2. Waiver. To the greatest extent permitted by, but not in contravention of, applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and unconditionally waives, abandons, and surrenders all of Affirmer's Copyright and Related Rights and associated claims and causes of action, whether now known or unknown (including existing as well as future claims and causes of action), in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each member of the public at large and to the detriment of Affirmer's heirs and successors, fully intending that such Waiver shall not be subject to revocation, rescission, cancellation, termination, or any other legal or equitable action to disrupt the quiet enjoyment of the Work by the public as contemplated by Affirmer's express Statement of Purpose. 3. Public License Fallback. Should any part of the Waiver for any reason be judged legally invalid or ineffective under applicable law, then the Waiver shall be preserved to the maximum extent permitted taking into account Affirmer's express Statement of Purpose. In addition, to the extent the Waiver is so judged Affirmer hereby grants to each affected person a royalty-free, non transferable, non sublicensable, non exclusive, irrevocable and unconditional license to exercise Affirmer's Copyright and Related Rights in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "License"). The License shall be deemed effective as of the date CC0 was applied by Affirmer to the Work. Should any part of the License for any reason be judged legally invalid or ineffective under applicable law, such partial invalidity or ineffectiveness shall not invalidate the remainder of the License, and in such case Affirmer hereby affirms that he or she will not (i) exercise any of his or her remaining Copyright and Related Rights in the Work or (ii) assert any associated claims and causes of action with respect to the Work, in either case contrary to Affirmer's express Statement of Purpose. 4. Limitations and Disclaimers. a. No trademark or patent rights held by Affirmer are waived, abandoned, surrendered, licensed or otherwise affected by this document. b. Affirmer offers the Work as-is and makes no representations or warranties of any kind concerning the Work, express, implied, statutory or otherwise, including without limitation warranties of title, merchantability, fitness for a particular purpose, non infringement, or the absence of latent or other defects, accuracy, or the present or absence of errors, whether or not discoverable, all to the greatest extent permissible under applicable law. c. Affirmer disclaims responsibility for clearing rights of other persons that may apply to the Work or any use thereof, including without limitation any person's Copyright and Related Rights in the Work. Further, Affirmer disclaims responsibility for obtaining any necessary consents, permissions or other rights required for any use of the Work. d. Affirmer understands and acknowledges that Creative Commons is not a party to this document and has no duty or obligation with respect to this CC0 or use of the Work. For more information, please see https://creativecommons.org/publicdomain/zero/1.0/ ed25519-1.2.4/ext/ed25519_jruby/org/0000755000004100000410000000000013260523700016342 5ustar www-datawww-dataed25519-1.2.4/ext/ed25519_jruby/org/cryptorb/0000755000004100000410000000000013260523700020206 5ustar www-datawww-dataed25519-1.2.4/ext/ed25519_jruby/org/cryptorb/Ed25519Provider.java0000644000004100000410000001006413260523700023523 0ustar www-datawww-datapackage org.cryptorb; import java.security.MessageDigest; import java.security.Signature; import java.util.Arrays; import net.i2p.crypto.eddsa.EdDSAEngine; import net.i2p.crypto.eddsa.EdDSAPrivateKey; import net.i2p.crypto.eddsa.EdDSAPublicKey; import net.i2p.crypto.eddsa.spec.EdDSANamedCurveTable; import net.i2p.crypto.eddsa.spec.EdDSAParameterSpec; import net.i2p.crypto.eddsa.spec.EdDSAPrivateKeySpec; import net.i2p.crypto.eddsa.spec.EdDSAPublicKeySpec; import org.jruby.Ruby; import org.jruby.RubyModule; import org.jruby.RubyString; import org.jruby.anno.JRubyMethod; import org.jruby.anno.JRubyModule; import org.jruby.runtime.ThreadContext; import org.jruby.runtime.builtin.IRubyObject; @JRubyModule(name="Ed25519::Provider::JRuby") public class Ed25519Provider { public static RubyModule createEd25519Module(Ruby runtime) { RubyModule mEd25519 = runtime.defineModule("Ed25519"); RubyModule mEd25519Provider = mEd25519.defineModuleUnder("Provider"); RubyModule mEd25519ProviderJRuby = mEd25519Provider.defineOrGetModuleUnder("JRuby"); mEd25519ProviderJRuby.defineAnnotatedMethods(Ed25519Provider.class); return mEd25519ProviderJRuby; } @JRubyMethod(name = "create_keypair", module = true) public static IRubyObject create_keypair(ThreadContext context, IRubyObject self, IRubyObject seed) { byte[] seedBytes = seed.convertToString().getByteList().bytes(); if (seedBytes.length != 32) { throw context.runtime.newArgumentError("expected 32-byte seed value, got " + seedBytes.length); } EdDSAParameterSpec edParams = EdDSANamedCurveTable.getByName(EdDSANamedCurveTable.ED_25519); EdDSAPrivateKeySpec signingKey = new EdDSAPrivateKeySpec(seedBytes, edParams); EdDSAPublicKeySpec verifyKey = new EdDSAPublicKeySpec(signingKey.getA(), edParams); byte[] keypair = new byte[64]; System.arraycopy(seedBytes, 0, keypair, 0, 32); System.arraycopy(verifyKey.getA().toByteArray(), 0, keypair, 32, 32); return RubyString.newString(context.getRuntime(), keypair); } @JRubyMethod(name = "sign", module = true) public static IRubyObject sign(ThreadContext context, IRubyObject self, IRubyObject keypair, IRubyObject msg) throws Exception { byte[] keypairBytes = keypair.convertToString().getByteList().bytes(); if (keypairBytes.length != 64) { throw context.runtime.newArgumentError("expected 64-byte keypair value, got " + keypairBytes.length); } EdDSAParameterSpec edParams = EdDSANamedCurveTable.getByName(EdDSANamedCurveTable.ED_25519); Signature signer = new EdDSAEngine(MessageDigest.getInstance(edParams.getHashAlgorithm())); byte[] seedBytes = Arrays.copyOfRange(keypairBytes, 0, 32); EdDSAPrivateKeySpec signingKey = new EdDSAPrivateKeySpec(seedBytes, edParams); signer.initSign(new EdDSAPrivateKey(signingKey)); signer.update(msg.convertToString().getByteList().bytes()); return RubyString.newString(context.getRuntime(), signer.sign()); } @JRubyMethod(name = "verify", module = true) public static IRubyObject verify(ThreadContext context, IRubyObject self, IRubyObject verify_key, IRubyObject signature, IRubyObject msg) throws Exception { byte[] verifyKeyBytes = verify_key.convertToString().getByteList().bytes(); byte[] signatureBytes = signature.convertToString().getByteList().bytes(); if (verifyKeyBytes.length != 32) { throw context.runtime.newArgumentError("expected 32-byte verify key, got " + verifyKeyBytes.length); } if (signatureBytes.length != 64) { throw context.runtime.newArgumentError("expected 64-byte signature, got " + signatureBytes.length); } EdDSAParameterSpec edParams = EdDSANamedCurveTable.getByName(EdDSANamedCurveTable.ED_25519); Signature signer = new EdDSAEngine(MessageDigest.getInstance(edParams.getHashAlgorithm())); EdDSAPublicKeySpec verifyKey = new EdDSAPublicKeySpec(verifyKeyBytes, edParams); signer.initVerify(new EdDSAPublicKey(verifyKey)); signer.update(msg.convertToString().getByteList().bytes()); boolean isValid = signer.verify(signatureBytes); return context.runtime.newBoolean(isValid); } } ed25519-1.2.4/ext/ed25519_jruby/README.md0000644000004100000410000000643413260523700017041 0ustar www-datawww-dataEdDSA-Java ========== [![Build Status](https://travis-ci.org/str4d/ed25519-java.svg?branch=master)](https://travis-ci.org/str4d/ed25519-java) This is an implementation of EdDSA in Java. Structurally, it is based on the ref10 implementation in SUPERCOP (see https://ed25519.cr.yp.to/software.html). There are two internal implementations: * A port of the radix-2^51 operations in ref10 - fast and constant-time, but only useful for Ed25519. * A generic version using BigIntegers for calculation - a bit slower and not constant-time, but compatible with any EdDSA parameter specification. To use ------ Download the latest .jar from the releases tab and place it in your classpath. Gradle users: ``` compile 'net.i2p.crypto:eddsa:0.2.0' ``` The code requires Java 6 (for e.g. the `Arrays.copyOfRange()` calls in `EdDSAEngine.engineVerify()`). The JUnit4 tests require the Hamcrest library `hamcrest-all.jar`. This code is released to the public domain and can be used for any purpose. See `LICENSE.txt` for details. Disclaimer ---------- There are **no** guarantees that this is secure for all cases, and users should review the code themselves before depending on it. PRs that fix bugs or improve reviewability are very welcome. Additionally: - The unit test suite includes tests against [the data from the original Python implementation](https://ed25519.cr.yp.to/python/sign.input). - The code (as of 97cea3f0d910fc627c7b57b1bc4d783cdd0c2a4a) was reviewed by [an independent developer](https://github.com/BloodyRookie). - The code (as of dc9f58f2c874463c15465326efc040d17a627b3a) was audited by an independent third party, and the one issue found [was fixed](https://github.com/str4d/ed25519-java/pull/31). Code comparison --------------- For ease of following, here are the main methods in ref10 and their equivalents in this codebase: | EdDSA Operation | ref10 function | Java function | | --------------- | -------------- | ------------- | | Generate keypair | `crypto_sign_keypair` | `EdDSAPrivateKeySpec` constructor | | Sign message | `crypto_sign` | `EdDSAEngine.engineSign` | | Verify signature | `crypto_sign_open` | `EdDSAEngine.engineVerify` | | EdDSA point arithmetic | ref10 function | Java function | | ---------------------- | -------------- | ------------- | | `R = b * B` | `ge_scalarmult_base` | `GroupElement.scalarMultiply` | | `R = a*A + b*B` | `ge_double_scalarmult_vartime` | `GroupElement.doubleScalarMultiplyVariableTime` | | `R = 2 * P` | `ge_p2_dbl` | `GroupElement.dbl` | | `R = P + Q` | `ge_madd`, `ge_add` | `GroupElement.madd`, `GroupElement.add` | | `R = P - Q` | `ge_msub`, `ge_sub` | `GroupElement.msub`, `GroupElement.sub` | Important changes ----------------- ### 0.2.0 - Ed25519 is now named `Ed25519` in `EdDSANamedCurveTable`, and the previous public constant (containing the older inaccurate name) has been removed. Credits ------- * The Ed25519 class was originally ported by k3d3 from [the Python Ed25519 reference implementation](https://ed25519.cr.yp.to/python/ed25519.py). * Useful comments and tweaks were found in [the GNUnet implementation of Ed25519](https://gnunet.org/svn/gnunet-java/src/main/java/org/gnunet/util/crypto/) (based on k3d3's class). * [BloodyRookie](https://github.com/BloodyRookie) reviewed the code, adding many useful comments, unit tests and literature. ed25519-1.2.4/ext/ed25519_ref10/0000755000004100000410000000000013260523700015335 5ustar www-datawww-dataed25519-1.2.4/ext/ed25519_ref10/sc.h0000644000004100000410000000056513260523700016121 0ustar www-datawww-data#ifndef SC_H #define SC_H #include /* The set of scalars is \Z/l where l = 2^252 + 27742317777372353535851937790883648493. */ #define sc_reduce crypto_sign_ed25519_ref10_sc_reduce #define sc_muladd crypto_sign_ed25519_ref10_sc_muladd extern void sc_reduce(uint8_t *); extern void sc_muladd(uint8_t *,const uint8_t *,const uint8_t *,const uint8_t *); #endif ed25519-1.2.4/ext/ed25519_ref10/sqrtm1.h0000644000004100000410000000012713260523700016735 0ustar www-datawww-data-32595792,-7943725,9377950,3500415,12389472,-272473,-25146209,-2005654,326686,11406482 ed25519-1.2.4/ext/ed25519_ref10/ge_madd.h0000644000004100000410000000355413260523700017075 0ustar www-datawww-data /* qhasm: enter ge_madd */ /* qhasm: fe X1 */ /* qhasm: fe Y1 */ /* qhasm: fe Z1 */ /* qhasm: fe T1 */ /* qhasm: fe ypx2 */ /* qhasm: fe ymx2 */ /* qhasm: fe xy2d2 */ /* qhasm: fe X3 */ /* qhasm: fe Y3 */ /* qhasm: fe Z3 */ /* qhasm: fe T3 */ /* qhasm: fe YpX1 */ /* qhasm: fe YmX1 */ /* qhasm: fe A */ /* qhasm: fe B */ /* qhasm: fe C */ /* qhasm: fe D */ /* qhasm: YpX1 = Y1+X1 */ /* asm 1: fe_add(>YpX1=fe#1,YpX1=r->X,Y,X); */ fe_add(r->X,p->Y,p->X); /* qhasm: YmX1 = Y1-X1 */ /* asm 1: fe_sub(>YmX1=fe#2,YmX1=r->Y,Y,X); */ fe_sub(r->Y,p->Y,p->X); /* qhasm: A = YpX1*ypx2 */ /* asm 1: fe_mul(>A=fe#3,A=r->Z,X,yplusx); */ fe_mul(r->Z,r->X,q->yplusx); /* qhasm: B = YmX1*ymx2 */ /* asm 1: fe_mul(>B=fe#2,B=r->Y,Y,yminusx); */ fe_mul(r->Y,r->Y,q->yminusx); /* qhasm: C = xy2d2*T1 */ /* asm 1: fe_mul(>C=fe#4,C=r->T,xy2d,T); */ fe_mul(r->T,q->xy2d,p->T); /* qhasm: D = 2*Z1 */ /* asm 1: fe_add(>D=fe#5,D=t0,Z,Z); */ fe_add(t0,p->Z,p->Z); /* qhasm: X3 = A-B */ /* asm 1: fe_sub(>X3=fe#1,X3=r->X,Z,Y); */ fe_sub(r->X,r->Z,r->Y); /* qhasm: Y3 = A+B */ /* asm 1: fe_add(>Y3=fe#2,Y3=r->Y,Z,Y); */ fe_add(r->Y,r->Z,r->Y); /* qhasm: Z3 = D+C */ /* asm 1: fe_add(>Z3=fe#3,Z3=r->Z,T); */ fe_add(r->Z,t0,r->T); /* qhasm: T3 = D-C */ /* asm 1: fe_sub(>T3=fe#4,T3=r->T,T); */ fe_sub(r->T,t0,r->T); /* qhasm: return */ ed25519-1.2.4/ext/ed25519_ref10/d.h0000644000004100000410000000013313260523700015726 0ustar www-datawww-data-10913610,13857413,-15372611,6949391,114729,-8787816,-6275908,-3247719,-18696448,-12055116 ed25519-1.2.4/ext/ed25519_ref10/sign.c0000644000004100000410000000142113260523700016437 0ustar www-datawww-data#include #include "ed25519_ref10.h" #include "sha512.h" #include "ge.h" #include "sc.h" int crypto_sign_ed25519_ref10( uint8_t *sm, uint64_t *smlen, const uint8_t *m, uint64_t mlen, const uint8_t *sk ) { unsigned char pk[32]; unsigned char az[64]; unsigned char nonce[64]; unsigned char hram[64]; ge_p3 R; memmove(pk,sk + 32,32); crypto_hash_sha512(az,sk,32); az[0] &= 248; az[31] &= 63; az[31] |= 64; *smlen = mlen + 64; memmove(sm + 64,m,mlen); memmove(sm + 32,az + 32,32); crypto_hash_sha512(nonce,sm + 32,mlen + 32); memmove(sm + 32,pk,32); sc_reduce(nonce); ge_scalarmult_base(&R,nonce); ge_p3_tobytes(sm,&R); crypto_hash_sha512(hram,sm,mlen + 64); sc_reduce(hram); sc_muladd(sm + 32,hram,az,nonce); return 0; } ed25519-1.2.4/ext/ed25519_ref10/extconf.rb0000644000004100000410000000023713260523700017332 0ustar www-datawww-data# frozen_string_literal: true # rubocop:disable Style/GlobalVars require "mkmf" $CFLAGS << " -Wall -O3 -pedantic -std=c99" create_makefile "ed25519_ref10" ed25519-1.2.4/ext/ed25519_ref10/base2.h0000644000004100000410000000452413260523700016507 0ustar www-datawww-data { { 25967493,-14356035,29566456,3660896,-12694345,4014787,27544626,-11754271,-6079156,2047605 }, { -12545711,934262,-2722910,3049990,-727428,9406986,12720692,5043384,19500929,-15469378 }, { -8738181,4489570,9688441,-14785194,10184609,-12363380,29287919,11864899,-24514362,-4438546 }, }, { { 15636291,-9688557,24204773,-7912398,616977,-16685262,27787600,-14772189,28944400,-1550024 }, { 16568933,4717097,-11556148,-1102322,15682896,-11807043,16354577,-11775962,7689662,11199574 }, { 30464156,-5976125,-11779434,-15670865,23220365,15915852,7512774,10017326,-17749093,-9920357 }, }, { { 10861363,11473154,27284546,1981175,-30064349,12577861,32867885,14515107,-15438304,10819380 }, { 4708026,6336745,20377586,9066809,-11272109,6594696,-25653668,12483688,-12668491,5581306 }, { 19563160,16186464,-29386857,4097519,10237984,-4348115,28542350,13850243,-23678021,-15815942 }, }, { { 5153746,9909285,1723747,-2777874,30523605,5516873,19480852,5230134,-23952439,-15175766 }, { -30269007,-3463509,7665486,10083793,28475525,1649722,20654025,16520125,30598449,7715701 }, { 28881845,14381568,9657904,3680757,-20181635,7843316,-31400660,1370708,29794553,-1409300 }, }, { { -22518993,-6692182,14201702,-8745502,-23510406,8844726,18474211,-1361450,-13062696,13821877 }, { -6455177,-7839871,3374702,-4740862,-27098617,-10571707,31655028,-7212327,18853322,-14220951 }, { 4566830,-12963868,-28974889,-12240689,-7602672,-2830569,-8514358,-10431137,2207753,-3209784 }, }, { { -25154831,-4185821,29681144,7868801,-6854661,-9423865,-12437364,-663000,-31111463,-16132436 }, { 25576264,-2703214,7349804,-11814844,16472782,9300885,3844789,15725684,171356,6466918 }, { 23103977,13316479,9739013,-16149481,817875,-15038942,8965339,-14088058,-30714912,16193877 }, }, { { -33521811,3180713,-2394130,14003687,-16903474,-16270840,17238398,4729455,-18074513,9256800 }, { -25182317,-4174131,32336398,5036987,-21236817,11360617,22616405,9761698,-19827198,630305 }, { -13720693,2639453,-24237460,-7406481,9494427,-5774029,-6554551,-15960994,-2449256,-14291300 }, }, { { -3151181,-5046075,9282714,6866145,-31907062,-863023,-18940575,15033784,25105118,-7894876 }, { -24326370,15950226,-31801215,-14592823,-11662737,-5090925,1573892,-2625887,2198790,-15804619 }, { -3099351,10324967,-2241613,7453183,-5446979,-2735503,-13812022,-16236442,-32461234,-12290683 }, }, ed25519-1.2.4/ext/ed25519_ref10/ed25519_ref10.c0000644000004100000410000000636213260523700017503 0ustar www-datawww-data#include "ruby.h" #include "ed25519_ref10.h" static VALUE mEd25519 = Qnil; static VALUE mEd25519_Provider = Qnil; static VALUE mEd25519_Provider_Ref10 = Qnil; static VALUE mEd25519_Provider_Ref10_create_keypair(VALUE self, VALUE seed); static VALUE mEd25519_Provider_Ref10_sign(VALUE self, VALUE signing_key, VALUE msg); static VALUE mEd25519_Provider_Ref10_verify(VALUE self, VALUE verify_key, VALUE signature, VALUE msg); void Init_ed25519_ref10() { mEd25519 = rb_define_module("Ed25519"); mEd25519_Provider = rb_define_module_under(mEd25519, "Provider"); mEd25519_Provider_Ref10 = rb_define_module_under(mEd25519_Provider, "Ref10"); rb_define_singleton_method(mEd25519_Provider_Ref10, "create_keypair", mEd25519_Provider_Ref10_create_keypair, 1); rb_define_singleton_method(mEd25519_Provider_Ref10, "sign", mEd25519_Provider_Ref10_sign, 2); rb_define_singleton_method(mEd25519_Provider_Ref10, "verify", mEd25519_Provider_Ref10_verify, 3); } static VALUE mEd25519_Provider_Ref10_create_keypair(VALUE self, VALUE seed) { uint8_t verify_key[PUBLICKEYBYTES]; uint8_t keypair[SECRETKEYBYTES]; StringValue(seed); if(RSTRING_LEN(seed) != SECRETKEYBYTES / 2) { rb_raise(rb_eArgError, "seed must be exactly %d bytes", SECRETKEYBYTES / 2); } crypto_sign_ed25519_ref10_seed_keypair(verify_key, keypair, (uint8_t *)RSTRING_PTR(seed)); return rb_str_new((const char *)keypair, SECRETKEYBYTES); } static VALUE mEd25519_Provider_Ref10_sign(VALUE self, VALUE signing_key, VALUE msg) { uint8_t *sig_and_msg; uint64_t sig_and_msg_len; VALUE result; StringValue(signing_key); StringValue(msg); if(RSTRING_LEN(signing_key) != SECRETKEYBYTES) { rb_raise(rb_eArgError, "private signing keys must be %d bytes", SECRETKEYBYTES); } sig_and_msg = (uint8_t *)xmalloc(SIGNATUREBYTES + RSTRING_LEN(msg)); crypto_sign_ed25519_ref10( sig_and_msg, &sig_and_msg_len, (uint8_t *)RSTRING_PTR(msg), RSTRING_LEN(msg), (uint8_t *)RSTRING_PTR(signing_key) ); result = rb_str_new((const char *)sig_and_msg, SIGNATUREBYTES); xfree(sig_and_msg); return result; } static VALUE mEd25519_Provider_Ref10_verify(VALUE self, VALUE verify_key, VALUE signature, VALUE msg) { uint8_t *sig_and_msg, *buffer; uint64_t sig_and_msg_len, buffer_len; int result; StringValue(verify_key); StringValue(signature); StringValue(msg); if(RSTRING_LEN(verify_key) != PUBLICKEYBYTES) { rb_raise(rb_eArgError, "public verify keys must be %d bytes", PUBLICKEYBYTES); } if(RSTRING_LEN(signature) != SIGNATUREBYTES) { rb_raise(rb_eArgError, "signatures must be %d bytes", SIGNATUREBYTES); } sig_and_msg_len = SIGNATUREBYTES + RSTRING_LEN(msg); sig_and_msg = (unsigned char *)xmalloc(sig_and_msg_len); buffer = (unsigned char *)xmalloc(sig_and_msg_len); memcpy(sig_and_msg, RSTRING_PTR(signature), SIGNATUREBYTES); memcpy(sig_and_msg + SIGNATUREBYTES, RSTRING_PTR(msg), RSTRING_LEN(msg)); result = crypto_sign_open_ed25519_ref10( buffer, &buffer_len, sig_and_msg, sig_and_msg_len, (uint8_t *)RSTRING_PTR(verify_key) ); xfree(sig_and_msg); xfree(buffer); return result == 0 ? Qtrue : Qfalse; } ed25519-1.2.4/ext/ed25519_ref10/ge.h0000644000004100000410000000546513260523700016113 0ustar www-datawww-data#ifndef GE_H #define GE_H /* ge means group element. Here the group is the set of pairs (x,y) of field elements (see fe.h) satisfying -x^2 + y^2 = 1 + d x^2y^2 where d = -121665/121666. Representations: ge_p2 (projective): (X:Y:Z) satisfying x=X/Z, y=Y/Z ge_p3 (extended): (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT ge_p1p1 (completed): ((X:Z),(Y:T)) satisfying x=X/Z, y=Y/T ge_precomp (Duif): (y+x,y-x,2dxy) */ #include "fe.h" typedef struct { fe X; fe Y; fe Z; } ge_p2; typedef struct { fe X; fe Y; fe Z; fe T; } ge_p3; typedef struct { fe X; fe Y; fe Z; fe T; } ge_p1p1; typedef struct { fe yplusx; fe yminusx; fe xy2d; } ge_precomp; typedef struct { fe YplusX; fe YminusX; fe Z; fe T2d; } ge_cached; #define ge_frombytes_negate_vartime crypto_sign_ed25519_ref10_ge_frombytes_negate_vartime #define ge_tobytes crypto_sign_ed25519_ref10_ge_tobytes #define ge_p3_tobytes crypto_sign_ed25519_ref10_ge_p3_tobytes #define ge_p2_0 crypto_sign_ed25519_ref10_ge_p2_0 #define ge_p3_0 crypto_sign_ed25519_ref10_ge_p3_0 #define ge_precomp_0 crypto_sign_ed25519_ref10_ge_precomp_0 #define ge_p3_to_p2 crypto_sign_ed25519_ref10_ge_p3_to_p2 #define ge_p3_to_cached crypto_sign_ed25519_ref10_ge_p3_to_cached #define ge_p1p1_to_p2 crypto_sign_ed25519_ref10_ge_p1p1_to_p2 #define ge_p1p1_to_p3 crypto_sign_ed25519_ref10_ge_p1p1_to_p3 #define ge_p2_dbl crypto_sign_ed25519_ref10_ge_p2_dbl #define ge_p3_dbl crypto_sign_ed25519_ref10_ge_p3_dbl #define ge_madd crypto_sign_ed25519_ref10_ge_madd #define ge_msub crypto_sign_ed25519_ref10_ge_msub #define ge_add crypto_sign_ed25519_ref10_ge_add #define ge_sub crypto_sign_ed25519_ref10_ge_sub #define ge_scalarmult_base crypto_sign_ed25519_ref10_ge_scalarmult_base #define ge_double_scalarmult_vartime crypto_sign_ed25519_ref10_ge_double_scalarmult_vartime extern void ge_tobytes(unsigned char *,const ge_p2 *); extern void ge_p3_tobytes(unsigned char *,const ge_p3 *); extern int ge_frombytes_negate_vartime(ge_p3 *,const unsigned char *); extern void ge_p2_0(ge_p2 *); extern void ge_p3_0(ge_p3 *); extern void ge_precomp_0(ge_precomp *); extern void ge_p3_to_p2(ge_p2 *,const ge_p3 *); extern void ge_p3_to_cached(ge_cached *,const ge_p3 *); extern void ge_p1p1_to_p2(ge_p2 *,const ge_p1p1 *); extern void ge_p1p1_to_p3(ge_p3 *,const ge_p1p1 *); extern void ge_p2_dbl(ge_p1p1 *,const ge_p2 *); extern void ge_p3_dbl(ge_p1p1 *,const ge_p3 *); extern void ge_madd(ge_p1p1 *,const ge_p3 *,const ge_precomp *); extern void ge_msub(ge_p1p1 *,const ge_p3 *,const ge_precomp *); extern void ge_add(ge_p1p1 *,const ge_p3 *,const ge_cached *); extern void ge_sub(ge_p1p1 *,const ge_p3 *,const ge_cached *); extern void ge_scalarmult_base(ge_p3 *,const unsigned char *); extern void ge_double_scalarmult_vartime(ge_p2 *,const unsigned char *,const ge_p3 *,const unsigned char *); #endif ed25519-1.2.4/ext/ed25519_ref10/ge_p2_dbl.h0000644000004100000410000000270413260523700017326 0ustar www-datawww-data /* qhasm: enter ge_p2_dbl */ /* qhasm: fe X1 */ /* qhasm: fe Y1 */ /* qhasm: fe Z1 */ /* qhasm: fe A */ /* qhasm: fe AA */ /* qhasm: fe XX */ /* qhasm: fe YY */ /* qhasm: fe B */ /* qhasm: fe X3 */ /* qhasm: fe Y3 */ /* qhasm: fe Z3 */ /* qhasm: fe T3 */ /* qhasm: XX=X1^2 */ /* asm 1: fe_sq(>XX=fe#1,XX=r->X,X); */ fe_sq(r->X,p->X); /* qhasm: YY=Y1^2 */ /* asm 1: fe_sq(>YY=fe#3,YY=r->Z,Y); */ fe_sq(r->Z,p->Y); /* qhasm: B=2*Z1^2 */ /* asm 1: fe_sq2(>B=fe#4,B=r->T,Z); */ fe_sq2(r->T,p->Z); /* qhasm: A=X1+Y1 */ /* asm 1: fe_add(>A=fe#2,A=r->Y,X,Y); */ fe_add(r->Y,p->X,p->Y); /* qhasm: AA=A^2 */ /* asm 1: fe_sq(>AA=fe#5,AA=t0,Y); */ fe_sq(t0,r->Y); /* qhasm: Y3=YY+XX */ /* asm 1: fe_add(>Y3=fe#2,Y3=r->Y,Z,X); */ fe_add(r->Y,r->Z,r->X); /* qhasm: Z3=YY-XX */ /* asm 1: fe_sub(>Z3=fe#3,Z3=r->Z,Z,X); */ fe_sub(r->Z,r->Z,r->X); /* qhasm: X3=AA-Y3 */ /* asm 1: fe_sub(>X3=fe#1,X3=r->X,Y); */ fe_sub(r->X,t0,r->Y); /* qhasm: T3=B-Z3 */ /* asm 1: fe_sub(>T3=fe#4,T3=r->T,T,Z); */ fe_sub(r->T,r->T,r->Z); /* qhasm: return */ ed25519-1.2.4/ext/ed25519_ref10/ge_add.h0000644000004100000410000000404013260523700016707 0ustar www-datawww-data /* qhasm: enter ge_add */ /* qhasm: fe X1 */ /* qhasm: fe Y1 */ /* qhasm: fe Z1 */ /* qhasm: fe Z2 */ /* qhasm: fe T1 */ /* qhasm: fe ZZ */ /* qhasm: fe YpX2 */ /* qhasm: fe YmX2 */ /* qhasm: fe T2d2 */ /* qhasm: fe X3 */ /* qhasm: fe Y3 */ /* qhasm: fe Z3 */ /* qhasm: fe T3 */ /* qhasm: fe YpX1 */ /* qhasm: fe YmX1 */ /* qhasm: fe A */ /* qhasm: fe B */ /* qhasm: fe C */ /* qhasm: fe D */ /* qhasm: YpX1 = Y1+X1 */ /* asm 1: fe_add(>YpX1=fe#1,YpX1=r->X,Y,X); */ fe_add(r->X,p->Y,p->X); /* qhasm: YmX1 = Y1-X1 */ /* asm 1: fe_sub(>YmX1=fe#2,YmX1=r->Y,Y,X); */ fe_sub(r->Y,p->Y,p->X); /* qhasm: A = YpX1*YpX2 */ /* asm 1: fe_mul(>A=fe#3,A=r->Z,X,YplusX); */ fe_mul(r->Z,r->X,q->YplusX); /* qhasm: B = YmX1*YmX2 */ /* asm 1: fe_mul(>B=fe#2,B=r->Y,Y,YminusX); */ fe_mul(r->Y,r->Y,q->YminusX); /* qhasm: C = T2d2*T1 */ /* asm 1: fe_mul(>C=fe#4,C=r->T,T2d,T); */ fe_mul(r->T,q->T2d,p->T); /* qhasm: ZZ = Z1*Z2 */ /* asm 1: fe_mul(>ZZ=fe#1,ZZ=r->X,Z,Z); */ fe_mul(r->X,p->Z,q->Z); /* qhasm: D = 2*ZZ */ /* asm 1: fe_add(>D=fe#5,D=t0,X,X); */ fe_add(t0,r->X,r->X); /* qhasm: X3 = A-B */ /* asm 1: fe_sub(>X3=fe#1,X3=r->X,Z,Y); */ fe_sub(r->X,r->Z,r->Y); /* qhasm: Y3 = A+B */ /* asm 1: fe_add(>Y3=fe#2,Y3=r->Y,Z,Y); */ fe_add(r->Y,r->Z,r->Y); /* qhasm: Z3 = D+C */ /* asm 1: fe_add(>Z3=fe#3,Z3=r->Z,T); */ fe_add(r->Z,t0,r->T); /* qhasm: T3 = D-C */ /* asm 1: fe_sub(>T3=fe#4,T3=r->T,T); */ fe_sub(r->T,t0,r->T); /* qhasm: return */ ed25519-1.2.4/ext/ed25519_ref10/api.h0000644000004100000410000000017113260523700016256 0ustar www-datawww-data#define CRYPTO_SECRETKEYBYTES 64 #define CRYPTO_PUBLICKEYBYTES 32 #define CRYPTO_BYTES 64 #define CRYPTO_DETERMINISTIC 1 ed25519-1.2.4/ext/ed25519_ref10/base.h0000644000004100000410000022525113260523700016427 0ustar www-datawww-data{ { { 25967493,-14356035,29566456,3660896,-12694345,4014787,27544626,-11754271,-6079156,2047605 }, { -12545711,934262,-2722910,3049990,-727428,9406986,12720692,5043384,19500929,-15469378 }, { -8738181,4489570,9688441,-14785194,10184609,-12363380,29287919,11864899,-24514362,-4438546 }, }, { { -12815894,-12976347,-21581243,11784320,-25355658,-2750717,-11717903,-3814571,-358445,-10211303 }, { -21703237,6903825,27185491,6451973,-29577724,-9554005,-15616551,11189268,-26829678,-5319081 }, { 26966642,11152617,32442495,15396054,14353839,-12752335,-3128826,-9541118,-15472047,-4166697 }, }, { { 15636291,-9688557,24204773,-7912398,616977,-16685262,27787600,-14772189,28944400,-1550024 }, { 16568933,4717097,-11556148,-1102322,15682896,-11807043,16354577,-11775962,7689662,11199574 }, { 30464156,-5976125,-11779434,-15670865,23220365,15915852,7512774,10017326,-17749093,-9920357 }, }, { { -17036878,13921892,10945806,-6033431,27105052,-16084379,-28926210,15006023,3284568,-6276540 }, { 23599295,-8306047,-11193664,-7687416,13236774,10506355,7464579,9656445,13059162,10374397 }, { 7798556,16710257,3033922,2874086,28997861,2835604,32406664,-3839045,-641708,-101325 }, }, { { 10861363,11473154,27284546,1981175,-30064349,12577861,32867885,14515107,-15438304,10819380 }, { 4708026,6336745,20377586,9066809,-11272109,6594696,-25653668,12483688,-12668491,5581306 }, { 19563160,16186464,-29386857,4097519,10237984,-4348115,28542350,13850243,-23678021,-15815942 }, }, { { -15371964,-12862754,32573250,4720197,-26436522,5875511,-19188627,-15224819,-9818940,-12085777 }, { -8549212,109983,15149363,2178705,22900618,4543417,3044240,-15689887,1762328,14866737 }, { -18199695,-15951423,-10473290,1707278,-17185920,3916101,-28236412,3959421,27914454,4383652 }, }, { { 5153746,9909285,1723747,-2777874,30523605,5516873,19480852,5230134,-23952439,-15175766 }, { -30269007,-3463509,7665486,10083793,28475525,1649722,20654025,16520125,30598449,7715701 }, { 28881845,14381568,9657904,3680757,-20181635,7843316,-31400660,1370708,29794553,-1409300 }, }, { { 14499471,-2729599,-33191113,-4254652,28494862,14271267,30290735,10876454,-33154098,2381726 }, { -7195431,-2655363,-14730155,462251,-27724326,3941372,-6236617,3696005,-32300832,15351955 }, { 27431194,8222322,16448760,-3907995,-18707002,11938355,-32961401,-2970515,29551813,10109425 }, }, }, { { { -13657040,-13155431,-31283750,11777098,21447386,6519384,-2378284,-1627556,10092783,-4764171 }, { 27939166,14210322,4677035,16277044,-22964462,-12398139,-32508754,12005538,-17810127,12803510 }, { 17228999,-15661624,-1233527,300140,-1224870,-11714777,30364213,-9038194,18016357,4397660 }, }, { { -10958843,-7690207,4776341,-14954238,27850028,-15602212,-26619106,14544525,-17477504,982639 }, { 29253598,15796703,-2863982,-9908884,10057023,3163536,7332899,-4120128,-21047696,9934963 }, { 5793303,16271923,-24131614,-10116404,29188560,1206517,-14747930,4559895,-30123922,-10897950 }, }, { { -27643952,-11493006,16282657,-11036493,28414021,-15012264,24191034,4541697,-13338309,5500568 }, { 12650548,-1497113,9052871,11355358,-17680037,-8400164,-17430592,12264343,10874051,13524335 }, { 25556948,-3045990,714651,2510400,23394682,-10415330,33119038,5080568,-22528059,5376628 }, }, { { -26088264,-4011052,-17013699,-3537628,-6726793,1920897,-22321305,-9447443,4535768,1569007 }, { -2255422,14606630,-21692440,-8039818,28430649,8775819,-30494562,3044290,31848280,12543772 }, { -22028579,2943893,-31857513,6777306,13784462,-4292203,-27377195,-2062731,7718482,14474653 }, }, { { 2385315,2454213,-22631320,46603,-4437935,-15680415,656965,-7236665,24316168,-5253567 }, { 13741529,10911568,-33233417,-8603737,-20177830,-1033297,33040651,-13424532,-20729456,8321686 }, { 21060490,-2212744,15712757,-4336099,1639040,10656336,23845965,-11874838,-9984458,608372 }, }, { { -13672732,-15087586,-10889693,-7557059,-6036909,11305547,1123968,-6780577,27229399,23887 }, { -23244140,-294205,-11744728,14712571,-29465699,-2029617,12797024,-6440308,-1633405,16678954 }, { -29500620,4770662,-16054387,14001338,7830047,9564805,-1508144,-4795045,-17169265,4904953 }, }, { { 24059557,14617003,19037157,-15039908,19766093,-14906429,5169211,16191880,2128236,-4326833 }, { -16981152,4124966,-8540610,-10653797,30336522,-14105247,-29806336,916033,-6882542,-2986532 }, { -22630907,12419372,-7134229,-7473371,-16478904,16739175,285431,2763829,15736322,4143876 }, }, { { 2379352,11839345,-4110402,-5988665,11274298,794957,212801,-14594663,23527084,-16458268 }, { 33431127,-11130478,-17838966,-15626900,8909499,8376530,-32625340,4087881,-15188911,-14416214 }, { 1767683,7197987,-13205226,-2022635,-13091350,448826,5799055,4357868,-4774191,-16323038 }, }, }, { { { 6721966,13833823,-23523388,-1551314,26354293,-11863321,23365147,-3949732,7390890,2759800 }, { 4409041,2052381,23373853,10530217,7676779,-12885954,21302353,-4264057,1244380,-12919645 }, { -4421239,7169619,4982368,-2957590,30256825,-2777540,14086413,9208236,15886429,16489664 }, }, { { 1996075,10375649,14346367,13311202,-6874135,-16438411,-13693198,398369,-30606455,-712933 }, { -25307465,9795880,-2777414,14878809,-33531835,14780363,13348553,12076947,-30836462,5113182 }, { -17770784,11797796,31950843,13929123,-25888302,12288344,-30341101,-7336386,13847711,5387222 }, }, { { -18582163,-3416217,17824843,-2340966,22744343,-10442611,8763061,3617786,-19600662,10370991 }, { 20246567,-14369378,22358229,-543712,18507283,-10413996,14554437,-8746092,32232924,16763880 }, { 9648505,10094563,26416693,14745928,-30374318,-6472621,11094161,15689506,3140038,-16510092 }, }, { { -16160072,5472695,31895588,4744994,8823515,10365685,-27224800,9448613,-28774454,366295 }, { 19153450,11523972,-11096490,-6503142,-24647631,5420647,28344573,8041113,719605,11671788 }, { 8678025,2694440,-6808014,2517372,4964326,11152271,-15432916,-15266516,27000813,-10195553 }, }, { { -15157904,7134312,8639287,-2814877,-7235688,10421742,564065,5336097,6750977,-14521026 }, { 11836410,-3979488,26297894,16080799,23455045,15735944,1695823,-8819122,8169720,16220347 }, { -18115838,8653647,17578566,-6092619,-8025777,-16012763,-11144307,-2627664,-5990708,-14166033 }, }, { { -23308498,-10968312,15213228,-10081214,-30853605,-11050004,27884329,2847284,2655861,1738395 }, { -27537433,-14253021,-25336301,-8002780,-9370762,8129821,21651608,-3239336,-19087449,-11005278 }, { 1533110,3437855,23735889,459276,29970501,11335377,26030092,5821408,10478196,8544890 }, }, { { 32173121,-16129311,24896207,3921497,22579056,-3410854,19270449,12217473,17789017,-3395995 }, { -30552961,-2228401,-15578829,-10147201,13243889,517024,15479401,-3853233,30460520,1052596 }, { -11614875,13323618,32618793,8175907,-15230173,12596687,27491595,-4612359,3179268,-9478891 }, }, { { 31947069,-14366651,-4640583,-15339921,-15125977,-6039709,-14756777,-16411740,19072640,-9511060 }, { 11685058,11822410,3158003,-13952594,33402194,-4165066,5977896,-5215017,473099,5040608 }, { -20290863,8198642,-27410132,11602123,1290375,-2799760,28326862,1721092,-19558642,-3131606 }, }, }, { { { 7881532,10687937,7578723,7738378,-18951012,-2553952,21820786,8076149,-27868496,11538389 }, { -19935666,3899861,18283497,-6801568,-15728660,-11249211,8754525,7446702,-5676054,5797016 }, { -11295600,-3793569,-15782110,-7964573,12708869,-8456199,2014099,-9050574,-2369172,-5877341 }, }, { { -22472376,-11568741,-27682020,1146375,18956691,16640559,1192730,-3714199,15123619,10811505 }, { 14352098,-3419715,-18942044,10822655,32750596,4699007,-70363,15776356,-28886779,-11974553 }, { -28241164,-8072475,-4978962,-5315317,29416931,1847569,-20654173,-16484855,4714547,-9600655 }, }, { { 15200332,8368572,19679101,15970074,-31872674,1959451,24611599,-4543832,-11745876,12340220 }, { 12876937,-10480056,33134381,6590940,-6307776,14872440,9613953,8241152,15370987,9608631 }, { -4143277,-12014408,8446281,-391603,4407738,13629032,-7724868,15866074,-28210621,-8814099 }, }, { { 26660628,-15677655,8393734,358047,-7401291,992988,-23904233,858697,20571223,8420556 }, { 14620715,13067227,-15447274,8264467,14106269,15080814,33531827,12516406,-21574435,-12476749 }, { 236881,10476226,57258,-14677024,6472998,2466984,17258519,7256740,8791136,15069930 }, }, { { 1276410,-9371918,22949635,-16322807,-23493039,-5702186,14711875,4874229,-30663140,-2331391 }, { 5855666,4990204,-13711848,7294284,-7804282,1924647,-1423175,-7912378,-33069337,9234253 }, { 20590503,-9018988,31529744,-7352666,-2706834,10650548,31559055,-11609587,18979186,13396066 }, }, { { 24474287,4968103,22267082,4407354,24063882,-8325180,-18816887,13594782,33514650,7021958 }, { -11566906,-6565505,-21365085,15928892,-26158305,4315421,-25948728,-3916677,-21480480,12868082 }, { -28635013,13504661,19988037,-2132761,21078225,6443208,-21446107,2244500,-12455797,-8089383 }, }, { { -30595528,13793479,-5852820,319136,-25723172,-6263899,33086546,8957937,-15233648,5540521 }, { -11630176,-11503902,-8119500,-7643073,2620056,1022908,-23710744,-1568984,-16128528,-14962807 }, { 23152971,775386,27395463,14006635,-9701118,4649512,1689819,892185,-11513277,-15205948 }, }, { { 9770129,9586738,26496094,4324120,1556511,-3550024,27453819,4763127,-19179614,5867134 }, { -32765025,1927590,31726409,-4753295,23962434,-16019500,27846559,5931263,-29749703,-16108455 }, { 27461885,-2977536,22380810,1815854,-23033753,-3031938,7283490,-15148073,-19526700,7734629 }, }, }, { { { -8010264,-9590817,-11120403,6196038,29344158,-13430885,7585295,-3176626,18549497,15302069 }, { -32658337,-6171222,-7672793,-11051681,6258878,13504381,10458790,-6418461,-8872242,8424746 }, { 24687205,8613276,-30667046,-3233545,1863892,-1830544,19206234,7134917,-11284482,-828919 }, }, { { 11334899,-9218022,8025293,12707519,17523892,-10476071,10243738,-14685461,-5066034,16498837 }, { 8911542,6887158,-9584260,-6958590,11145641,-9543680,17303925,-14124238,6536641,10543906 }, { -28946384,15479763,-17466835,568876,-1497683,11223454,-2669190,-16625574,-27235709,8876771 }, }, { { -25742899,-12566864,-15649966,-846607,-33026686,-796288,-33481822,15824474,-604426,-9039817 }, { 10330056,70051,7957388,-9002667,9764902,15609756,27698697,-4890037,1657394,3084098 }, { 10477963,-7470260,12119566,-13250805,29016247,-5365589,31280319,14396151,-30233575,15272409 }, }, { { -12288309,3169463,28813183,16658753,25116432,-5630466,-25173957,-12636138,-25014757,1950504 }, { -26180358,9489187,11053416,-14746161,-31053720,5825630,-8384306,-8767532,15341279,8373727 }, { 28685821,7759505,-14378516,-12002860,-31971820,4079242,298136,-10232602,-2878207,15190420 }, }, { { -32932876,13806336,-14337485,-15794431,-24004620,10940928,8669718,2742393,-26033313,-6875003 }, { -1580388,-11729417,-25979658,-11445023,-17411874,-10912854,9291594,-16247779,-12154742,6048605 }, { -30305315,14843444,1539301,11864366,20201677,1900163,13934231,5128323,11213262,9168384 }, }, { { -26280513,11007847,19408960,-940758,-18592965,-4328580,-5088060,-11105150,20470157,-16398701 }, { -23136053,9282192,14855179,-15390078,-7362815,-14408560,-22783952,14461608,14042978,5230683 }, { 29969567,-2741594,-16711867,-8552442,9175486,-2468974,21556951,3506042,-5933891,-12449708 }, }, { { -3144746,8744661,19704003,4581278,-20430686,6830683,-21284170,8971513,-28539189,15326563 }, { -19464629,10110288,-17262528,-3503892,-23500387,1355669,-15523050,15300988,-20514118,9168260 }, { -5353335,4488613,-23803248,16314347,7780487,-15638939,-28948358,9601605,33087103,-9011387 }, }, { { -19443170,-15512900,-20797467,-12445323,-29824447,10229461,-27444329,-15000531,-5996870,15664672 }, { 23294591,-16632613,-22650781,-8470978,27844204,11461195,13099750,-2460356,18151676,13417686 }, { -24722913,-4176517,-31150679,5988919,-26858785,6685065,1661597,-12551441,15271676,-15452665 }, }, }, { { { 11433042,-13228665,8239631,-5279517,-1985436,-725718,-18698764,2167544,-6921301,-13440182 }, { -31436171,15575146,30436815,12192228,-22463353,9395379,-9917708,-8638997,12215110,12028277 }, { 14098400,6555944,23007258,5757252,-15427832,-12950502,30123440,4617780,-16900089,-655628 }, }, { { -4026201,-15240835,11893168,13718664,-14809462,1847385,-15819999,10154009,23973261,-12684474 }, { -26531820,-3695990,-1908898,2534301,-31870557,-16550355,18341390,-11419951,32013174,-10103539 }, { -25479301,10876443,-11771086,-14625140,-12369567,1838104,21911214,6354752,4425632,-837822 }, }, { { -10433389,-14612966,22229858,-3091047,-13191166,776729,-17415375,-12020462,4725005,14044970 }, { 19268650,-7304421,1555349,8692754,-21474059,-9910664,6347390,-1411784,-19522291,-16109756 }, { -24864089,12986008,-10898878,-5558584,-11312371,-148526,19541418,8180106,9282262,10282508 }, }, { { -26205082,4428547,-8661196,-13194263,4098402,-14165257,15522535,8372215,5542595,-10702683 }, { -10562541,14895633,26814552,-16673850,-17480754,-2489360,-2781891,6993761,-18093885,10114655 }, { -20107055,-929418,31422704,10427861,-7110749,6150669,-29091755,-11529146,25953725,-106158 }, }, { { -4234397,-8039292,-9119125,3046000,2101609,-12607294,19390020,6094296,-3315279,12831125 }, { -15998678,7578152,5310217,14408357,-33548620,-224739,31575954,6326196,7381791,-2421839 }, { -20902779,3296811,24736065,-16328389,18374254,7318640,6295303,8082724,-15362489,12339664 }, }, { { 27724736,2291157,6088201,-14184798,1792727,5857634,13848414,15768922,25091167,14856294 }, { -18866652,8331043,24373479,8541013,-701998,-9269457,12927300,-12695493,-22182473,-9012899 }, { -11423429,-5421590,11632845,3405020,30536730,-11674039,-27260765,13866390,30146206,9142070 }, }, { { 3924129,-15307516,-13817122,-10054960,12291820,-668366,-27702774,9326384,-8237858,4171294 }, { -15921940,16037937,6713787,16606682,-21612135,2790944,26396185,3731949,345228,-5462949 }, { -21327538,13448259,25284571,1143661,20614966,-8849387,2031539,-12391231,-16253183,-13582083 }, }, { { 31016211,-16722429,26371392,-14451233,-5027349,14854137,17477601,3842657,28012650,-16405420 }, { -5075835,9368966,-8562079,-4600902,-15249953,6970560,-9189873,16292057,-8867157,3507940 }, { 29439664,3537914,23333589,6997794,-17555561,-11018068,-15209202,-15051267,-9164929,6580396 }, }, }, { { { -12185861,-7679788,16438269,10826160,-8696817,-6235611,17860444,-9273846,-2095802,9304567 }, { 20714564,-4336911,29088195,7406487,11426967,-5095705,14792667,-14608617,5289421,-477127 }, { -16665533,-10650790,-6160345,-13305760,9192020,-1802462,17271490,12349094,26939669,-3752294 }, }, { { -12889898,9373458,31595848,16374215,21471720,13221525,-27283495,-12348559,-3698806,117887 }, { 22263325,-6560050,3984570,-11174646,-15114008,-566785,28311253,5358056,-23319780,541964 }, { 16259219,3261970,2309254,-15534474,-16885711,-4581916,24134070,-16705829,-13337066,-13552195 }, }, { { 9378160,-13140186,-22845982,-12745264,28198281,-7244098,-2399684,-717351,690426,14876244 }, { 24977353,-314384,-8223969,-13465086,28432343,-1176353,-13068804,-12297348,-22380984,6618999 }, { -1538174,11685646,12944378,13682314,-24389511,-14413193,8044829,-13817328,32239829,-5652762 }, }, { { -18603066,4762990,-926250,8885304,-28412480,-3187315,9781647,-10350059,32779359,5095274 }, { -33008130,-5214506,-32264887,-3685216,9460461,-9327423,-24601656,14506724,21639561,-2630236 }, { -16400943,-13112215,25239338,15531969,3987758,-4499318,-1289502,-6863535,17874574,558605 }, }, { { -13600129,10240081,9171883,16131053,-20869254,9599700,33499487,5080151,2085892,5119761 }, { -22205145,-2519528,-16381601,414691,-25019550,2170430,30634760,-8363614,-31999993,-5759884 }, { -6845704,15791202,8550074,-1312654,29928809,-12092256,27534430,-7192145,-22351378,12961482 }, }, { { -24492060,-9570771,10368194,11582341,-23397293,-2245287,16533930,8206996,-30194652,-5159638 }, { -11121496,-3382234,2307366,6362031,-135455,8868177,-16835630,7031275,7589640,8945490 }, { -32152748,8917967,6661220,-11677616,-1192060,-15793393,7251489,-11182180,24099109,-14456170 }, }, { { 5019558,-7907470,4244127,-14714356,-26933272,6453165,-19118182,-13289025,-6231896,-10280736 }, { 10853594,10721687,26480089,5861829,-22995819,1972175,-1866647,-10557898,-3363451,-6441124 }, { -17002408,5906790,221599,-6563147,7828208,-13248918,24362661,-2008168,-13866408,7421392 }, }, { { 8139927,-6546497,32257646,-5890546,30375719,1886181,-21175108,15441252,28826358,-4123029 }, { 6267086,9695052,7709135,-16603597,-32869068,-1886135,14795160,-7840124,13746021,-1742048 }, { 28584902,7787108,-6732942,-15050729,22846041,-7571236,-3181936,-363524,4771362,-8419958 }, }, }, { { { 24949256,6376279,-27466481,-8174608,-18646154,-9930606,33543569,-12141695,3569627,11342593 }, { 26514989,4740088,27912651,3697550,19331575,-11472339,6809886,4608608,7325975,-14801071 }, { -11618399,-14554430,-24321212,7655128,-1369274,5214312,-27400540,10258390,-17646694,-8186692 }, }, { { 11431204,15823007,26570245,14329124,18029990,4796082,-31446179,15580664,9280358,-3973687 }, { -160783,-10326257,-22855316,-4304997,-20861367,-13621002,-32810901,-11181622,-15545091,4387441 }, { -20799378,12194512,3937617,-5805892,-27154820,9340370,-24513992,8548137,20617071,-7482001 }, }, { { -938825,-3930586,-8714311,16124718,24603125,-6225393,-13775352,-11875822,24345683,10325460 }, { -19855277,-1568885,-22202708,8714034,14007766,6928528,16318175,-1010689,4766743,3552007 }, { -21751364,-16730916,1351763,-803421,-4009670,3950935,3217514,14481909,10988822,-3994762 }, }, { { 15564307,-14311570,3101243,5684148,30446780,-8051356,12677127,-6505343,-8295852,13296005 }, { -9442290,6624296,-30298964,-11913677,-4670981,-2057379,31521204,9614054,-30000824,12074674 }, { 4771191,-135239,14290749,-13089852,27992298,14998318,-1413936,-1556716,29832613,-16391035 }, }, { { 7064884,-7541174,-19161962,-5067537,-18891269,-2912736,25825242,5293297,-27122660,13101590 }, { -2298563,2439670,-7466610,1719965,-27267541,-16328445,32512469,-5317593,-30356070,-4190957 }, { -30006540,10162316,-33180176,3981723,-16482138,-13070044,14413974,9515896,19568978,9628812 }, }, { { 33053803,199357,15894591,1583059,27380243,-4580435,-17838894,-6106839,-6291786,3437740 }, { -18978877,3884493,19469877,12726490,15913552,13614290,-22961733,70104,7463304,4176122 }, { -27124001,10659917,11482427,-16070381,12771467,-6635117,-32719404,-5322751,24216882,5944158 }, }, { { 8894125,7450974,-2664149,-9765752,-28080517,-12389115,19345746,14680796,11632993,5847885 }, { 26942781,-2315317,9129564,-4906607,26024105,11769399,-11518837,6367194,-9727230,4782140 }, { 19916461,-4828410,-22910704,-11414391,25606324,-5972441,33253853,8220911,6358847,-1873857 }, }, { { 801428,-2081702,16569428,11065167,29875704,96627,7908388,-4480480,-13538503,1387155 }, { 19646058,5720633,-11416706,12814209,11607948,12749789,14147075,15156355,-21866831,11835260 }, { 19299512,1155910,28703737,14890794,2925026,7269399,26121523,15467869,-26560550,5052483 }, }, }, { { { -3017432,10058206,1980837,3964243,22160966,12322533,-6431123,-12618185,12228557,-7003677 }, { 32944382,14922211,-22844894,5188528,21913450,-8719943,4001465,13238564,-6114803,8653815 }, { 22865569,-4652735,27603668,-12545395,14348958,8234005,24808405,5719875,28483275,2841751 }, }, { { -16420968,-1113305,-327719,-12107856,21886282,-15552774,-1887966,-315658,19932058,-12739203 }, { -11656086,10087521,-8864888,-5536143,-19278573,-3055912,3999228,13239134,-4777469,-13910208 }, { 1382174,-11694719,17266790,9194690,-13324356,9720081,20403944,11284705,-14013818,3093230 }, }, { { 16650921,-11037932,-1064178,1570629,-8329746,7352753,-302424,16271225,-24049421,-6691850 }, { -21911077,-5927941,-4611316,-5560156,-31744103,-10785293,24123614,15193618,-21652117,-16739389 }, { -9935934,-4289447,-25279823,4372842,2087473,10399484,31870908,14690798,17361620,11864968 }, }, { { -11307610,6210372,13206574,5806320,-29017692,-13967200,-12331205,-7486601,-25578460,-16240689 }, { 14668462,-12270235,26039039,15305210,25515617,4542480,10453892,6577524,9145645,-6443880 }, { 5974874,3053895,-9433049,-10385191,-31865124,3225009,-7972642,3936128,-5652273,-3050304 }, }, { { 30625386,-4729400,-25555961,-12792866,-20484575,7695099,17097188,-16303496,-27999779,1803632 }, { -3553091,9865099,-5228566,4272701,-5673832,-16689700,14911344,12196514,-21405489,7047412 }, { 20093277,9920966,-11138194,-5343857,13161587,12044805,-32856851,4124601,-32343828,-10257566 }, }, { { -20788824,14084654,-13531713,7842147,19119038,-13822605,4752377,-8714640,-21679658,2288038 }, { -26819236,-3283715,29965059,3039786,-14473765,2540457,29457502,14625692,-24819617,12570232 }, { -1063558,-11551823,16920318,12494842,1278292,-5869109,-21159943,-3498680,-11974704,4724943 }, }, { { 17960970,-11775534,-4140968,-9702530,-8876562,-1410617,-12907383,-8659932,-29576300,1903856 }, { 23134274,-14279132,-10681997,-1611936,20684485,15770816,-12989750,3190296,26955097,14109738 }, { 15308788,5320727,-30113809,-14318877,22902008,7767164,29425325,-11277562,31960942,11934971 }, }, { { -27395711,8435796,4109644,12222639,-24627868,14818669,20638173,4875028,10491392,1379718 }, { -13159415,9197841,3875503,-8936108,-1383712,-5879801,33518459,16176658,21432314,12180697 }, { -11787308,11500838,13787581,-13832590,-22430679,10140205,1465425,12689540,-10301319,-13872883 }, }, }, { { { 5414091,-15386041,-21007664,9643570,12834970,1186149,-2622916,-1342231,26128231,6032912 }, { -26337395,-13766162,32496025,-13653919,17847801,-12669156,3604025,8316894,-25875034,-10437358 }, { 3296484,6223048,24680646,-12246460,-23052020,5903205,-8862297,-4639164,12376617,3188849 }, }, { { 29190488,-14659046,27549113,-1183516,3520066,-10697301,32049515,-7309113,-16109234,-9852307 }, { -14744486,-9309156,735818,-598978,-20407687,-5057904,25246078,-15795669,18640741,-960977 }, { -6928835,-16430795,10361374,5642961,4910474,12345252,-31638386,-494430,10530747,1053335 }, }, { { -29265967,-14186805,-13538216,-12117373,-19457059,-10655384,-31462369,-2948985,24018831,15026644 }, { -22592535,-3145277,-2289276,5953843,-13440189,9425631,25310643,13003497,-2314791,-15145616 }, { -27419985,-603321,-8043984,-1669117,-26092265,13987819,-27297622,187899,-23166419,-2531735 }, }, { { -21744398,-13810475,1844840,5021428,-10434399,-15911473,9716667,16266922,-5070217,726099 }, { 29370922,-6053998,7334071,-15342259,9385287,2247707,-13661962,-4839461,30007388,-15823341 }, { -936379,16086691,23751945,-543318,-1167538,-5189036,9137109,730663,9835848,4555336 }, }, { { -23376435,1410446,-22253753,-12899614,30867635,15826977,17693930,544696,-11985298,12422646 }, { 31117226,-12215734,-13502838,6561947,-9876867,-12757670,-5118685,-4096706,29120153,13924425 }, { -17400879,-14233209,19675799,-2734756,-11006962,-5858820,-9383939,-11317700,7240931,-237388 }, }, { { -31361739,-11346780,-15007447,-5856218,-22453340,-12152771,1222336,4389483,3293637,-15551743 }, { -16684801,-14444245,11038544,11054958,-13801175,-3338533,-24319580,7733547,12796905,-6335822 }, { -8759414,-10817836,-25418864,10783769,-30615557,-9746811,-28253339,3647836,3222231,-11160462 }, }, { { 18606113,1693100,-25448386,-15170272,4112353,10045021,23603893,-2048234,-7550776,2484985 }, { 9255317,-3131197,-12156162,-1004256,13098013,-9214866,16377220,-2102812,-19802075,-3034702 }, { -22729289,7496160,-5742199,11329249,19991973,-3347502,-31718148,9936966,-30097688,-10618797 }, }, { { 21878590,-5001297,4338336,13643897,-3036865,13160960,19708896,5415497,-7360503,-4109293 }, { 27736861,10103576,12500508,8502413,-3413016,-9633558,10436918,-1550276,-23659143,-8132100 }, { 19492550,-12104365,-29681976,-852630,-3208171,12403437,30066266,8367329,13243957,8709688 }, }, }, { { { 12015105,2801261,28198131,10151021,24818120,-4743133,-11194191,-5645734,5150968,7274186 }, { 2831366,-12492146,1478975,6122054,23825128,-12733586,31097299,6083058,31021603,-9793610 }, { -2529932,-2229646,445613,10720828,-13849527,-11505937,-23507731,16354465,15067285,-14147707 }, }, { { 7840942,14037873,-33364863,15934016,-728213,-3642706,21403988,1057586,-19379462,-12403220 }, { 915865,-16469274,15608285,-8789130,-24357026,6060030,-17371319,8410997,-7220461,16527025 }, { 32922597,-556987,20336074,-16184568,10903705,-5384487,16957574,52992,23834301,6588044 }, }, { { 32752030,11232950,3381995,-8714866,22652988,-10744103,17159699,16689107,-20314580,-1305992 }, { -4689649,9166776,-25710296,-10847306,11576752,12733943,7924251,-2752281,1976123,-7249027 }, { 21251222,16309901,-2983015,-6783122,30810597,12967303,156041,-3371252,12331345,-8237197 }, }, { { 8651614,-4477032,-16085636,-4996994,13002507,2950805,29054427,-5106970,10008136,-4667901 }, { 31486080,15114593,-14261250,12951354,14369431,-7387845,16347321,-13662089,8684155,-10532952 }, { 19443825,11385320,24468943,-9659068,-23919258,2187569,-26263207,-6086921,31316348,14219878 }, }, { { -28594490,1193785,32245219,11392485,31092169,15722801,27146014,6992409,29126555,9207390 }, { 32382935,1110093,18477781,11028262,-27411763,-7548111,-4980517,10843782,-7957600,-14435730 }, { 2814918,7836403,27519878,-7868156,-20894015,-11553689,-21494559,8550130,28346258,1994730 }, }, { { -19578299,8085545,-14000519,-3948622,2785838,-16231307,-19516951,7174894,22628102,8115180 }, { -30405132,955511,-11133838,-15078069,-32447087,-13278079,-25651578,3317160,-9943017,930272 }, { -15303681,-6833769,28856490,1357446,23421993,1057177,24091212,-1388970,-22765376,-10650715 }, }, { { -22751231,-5303997,-12907607,-12768866,-15811511,-7797053,-14839018,-16554220,-1867018,8398970 }, { -31969310,2106403,-4736360,1362501,12813763,16200670,22981545,-6291273,18009408,-15772772 }, { -17220923,-9545221,-27784654,14166835,29815394,7444469,29551787,-3727419,19288549,1325865 }, }, { { 15100157,-15835752,-23923978,-1005098,-26450192,15509408,12376730,-3479146,33166107,-8042750 }, { 20909231,13023121,-9209752,16251778,-5778415,-8094914,12412151,10018715,2213263,-13878373 }, { 32529814,-11074689,30361439,-16689753,-9135940,1513226,22922121,6382134,-5766928,8371348 }, }, }, { { { 9923462,11271500,12616794,3544722,-29998368,-1721626,12891687,-8193132,-26442943,10486144 }, { -22597207,-7012665,8587003,-8257861,4084309,-12970062,361726,2610596,-23921530,-11455195 }, { 5408411,-1136691,-4969122,10561668,24145918,14240566,31319731,-4235541,19985175,-3436086 }, }, { { -13994457,16616821,14549246,3341099,32155958,13648976,-17577068,8849297,65030,8370684 }, { -8320926,-12049626,31204563,5839400,-20627288,-1057277,-19442942,6922164,12743482,-9800518 }, { -2361371,12678785,28815050,4759974,-23893047,4884717,23783145,11038569,18800704,255233 }, }, { { -5269658,-1773886,13957886,7990715,23132995,728773,13393847,9066957,19258688,-14753793 }, { -2936654,-10827535,-10432089,14516793,-3640786,4372541,-31934921,2209390,-1524053,2055794 }, { 580882,16705327,5468415,-2683018,-30926419,-14696000,-7203346,-8994389,-30021019,7394435 }, }, { { 23838809,1822728,-15738443,15242727,8318092,-3733104,-21672180,-3492205,-4821741,14799921 }, { 13345610,9759151,3371034,-16137791,16353039,8577942,31129804,13496856,-9056018,7402518 }, { 2286874,-4435931,-20042458,-2008336,-13696227,5038122,11006906,-15760352,8205061,1607563 }, }, { { 14414086,-8002132,3331830,-3208217,22249151,-5594188,18364661,-2906958,30019587,-9029278 }, { -27688051,1585953,-10775053,931069,-29120221,-11002319,-14410829,12029093,9944378,8024 }, { 4368715,-3709630,29874200,-15022983,-20230386,-11410704,-16114594,-999085,-8142388,5640030 }, }, { { 10299610,13746483,11661824,16234854,7630238,5998374,9809887,-16694564,15219798,-14327783 }, { 27425505,-5719081,3055006,10660664,23458024,595578,-15398605,-1173195,-18342183,9742717 }, { 6744077,2427284,26042789,2720740,-847906,1118974,32324614,7406442,12420155,1994844 }, }, { { 14012521,-5024720,-18384453,-9578469,-26485342,-3936439,-13033478,-10909803,24319929,-6446333 }, { 16412690,-4507367,10772641,15929391,-17068788,-4658621,10555945,-10484049,-30102368,-4739048 }, { 22397382,-7767684,-9293161,-12792868,17166287,-9755136,-27333065,6199366,21880021,-12250760 }, }, { { -4283307,5368523,-31117018,8163389,-30323063,3209128,16557151,8890729,8840445,4957760 }, { -15447727,709327,-6919446,-10870178,-29777922,6522332,-21720181,12130072,-14796503,5005757 }, { -2114751,-14308128,23019042,15765735,-25269683,6002752,10183197,-13239326,-16395286,-2176112 }, }, }, { { { -19025756,1632005,13466291,-7995100,-23640451,16573537,-32013908,-3057104,22208662,2000468 }, { 3065073,-1412761,-25598674,-361432,-17683065,-5703415,-8164212,11248527,-3691214,-7414184 }, { 10379208,-6045554,8877319,1473647,-29291284,-12507580,16690915,2553332,-3132688,16400289 }, }, { { 15716668,1254266,-18472690,7446274,-8448918,6344164,-22097271,-7285580,26894937,9132066 }, { 24158887,12938817,11085297,-8177598,-28063478,-4457083,-30576463,64452,-6817084,-2692882 }, { 13488534,7794716,22236231,5989356,25426474,-12578208,2350710,-3418511,-4688006,2364226 }, }, { { 16335052,9132434,25640582,6678888,1725628,8517937,-11807024,-11697457,15445875,-7798101 }, { 29004207,-7867081,28661402,-640412,-12794003,-7943086,31863255,-4135540,-278050,-15759279 }, { -6122061,-14866665,-28614905,14569919,-10857999,-3591829,10343412,-6976290,-29828287,-10815811 }, }, { { 27081650,3463984,14099042,-4517604,1616303,-6205604,29542636,15372179,17293797,960709 }, { 20263915,11434237,-5765435,11236810,13505955,-10857102,-16111345,6493122,-19384511,7639714 }, { -2830798,-14839232,25403038,-8215196,-8317012,-16173699,18006287,-16043750,29994677,-15808121 }, }, { { 9769828,5202651,-24157398,-13631392,-28051003,-11561624,-24613141,-13860782,-31184575,709464 }, { 12286395,13076066,-21775189,-1176622,-25003198,4057652,-32018128,-8890874,16102007,13205847 }, { 13733362,5599946,10557076,3195751,-5557991,8536970,-25540170,8525972,10151379,10394400 }, }, { { 4024660,-16137551,22436262,12276534,-9099015,-2686099,19698229,11743039,-33302334,8934414 }, { -15879800,-4525240,-8580747,-2934061,14634845,-698278,-9449077,3137094,-11536886,11721158 }, { 17555939,-5013938,8268606,2331751,-22738815,9761013,9319229,8835153,-9205489,-1280045 }, }, { { -461409,-7830014,20614118,16688288,-7514766,-4807119,22300304,505429,6108462,-6183415 }, { -5070281,12367917,-30663534,3234473,32617080,-8422642,29880583,-13483331,-26898490,-7867459 }, { -31975283,5726539,26934134,10237677,-3173717,-605053,24199304,3795095,7592688,-14992079 }, }, { { 21594432,-14964228,17466408,-4077222,32537084,2739898,6407723,12018833,-28256052,4298412 }, { -20650503,-11961496,-27236275,570498,3767144,-1717540,13891942,-1569194,13717174,10805743 }, { -14676630,-15644296,15287174,11927123,24177847,-8175568,-796431,14860609,-26938930,-5863836 }, }, }, { { { 12962541,5311799,-10060768,11658280,18855286,-7954201,13286263,-12808704,-4381056,9882022 }, { 18512079,11319350,-20123124,15090309,18818594,5271736,-22727904,3666879,-23967430,-3299429 }, { -6789020,-3146043,16192429,13241070,15898607,-14206114,-10084880,-6661110,-2403099,5276065 }, }, { { 30169808,-5317648,26306206,-11750859,27814964,7069267,7152851,3684982,1449224,13082861 }, { 10342826,3098505,2119311,193222,25702612,12233820,23697382,15056736,-21016438,-8202000 }, { -33150110,3261608,22745853,7948688,19370557,-15177665,-26171976,6482814,-10300080,-11060101 }, }, { { 32869458,-5408545,25609743,15678670,-10687769,-15471071,26112421,2521008,-22664288,6904815 }, { 29506923,4457497,3377935,-9796444,-30510046,12935080,1561737,3841096,-29003639,-6657642 }, { 10340844,-6630377,-18656632,-2278430,12621151,-13339055,30878497,-11824370,-25584551,5181966 }, }, { { 25940115,-12658025,17324188,-10307374,-8671468,15029094,24396252,-16450922,-2322852,-12388574 }, { -21765684,9916823,-1300409,4079498,-1028346,11909559,1782390,12641087,20603771,-6561742 }, { -18882287,-11673380,24849422,11501709,13161720,-4768874,1925523,11914390,4662781,7820689 }, }, { { 12241050,-425982,8132691,9393934,32846760,-1599620,29749456,12172924,16136752,15264020 }, { -10349955,-14680563,-8211979,2330220,-17662549,-14545780,10658213,6671822,19012087,3772772 }, { 3753511,-3421066,10617074,2028709,14841030,-6721664,28718732,-15762884,20527771,12988982 }, }, { { -14822485,-5797269,-3707987,12689773,-898983,-10914866,-24183046,-10564943,3299665,-12424953 }, { -16777703,-15253301,-9642417,4978983,3308785,8755439,6943197,6461331,-25583147,8991218 }, { -17226263,1816362,-1673288,-6086439,31783888,-8175991,-32948145,7417950,-30242287,1507265 }, }, { { 29692663,6829891,-10498800,4334896,20945975,-11906496,-28887608,8209391,14606362,-10647073 }, { -3481570,8707081,32188102,5672294,22096700,1711240,-33020695,9761487,4170404,-2085325 }, { -11587470,14855945,-4127778,-1531857,-26649089,15084046,22186522,16002000,-14276837,-8400798 }, }, { { -4811456,13761029,-31703877,-2483919,-3312471,7869047,-7113572,-9620092,13240845,10965870 }, { -7742563,-8256762,-14768334,-13656260,-23232383,12387166,4498947,14147411,29514390,4302863 }, { -13413405,-12407859,20757302,-13801832,14785143,8976368,-5061276,-2144373,17846988,-13971927 }, }, }, { { { -2244452,-754728,-4597030,-1066309,-6247172,1455299,-21647728,-9214789,-5222701,12650267 }, { -9906797,-16070310,21134160,12198166,-27064575,708126,387813,13770293,-19134326,10958663 }, { 22470984,12369526,23446014,-5441109,-21520802,-9698723,-11772496,-11574455,-25083830,4271862 }, }, { { -25169565,-10053642,-19909332,15361595,-5984358,2159192,75375,-4278529,-32526221,8469673 }, { 15854970,4148314,-8893890,7259002,11666551,13824734,-30531198,2697372,24154791,-9460943 }, { 15446137,-15806644,29759747,14019369,30811221,-9610191,-31582008,12840104,24913809,9815020 }, }, { { -4709286,-5614269,-31841498,-12288893,-14443537,10799414,-9103676,13438769,18735128,9466238 }, { 11933045,9281483,5081055,-5183824,-2628162,-4905629,-7727821,-10896103,-22728655,16199064 }, { 14576810,379472,-26786533,-8317236,-29426508,-10812974,-102766,1876699,30801119,2164795 }, }, { { 15995086,3199873,13672555,13712240,-19378835,-4647646,-13081610,-15496269,-13492807,1268052 }, { -10290614,-3659039,-3286592,10948818,23037027,3794475,-3470338,-12600221,-17055369,3565904 }, { 29210088,-9419337,-5919792,-4952785,10834811,-13327726,-16512102,-10820713,-27162222,-14030531 }, }, { { -13161890,15508588,16663704,-8156150,-28349942,9019123,-29183421,-3769423,2244111,-14001979 }, { -5152875,-3800936,-9306475,-6071583,16243069,14684434,-25673088,-16180800,13491506,4641841 }, { 10813417,643330,-19188515,-728916,30292062,-16600078,27548447,-7721242,14476989,-12767431 }, }, { { 10292079,9984945,6481436,8279905,-7251514,7032743,27282937,-1644259,-27912810,12651324 }, { -31185513,-813383,22271204,11835308,10201545,15351028,17099662,3988035,21721536,-3148940 }, { 10202177,-6545839,-31373232,-9574638,-32150642,-8119683,-12906320,3852694,13216206,14842320 }, }, { { -15815640,-10601066,-6538952,-7258995,-6984659,-6581778,-31500847,13765824,-27434397,9900184 }, { 14465505,-13833331,-32133984,-14738873,-27443187,12990492,33046193,15796406,-7051866,-8040114 }, { 30924417,-8279620,6359016,-12816335,16508377,9071735,-25488601,15413635,9524356,-7018878 }, }, { { 12274201,-13175547,32627641,-1785326,6736625,13267305,5237659,-5109483,15663516,4035784 }, { -2951309,8903985,17349946,601635,-16432815,-4612556,-13732739,-15889334,-22258478,4659091 }, { -16916263,-4952973,-30393711,-15158821,20774812,15897498,5736189,15026997,-2178256,-13455585 }, }, }, { { { -8858980,-2219056,28571666,-10155518,-474467,-10105698,-3801496,278095,23440562,-290208 }, { 10226241,-5928702,15139956,120818,-14867693,5218603,32937275,11551483,-16571960,-7442864 }, { 17932739,-12437276,-24039557,10749060,11316803,7535897,22503767,5561594,-3646624,3898661 }, }, { { 7749907,-969567,-16339731,-16464,-25018111,15122143,-1573531,7152530,21831162,1245233 }, { 26958459,-14658026,4314586,8346991,-5677764,11960072,-32589295,-620035,-30402091,-16716212 }, { -12165896,9166947,33491384,13673479,29787085,13096535,6280834,14587357,-22338025,13987525 }, }, { { -24349909,7778775,21116000,15572597,-4833266,-5357778,-4300898,-5124639,-7469781,-2858068 }, { 9681908,-6737123,-31951644,13591838,-6883821,386950,31622781,6439245,-14581012,4091397 }, { -8426427,1470727,-28109679,-1596990,3978627,-5123623,-19622683,12092163,29077877,-14741988 }, }, { { 5269168,-6859726,-13230211,-8020715,25932563,1763552,-5606110,-5505881,-20017847,2357889 }, { 32264008,-15407652,-5387735,-1160093,-2091322,-3946900,23104804,-12869908,5727338,189038 }, { 14609123,-8954470,-6000566,-16622781,-14577387,-7743898,-26745169,10942115,-25888931,-14884697 }, }, { { 20513500,5557931,-15604613,7829531,26413943,-2019404,-21378968,7471781,13913677,-5137875 }, { -25574376,11967826,29233242,12948236,-6754465,4713227,-8940970,14059180,12878652,8511905 }, { -25656801,3393631,-2955415,-7075526,-2250709,9366908,-30223418,6812974,5568676,-3127656 }, }, { { 11630004,12144454,2116339,13606037,27378885,15676917,-17408753,-13504373,-14395196,8070818 }, { 27117696,-10007378,-31282771,-5570088,1127282,12772488,-29845906,10483306,-11552749,-1028714 }, { 10637467,-5688064,5674781,1072708,-26343588,-6982302,-1683975,9177853,-27493162,15431203 }, }, { { 20525145,10892566,-12742472,12779443,-29493034,16150075,-28240519,14943142,-15056790,-7935931 }, { -30024462,5626926,-551567,-9981087,753598,11981191,25244767,-3239766,-3356550,9594024 }, { -23752644,2636870,-5163910,-10103818,585134,7877383,11345683,-6492290,13352335,-10977084 }, }, { { -1931799,-5407458,3304649,-12884869,17015806,-4877091,-29783850,-7752482,-13215537,-319204 }, { 20239939,6607058,6203985,3483793,-18386976,-779229,-20723742,15077870,-22750759,14523817 }, { 27406042,-6041657,27423596,-4497394,4996214,10002360,-28842031,-4545494,-30172742,-4805667 }, }, }, { { { 11374242,12660715,17861383,-12540833,10935568,1099227,-13886076,-9091740,-27727044,11358504 }, { -12730809,10311867,1510375,10778093,-2119455,-9145702,32676003,11149336,-26123651,4985768 }, { -19096303,341147,-6197485,-239033,15756973,-8796662,-983043,13794114,-19414307,-15621255 }, }, { { 6490081,11940286,25495923,-7726360,8668373,-8751316,3367603,6970005,-1691065,-9004790 }, { 1656497,13457317,15370807,6364910,13605745,8362338,-19174622,-5475723,-16796596,-5031438 }, { -22273315,-13524424,-64685,-4334223,-18605636,-10921968,-20571065,-7007978,-99853,-10237333 }, }, { { 17747465,10039260,19368299,-4050591,-20630635,-16041286,31992683,-15857976,-29260363,-5511971 }, { 31932027,-4986141,-19612382,16366580,22023614,88450,11371999,-3744247,4882242,-10626905 }, { 29796507,37186,19818052,10115756,-11829032,3352736,18551198,3272828,-5190932,-4162409 }, }, { { 12501286,4044383,-8612957,-13392385,-32430052,5136599,-19230378,-3529697,330070,-3659409 }, { 6384877,2899513,17807477,7663917,-2358888,12363165,25366522,-8573892,-271295,12071499 }, { -8365515,-4042521,25133448,-4517355,-6211027,2265927,-32769618,1936675,-5159697,3829363 }, }, { { 28425966,-5835433,-577090,-4697198,-14217555,6870930,7921550,-6567787,26333140,14267664 }, { -11067219,11871231,27385719,-10559544,-4585914,-11189312,10004786,-8709488,-21761224,8930324 }, { -21197785,-16396035,25654216,-1725397,12282012,11008919,1541940,4757911,-26491501,-16408940 }, }, { { 13537262,-7759490,-20604840,10961927,-5922820,-13218065,-13156584,6217254,-15943699,13814990 }, { -17422573,15157790,18705543,29619,24409717,-260476,27361681,9257833,-1956526,-1776914 }, { -25045300,-10191966,15366585,15166509,-13105086,8423556,-29171540,12361135,-18685978,4578290 }, }, { { 24579768,3711570,1342322,-11180126,-27005135,14124956,-22544529,14074919,21964432,8235257 }, { -6528613,-2411497,9442966,-5925588,12025640,-1487420,-2981514,-1669206,13006806,2355433 }, { -16304899,-13605259,-6632427,-5142349,16974359,-10911083,27202044,1719366,1141648,-12796236 }, }, { { -12863944,-13219986,-8318266,-11018091,-6810145,-4843894,13475066,-3133972,32674895,13715045 }, { 11423335,-5468059,32344216,8962751,24989809,9241752,-13265253,16086212,-28740881,-15642093 }, { -1409668,12530728,-6368726,10847387,19531186,-14132160,-11709148,7791794,-27245943,4383347 }, }, }, { { { -28970898,5271447,-1266009,-9736989,-12455236,16732599,-4862407,-4906449,27193557,6245191 }, { -15193956,5362278,-1783893,2695834,4960227,12840725,23061898,3260492,22510453,8577507 }, { -12632451,11257346,-32692994,13548177,-721004,10879011,31168030,13952092,-29571492,-3635906 }, }, { { 3877321,-9572739,32416692,5405324,-11004407,-13656635,3759769,11935320,5611860,8164018 }, { -16275802,14667797,15906460,12155291,-22111149,-9039718,32003002,-8832289,5773085,-8422109 }, { -23788118,-8254300,1950875,8937633,18686727,16459170,-905725,12376320,31632953,190926 }, }, { { -24593607,-16138885,-8423991,13378746,14162407,6901328,-8288749,4508564,-25341555,-3627528 }, { 8884438,-5884009,6023974,10104341,-6881569,-4941533,18722941,-14786005,-1672488,827625 }, { -32720583,-16289296,-32503547,7101210,13354605,2659080,-1800575,-14108036,-24878478,1541286 }, }, { { 2901347,-1117687,3880376,-10059388,-17620940,-3612781,-21802117,-3567481,20456845,-1885033 }, { 27019610,12299467,-13658288,-1603234,-12861660,-4861471,-19540150,-5016058,29439641,15138866 }, { 21536104,-6626420,-32447818,-10690208,-22408077,5175814,-5420040,-16361163,7779328,109896 }, }, { { 30279744,14648750,-8044871,6425558,13639621,-743509,28698390,12180118,23177719,-554075 }, { 26572847,3405927,-31701700,12890905,-19265668,5335866,-6493768,2378492,4439158,-13279347 }, { -22716706,3489070,-9225266,-332753,18875722,-1140095,14819434,-12731527,-17717757,-5461437 }, }, { { -5056483,16566551,15953661,3767752,-10436499,15627060,-820954,2177225,8550082,-15114165 }, { -18473302,16596775,-381660,15663611,22860960,15585581,-27844109,-3582739,-23260460,-8428588 }, { -32480551,15707275,-8205912,-5652081,29464558,2713815,-22725137,15860482,-21902570,1494193 }, }, { { -19562091,-14087393,-25583872,-9299552,13127842,759709,21923482,16529112,8742704,12967017 }, { -28464899,1553205,32536856,-10473729,-24691605,-406174,-8914625,-2933896,-29903758,15553883 }, { 21877909,3230008,9881174,10539357,-4797115,2841332,11543572,14513274,19375923,-12647961 }, }, { { 8832269,-14495485,13253511,5137575,5037871,4078777,24880818,-6222716,2862653,9455043 }, { 29306751,5123106,20245049,-14149889,9592566,8447059,-2077124,-2990080,15511449,4789663 }, { -20679756,7004547,8824831,-9434977,-4045704,-3750736,-5754762,108893,23513200,16652362 }, }, }, { { { -33256173,4144782,-4476029,-6579123,10770039,-7155542,-6650416,-12936300,-18319198,10212860 }, { 2756081,8598110,7383731,-6859892,22312759,-1105012,21179801,2600940,-9988298,-12506466 }, { -24645692,13317462,-30449259,-15653928,21365574,-10869657,11344424,864440,-2499677,-16710063 }, }, { { -26432803,6148329,-17184412,-14474154,18782929,-275997,-22561534,211300,2719757,4940997 }, { -1323882,3911313,-6948744,14759765,-30027150,7851207,21690126,8518463,26699843,5276295 }, { -13149873,-6429067,9396249,365013,24703301,-10488939,1321586,149635,-15452774,7159369 }, }, { { 9987780,-3404759,17507962,9505530,9731535,-2165514,22356009,8312176,22477218,-8403385 }, { 18155857,-16504990,19744716,9006923,15154154,-10538976,24256460,-4864995,-22548173,9334109 }, { 2986088,-4911893,10776628,-3473844,10620590,-7083203,-21413845,14253545,-22587149,536906 }, }, { { 4377756,8115836,24567078,15495314,11625074,13064599,7390551,10589625,10838060,-15420424 }, { -19342404,867880,9277171,-3218459,-14431572,-1986443,19295826,-15796950,6378260,699185 }, { 7895026,4057113,-7081772,-13077756,-17886831,-323126,-716039,15693155,-5045064,-13373962 }, }, { { -7737563,-5869402,-14566319,-7406919,11385654,13201616,31730678,-10962840,-3918636,-9669325 }, { 10188286,-15770834,-7336361,13427543,22223443,14896287,30743455,7116568,-21786507,5427593 }, { 696102,13206899,27047647,-10632082,15285305,-9853179,10798490,-4578720,19236243,12477404 }, }, { { -11229439,11243796,-17054270,-8040865,-788228,-8167967,-3897669,11180504,-23169516,7733644 }, { 17800790,-14036179,-27000429,-11766671,23887827,3149671,23466177,-10538171,10322027,15313801 }, { 26246234,11968874,32263343,-5468728,6830755,-13323031,-15794704,-101982,-24449242,10890804 }, }, { { -31365647,10271363,-12660625,-6267268,16690207,-13062544,-14982212,16484931,25180797,-5334884 }, { -586574,10376444,-32586414,-11286356,19801893,10997610,2276632,9482883,316878,13820577 }, { -9882808,-4510367,-2115506,16457136,-11100081,11674996,30756178,-7515054,30696930,-3712849 }, }, { { 32988917,-9603412,12499366,7910787,-10617257,-11931514,-7342816,-9985397,-32349517,7392473 }, { -8855661,15927861,9866406,-3649411,-2396914,-16655781,-30409476,-9134995,25112947,-2926644 }, { -2504044,-436966,25621774,-5678772,15085042,-5479877,-24884878,-13526194,5537438,-13914319 }, }, }, { { { -11225584,2320285,-9584280,10149187,-33444663,5808648,-14876251,-1729667,31234590,6090599 }, { -9633316,116426,26083934,2897444,-6364437,-2688086,609721,15878753,-6970405,-9034768 }, { -27757857,247744,-15194774,-9002551,23288161,-10011936,-23869595,6503646,20650474,1804084 }, }, { { -27589786,15456424,8972517,8469608,15640622,4439847,3121995,-10329713,27842616,-202328 }, { -15306973,2839644,22530074,10026331,4602058,5048462,28248656,5031932,-11375082,12714369 }, { 20807691,-7270825,29286141,11421711,-27876523,-13868230,-21227475,1035546,-19733229,12796920 }, }, { { 12076899,-14301286,-8785001,-11848922,-25012791,16400684,-17591495,-12899438,3480665,-15182815 }, { -32361549,5457597,28548107,7833186,7303070,-11953545,-24363064,-15921875,-33374054,2771025 }, { -21389266,421932,26597266,6860826,22486084,-6737172,-17137485,-4210226,-24552282,15673397 }, }, { { -20184622,2338216,19788685,-9620956,-4001265,-8740893,-20271184,4733254,3727144,-12934448 }, { 6120119,814863,-11794402,-622716,6812205,-15747771,2019594,7975683,31123697,-10958981 }, { 30069250,-11435332,30434654,2958439,18399564,-976289,12296869,9204260,-16432438,9648165 }, }, { { 32705432,-1550977,30705658,7451065,-11805606,9631813,3305266,5248604,-26008332,-11377501 }, { 17219865,2375039,-31570947,-5575615,-19459679,9219903,294711,15298639,2662509,-16297073 }, { -1172927,-7558695,-4366770,-4287744,-21346413,-8434326,32087529,-1222777,32247248,-14389861 }, }, { { 14312628,1221556,17395390,-8700143,-4945741,-8684635,-28197744,-9637817,-16027623,-13378845 }, { -1428825,-9678990,-9235681,6549687,-7383069,-468664,23046502,9803137,17597934,2346211 }, { 18510800,15337574,26171504,981392,-22241552,7827556,-23491134,-11323352,3059833,-11782870 }, }, { { 10141598,6082907,17829293,-1947643,9830092,13613136,-25556636,-5544586,-33502212,3592096 }, { 33114168,-15889352,-26525686,-13343397,33076705,8716171,1151462,1521897,-982665,-6837803 }, { -32939165,-4255815,23947181,-324178,-33072974,-12305637,-16637686,3891704,26353178,693168 }, }, { { 30374239,1595580,-16884039,13186931,4600344,406904,9585294,-400668,31375464,14369965 }, { -14370654,-7772529,1510301,6434173,-18784789,-6262728,32732230,-13108839,17901441,16011505 }, { 18171223,-11934626,-12500402,15197122,-11038147,-15230035,-19172240,-16046376,8764035,12309598 }, }, }, { { { 5975908,-5243188,-19459362,-9681747,-11541277,14015782,-23665757,1228319,17544096,-10593782 }, { 5811932,-1715293,3442887,-2269310,-18367348,-8359541,-18044043,-15410127,-5565381,12348900 }, { -31399660,11407555,25755363,6891399,-3256938,14872274,-24849353,8141295,-10632534,-585479 }, }, { { -12675304,694026,-5076145,13300344,14015258,-14451394,-9698672,-11329050,30944593,1130208 }, { 8247766,-6710942,-26562381,-7709309,-14401939,-14648910,4652152,2488540,23550156,-271232 }, { 17294316,-3788438,7026748,15626851,22990044,113481,2267737,-5908146,-408818,-137719 }, }, { { 16091085,-16253926,18599252,7340678,2137637,-1221657,-3364161,14550936,3260525,-7166271 }, { -4910104,-13332887,18550887,10864893,-16459325,-7291596,-23028869,-13204905,-12748722,2701326 }, { -8574695,16099415,4629974,-16340524,-20786213,-6005432,-10018363,9276971,11329923,1862132 }, }, { { 14763076,-15903608,-30918270,3689867,3511892,10313526,-21951088,12219231,-9037963,-940300 }, { 8894987,-3446094,6150753,3013931,301220,15693451,-31981216,-2909717,-15438168,11595570 }, { 15214962,3537601,-26238722,-14058872,4418657,-15230761,13947276,10730794,-13489462,-4363670 }, }, { { -2538306,7682793,32759013,263109,-29984731,-7955452,-22332124,-10188635,977108,699994 }, { -12466472,4195084,-9211532,550904,-15565337,12917920,19118110,-439841,-30534533,-14337913 }, { 31788461,-14507657,4799989,7372237,8808585,-14747943,9408237,-10051775,12493932,-5409317 }, }, { { -25680606,5260744,-19235809,-6284470,-3695942,16566087,27218280,2607121,29375955,6024730 }, { 842132,-2794693,-4763381,-8722815,26332018,-12405641,11831880,6985184,-9940361,2854096 }, { -4847262,-7969331,2516242,-5847713,9695691,-7221186,16512645,960770,12121869,16648078 }, }, { { -15218652,14667096,-13336229,2013717,30598287,-464137,-31504922,-7882064,20237806,2838411 }, { -19288047,4453152,15298546,-16178388,22115043,-15972604,12544294,-13470457,1068881,-12499905 }, { -9558883,-16518835,33238498,13506958,30505848,-1114596,-8486907,-2630053,12521378,4845654 }, }, { { -28198521,10744108,-2958380,10199664,7759311,-13088600,3409348,-873400,-6482306,-12885870 }, { -23561822,6230156,-20382013,10655314,-24040585,-11621172,10477734,-1240216,-3113227,13974498 }, { 12966261,15550616,-32038948,-1615346,21025980,-629444,5642325,7188737,18895762,12629579 }, }, }, { { { 14741879,-14946887,22177208,-11721237,1279741,8058600,11758140,789443,32195181,3895677 }, { 10758205,15755439,-4509950,9243698,-4879422,6879879,-2204575,-3566119,-8982069,4429647 }, { -2453894,15725973,-20436342,-10410672,-5803908,-11040220,-7135870,-11642895,18047436,-15281743 }, }, { { -25173001,-11307165,29759956,11776784,-22262383,-15820455,10993114,-12850837,-17620701,-9408468 }, { 21987233,700364,-24505048,14972008,-7774265,-5718395,32155026,2581431,-29958985,8773375 }, { -25568350,454463,-13211935,16126715,25240068,8594567,20656846,12017935,-7874389,-13920155 }, }, { { 6028182,6263078,-31011806,-11301710,-818919,2461772,-31841174,-5468042,-1721788,-2776725 }, { -12278994,16624277,987579,-5922598,32908203,1248608,7719845,-4166698,28408820,6816612 }, { -10358094,-8237829,19549651,-12169222,22082623,16147817,20613181,13982702,-10339570,5067943 }, }, { { -30505967,-3821767,12074681,13582412,-19877972,2443951,-19719286,12746132,5331210,-10105944 }, { 30528811,3601899,-1957090,4619785,-27361822,-15436388,24180793,-12570394,27679908,-1648928 }, { 9402404,-13957065,32834043,10838634,-26580150,-13237195,26653274,-8685565,22611444,-12715406 }, }, { { 22190590,1118029,22736441,15130463,-30460692,-5991321,19189625,-4648942,4854859,6622139 }, { -8310738,-2953450,-8262579,-3388049,-10401731,-271929,13424426,-3567227,26404409,13001963 }, { -31241838,-15415700,-2994250,8939346,11562230,-12840670,-26064365,-11621720,-15405155,11020693 }, }, { { 1866042,-7949489,-7898649,-10301010,12483315,13477547,3175636,-12424163,28761762,1406734 }, { -448555,-1777666,13018551,3194501,-9580420,-11161737,24760585,-4347088,25577411,-13378680 }, { -24290378,4759345,-690653,-1852816,2066747,10693769,-29595790,9884936,-9368926,4745410 }, }, { { -9141284,6049714,-19531061,-4341411,-31260798,9944276,-15462008,-11311852,10931924,-11931931 }, { -16561513,14112680,-8012645,4817318,-8040464,-11414606,-22853429,10856641,-20470770,13434654 }, { 22759489,-10073434,-16766264,-1871422,13637442,-10168091,1765144,-12654326,28445307,-5364710 }, }, { { 29875063,12493613,2795536,-3786330,1710620,15181182,-10195717,-8788675,9074234,1167180 }, { -26205683,11014233,-9842651,-2635485,-26908120,7532294,-18716888,-9535498,3843903,9367684 }, { -10969595,-6403711,9591134,9582310,11349256,108879,16235123,8601684,-139197,4242895 }, }, }, { { { 22092954,-13191123,-2042793,-11968512,32186753,-11517388,-6574341,2470660,-27417366,16625501 }, { -11057722,3042016,13770083,-9257922,584236,-544855,-7770857,2602725,-27351616,14247413 }, { 6314175,-10264892,-32772502,15957557,-10157730,168750,-8618807,14290061,27108877,-1180880 }, }, { { -8586597,-7170966,13241782,10960156,-32991015,-13794596,33547976,-11058889,-27148451,981874 }, { 22833440,9293594,-32649448,-13618667,-9136966,14756819,-22928859,-13970780,-10479804,-16197962 }, { -7768587,3326786,-28111797,10783824,19178761,14905060,22680049,13906969,-15933690,3797899 }, }, { { 21721356,-4212746,-12206123,9310182,-3882239,-13653110,23740224,-2709232,20491983,-8042152 }, { 9209270,-15135055,-13256557,-6167798,-731016,15289673,25947805,15286587,30997318,-6703063 }, { 7392032,16618386,23946583,-8039892,-13265164,-1533858,-14197445,-2321576,17649998,-250080 }, }, { { -9301088,-14193827,30609526,-3049543,-25175069,-1283752,-15241566,-9525724,-2233253,7662146 }, { -17558673,1763594,-33114336,15908610,-30040870,-12174295,7335080,-8472199,-3174674,3440183 }, { -19889700,-5977008,-24111293,-9688870,10799743,-16571957,40450,-4431835,4862400,1133 }, }, { { -32856209,-7873957,-5422389,14860950,-16319031,7956142,7258061,311861,-30594991,-7379421 }, { -3773428,-1565936,28985340,7499440,24445838,9325937,29727763,16527196,18278453,15405622 }, { -4381906,8508652,-19898366,-3674424,-5984453,15149970,-13313598,843523,-21875062,13626197 }, }, { { 2281448,-13487055,-10915418,-2609910,1879358,16164207,-10783882,3953792,13340839,15928663 }, { 31727126,-7179855,-18437503,-8283652,2875793,-16390330,-25269894,-7014826,-23452306,5964753 }, { 4100420,-5959452,-17179337,6017714,-18705837,12227141,-26684835,11344144,2538215,-7570755 }, }, { { -9433605,6123113,11159803,-2156608,30016280,14966241,-20474983,1485421,-629256,-15958862 }, { -26804558,4260919,11851389,9658551,-32017107,16367492,-20205425,-13191288,11659922,-11115118 }, { 26180396,10015009,-30844224,-8581293,5418197,9480663,2231568,-10170080,33100372,-1306171 }, }, { { 15121113,-5201871,-10389905,15427821,-27509937,-15992507,21670947,4486675,-5931810,-14466380 }, { 16166486,-9483733,-11104130,6023908,-31926798,-1364923,2340060,-16254968,-10735770,-10039824 }, { 28042865,-3557089,-12126526,12259706,-3717498,-6945899,6766453,-8689599,18036436,5803270 }, }, }, { { { -817581,6763912,11803561,1585585,10958447,-2671165,23855391,4598332,-6159431,-14117438 }, { -31031306,-14256194,17332029,-2383520,31312682,-5967183,696309,50292,-20095739,11763584 }, { -594563,-2514283,-32234153,12643980,12650761,14811489,665117,-12613632,-19773211,-10713562 }, }, { { 30464590,-11262872,-4127476,-12734478,19835327,-7105613,-24396175,2075773,-17020157,992471 }, { 18357185,-6994433,7766382,16342475,-29324918,411174,14578841,8080033,-11574335,-10601610 }, { 19598397,10334610,12555054,2555664,18821899,-10339780,21873263,16014234,26224780,16452269 }, }, { { -30223925,5145196,5944548,16385966,3976735,2009897,-11377804,-7618186,-20533829,3698650 }, { 14187449,3448569,-10636236,-10810935,-22663880,-3433596,7268410,-10890444,27394301,12015369 }, { 19695761,16087646,28032085,12999827,6817792,11427614,20244189,-1312777,-13259127,-3402461 }, }, { { 30860103,12735208,-1888245,-4699734,-16974906,2256940,-8166013,12298312,-8550524,-10393462 }, { -5719826,-11245325,-1910649,15569035,26642876,-7587760,-5789354,-15118654,-4976164,12651793 }, { -2848395,9953421,11531313,-5282879,26895123,-12697089,-13118820,-16517902,9768698,-2533218 }, }, { { -24719459,1894651,-287698,-4704085,15348719,-8156530,32767513,12765450,4940095,10678226 }, { 18860224,15980149,-18987240,-1562570,-26233012,-11071856,-7843882,13944024,-24372348,16582019 }, { -15504260,4970268,-29893044,4175593,-20993212,-2199756,-11704054,15444560,-11003761,7989037 }, }, { { 31490452,5568061,-2412803,2182383,-32336847,4531686,-32078269,6200206,-19686113,-14800171 }, { -17308668,-15879940,-31522777,-2831,-32887382,16375549,8680158,-16371713,28550068,-6857132 }, { -28126887,-5688091,16837845,-1820458,-6850681,12700016,-30039981,4364038,1155602,5988841 }, }, { { 21890435,-13272907,-12624011,12154349,-7831873,15300496,23148983,-4470481,24618407,8283181 }, { -33136107,-10512751,9975416,6841041,-31559793,16356536,3070187,-7025928,1466169,10740210 }, { -1509399,-15488185,-13503385,-10655916,32799044,909394,-13938903,-5779719,-32164649,-15327040 }, }, { { 3960823,-14267803,-28026090,-15918051,-19404858,13146868,15567327,951507,-3260321,-573935 }, { 24740841,5052253,-30094131,8961361,25877428,6165135,-24368180,14397372,-7380369,-6144105 }, { -28888365,3510803,-28103278,-1158478,-11238128,-10631454,-15441463,-14453128,-1625486,-6494814 }, }, }, { { { 793299,-9230478,8836302,-6235707,-27360908,-2369593,33152843,-4885251,-9906200,-621852 }, { 5666233,525582,20782575,-8038419,-24538499,14657740,16099374,1468826,-6171428,-15186581 }, { -4859255,-3779343,-2917758,-6748019,7778750,11688288,-30404353,-9871238,-1558923,-9863646 }, }, { { 10896332,-7719704,824275,472601,-19460308,3009587,25248958,14783338,-30581476,-15757844 }, { 10566929,12612572,-31944212,11118703,-12633376,12362879,21752402,8822496,24003793,14264025 }, { 27713862,-7355973,-11008240,9227530,27050101,2504721,23886875,-13117525,13958495,-5732453 }, }, { { -23481610,4867226,-27247128,3900521,29838369,-8212291,-31889399,-10041781,7340521,-15410068 }, { 4646514,-8011124,-22766023,-11532654,23184553,8566613,31366726,-1381061,-15066784,-10375192 }, { -17270517,12723032,-16993061,14878794,21619651,-6197576,27584817,3093888,-8843694,3849921 }, }, { { -9064912,2103172,25561640,-15125738,-5239824,9582958,32477045,-9017955,5002294,-15550259 }, { -12057553,-11177906,21115585,-13365155,8808712,-12030708,16489530,13378448,-25845716,12741426 }, { -5946367,10645103,-30911586,15390284,-3286982,-7118677,24306472,15852464,28834118,-7646072 }, }, { { -17335748,-9107057,-24531279,9434953,-8472084,-583362,-13090771,455841,20461858,5491305 }, { 13669248,-16095482,-12481974,-10203039,-14569770,-11893198,-24995986,11293807,-28588204,-9421832 }, { 28497928,6272777,-33022994,14470570,8906179,-1225630,18504674,-14165166,29867745,-8795943 }, }, { { -16207023,13517196,-27799630,-13697798,24009064,-6373891,-6367600,-13175392,22853429,-4012011 }, { 24191378,16712145,-13931797,15217831,14542237,1646131,18603514,-11037887,12876623,-2112447 }, { 17902668,4518229,-411702,-2829247,26878217,5258055,-12860753,608397,16031844,3723494 }, }, { { -28632773,12763728,-20446446,7577504,33001348,-13017745,17558842,-7872890,23896954,-4314245 }, { -20005381,-12011952,31520464,605201,2543521,5991821,-2945064,7229064,-9919646,-8826859 }, { 28816045,298879,-28165016,-15920938,19000928,-1665890,-12680833,-2949325,-18051778,-2082915 }, }, { { 16000882,-344896,3493092,-11447198,-29504595,-13159789,12577740,16041268,-19715240,7847707 }, { 10151868,10572098,27312476,7922682,14825339,4723128,-32855931,-6519018,-10020567,3852848 }, { -11430470,15697596,-21121557,-4420647,5386314,15063598,16514493,-15932110,29330899,-15076224 }, }, }, { { { -25499735,-4378794,-15222908,-6901211,16615731,2051784,3303702,15490,-27548796,12314391 }, { 15683520,-6003043,18109120,-9980648,15337968,-5997823,-16717435,15921866,16103996,-3731215 }, { -23169824,-10781249,13588192,-1628807,-3798557,-1074929,-19273607,5402699,-29815713,-9841101 }, }, { { 23190676,2384583,-32714340,3462154,-29903655,-1529132,-11266856,8911517,-25205859,2739713 }, { 21374101,-3554250,-33524649,9874411,15377179,11831242,-33529904,6134907,4931255,11987849 }, { -7732,-2978858,-16223486,7277597,105524,-322051,-31480539,13861388,-30076310,10117930 }, }, { { -29501170,-10744872,-26163768,13051539,-25625564,5089643,-6325503,6704079,12890019,15728940 }, { -21972360,-11771379,-951059,-4418840,14704840,2695116,903376,-10428139,12885167,8311031 }, { -17516482,5352194,10384213,-13811658,7506451,13453191,26423267,4384730,1888765,-5435404 }, }, { { -25817338,-3107312,-13494599,-3182506,30896459,-13921729,-32251644,-12707869,-19464434,-3340243 }, { -23607977,-2665774,-526091,4651136,5765089,4618330,6092245,14845197,17151279,-9854116 }, { -24830458,-12733720,-15165978,10367250,-29530908,-265356,22825805,-7087279,-16866484,16176525 }, }, { { -23583256,6564961,20063689,3798228,-4740178,7359225,2006182,-10363426,-28746253,-10197509 }, { -10626600,-4486402,-13320562,-5125317,3432136,-6393229,23632037,-1940610,32808310,1099883 }, { 15030977,5768825,-27451236,-2887299,-6427378,-15361371,-15277896,-6809350,2051441,-15225865 }, }, { { -3362323,-7239372,7517890,9824992,23555850,295369,5148398,-14154188,-22686354,16633660 }, { 4577086,-16752288,13249841,-15304328,19958763,-14537274,18559670,-10759549,8402478,-9864273 }, { -28406330,-1051581,-26790155,-907698,-17212414,-11030789,9453451,-14980072,17983010,9967138 }, }, { { -25762494,6524722,26585488,9969270,24709298,1220360,-1677990,7806337,17507396,3651560 }, { -10420457,-4118111,14584639,15971087,-15768321,8861010,26556809,-5574557,-18553322,-11357135 }, { 2839101,14284142,4029895,3472686,14402957,12689363,-26642121,8459447,-5605463,-7621941 }, }, { { -4839289,-3535444,9744961,2871048,25113978,3187018,-25110813,-849066,17258084,-7977739 }, { 18164541,-10595176,-17154882,-1542417,19237078,-9745295,23357533,-15217008,26908270,12150756 }, { -30264870,-7647865,5112249,-7036672,-1499807,-6974257,43168,-5537701,-32302074,16215819 }, }, }, { { { -6898905,9824394,-12304779,-4401089,-31397141,-6276835,32574489,12532905,-7503072,-8675347 }, { -27343522,-16515468,-27151524,-10722951,946346,16291093,254968,7168080,21676107,-1943028 }, { 21260961,-8424752,-16831886,-11920822,-23677961,3968121,-3651949,-6215466,-3556191,-7913075 }, }, { { 16544754,13250366,-16804428,15546242,-4583003,12757258,-2462308,-8680336,-18907032,-9662799 }, { -2415239,-15577728,18312303,4964443,-15272530,-12653564,26820651,16690659,25459437,-4564609 }, { -25144690,11425020,28423002,-11020557,-6144921,-15826224,9142795,-2391602,-6432418,-1644817 }, }, { { -23104652,6253476,16964147,-3768872,-25113972,-12296437,-27457225,-16344658,6335692,7249989 }, { -30333227,13979675,7503222,-12368314,-11956721,-4621693,-30272269,2682242,25993170,-12478523 }, { 4364628,5930691,32304656,-10044554,-8054781,15091131,22857016,-10598955,31820368,15075278 }, }, { { 31879134,-8918693,17258761,90626,-8041836,-4917709,24162788,-9650886,-17970238,12833045 }, { 19073683,14851414,-24403169,-11860168,7625278,11091125,-19619190,2074449,-9413939,14905377 }, { 24483667,-11935567,-2518866,-11547418,-1553130,15355506,-25282080,9253129,27628530,-7555480 }, }, { { 17597607,8340603,19355617,552187,26198470,-3176583,4593324,-9157582,-14110875,15297016 }, { 510886,14337390,-31785257,16638632,6328095,2713355,-20217417,-11864220,8683221,2921426 }, { 18606791,11874196,27155355,-5281482,-24031742,6265446,-25178240,-1278924,4674690,13890525 }, }, { { 13609624,13069022,-27372361,-13055908,24360586,9592974,14977157,9835105,4389687,288396 }, { 9922506,-519394,13613107,5883594,-18758345,-434263,-12304062,8317628,23388070,16052080 }, { 12720016,11937594,-31970060,-5028689,26900120,8561328,-20155687,-11632979,-14754271,-10812892 }, }, { { 15961858,14150409,26716931,-665832,-22794328,13603569,11829573,7467844,-28822128,929275 }, { 11038231,-11582396,-27310482,-7316562,-10498527,-16307831,-23479533,-9371869,-21393143,2465074 }, { 20017163,-4323226,27915242,1529148,12396362,15675764,13817261,-9658066,2463391,-4622140 }, }, { { -16358878,-12663911,-12065183,4996454,-1256422,1073572,9583558,12851107,4003896,12673717 }, { -1731589,-15155870,-3262930,16143082,19294135,13385325,14741514,-9103726,7903886,2348101 }, { 24536016,-16515207,12715592,-3862155,1511293,10047386,-3842346,-7129159,-28377538,10048127 }, }, }, { { { -12622226,-6204820,30718825,2591312,-10617028,12192840,18873298,-7297090,-32297756,15221632 }, { -26478122,-11103864,11546244,-1852483,9180880,7656409,-21343950,2095755,29769758,6593415 }, { -31994208,-2907461,4176912,3264766,12538965,-868111,26312345,-6118678,30958054,8292160 }, }, { { 31429822,-13959116,29173532,15632448,12174511,-2760094,32808831,3977186,26143136,-3148876 }, { 22648901,1402143,-22799984,13746059,7936347,365344,-8668633,-1674433,-3758243,-2304625 }, { -15491917,8012313,-2514730,-12702462,-23965846,-10254029,-1612713,-1535569,-16664475,8194478 }, }, { { 27338066,-7507420,-7414224,10140405,-19026427,-6589889,27277191,8855376,28572286,3005164 }, { 26287124,4821776,25476601,-4145903,-3764513,-15788984,-18008582,1182479,-26094821,-13079595 }, { -7171154,3178080,23970071,6201893,-17195577,-4489192,-21876275,-13982627,32208683,-1198248 }, }, { { -16657702,2817643,-10286362,14811298,6024667,13349505,-27315504,-10497842,-27672585,-11539858 }, { 15941029,-9405932,-21367050,8062055,31876073,-238629,-15278393,-1444429,15397331,-4130193 }, { 8934485,-13485467,-23286397,-13423241,-32446090,14047986,31170398,-1441021,-27505566,15087184 }, }, { { -18357243,-2156491,24524913,-16677868,15520427,-6360776,-15502406,11461896,16788528,-5868942 }, { -1947386,16013773,21750665,3714552,-17401782,-16055433,-3770287,-10323320,31322514,-11615635 }, { 21426655,-5650218,-13648287,-5347537,-28812189,-4920970,-18275391,-14621414,13040862,-12112948 }, }, { { 11293895,12478086,-27136401,15083750,-29307421,14748872,14555558,-13417103,1613711,4896935 }, { -25894883,15323294,-8489791,-8057900,25967126,-13425460,2825960,-4897045,-23971776,-11267415 }, { -15924766,-5229880,-17443532,6410664,3622847,10243618,20615400,12405433,-23753030,-8436416 }, }, { { -7091295,12556208,-20191352,9025187,-17072479,4333801,4378436,2432030,23097949,-566018 }, { 4565804,-16025654,20084412,-7842817,1724999,189254,24767264,10103221,-18512313,2424778 }, { 366633,-11976806,8173090,-6890119,30788634,5745705,-7168678,1344109,-3642553,12412659 }, }, { { -24001791,7690286,14929416,-168257,-32210835,-13412986,24162697,-15326504,-3141501,11179385 }, { 18289522,-14724954,8056945,16430056,-21729724,7842514,-6001441,-1486897,-18684645,-11443503 }, { 476239,6601091,-6152790,-9723375,17503545,-4863900,27672959,13403813,11052904,5219329 }, }, }, { { { 20678546,-8375738,-32671898,8849123,-5009758,14574752,31186971,-3973730,9014762,-8579056 }, { -13644050,-10350239,-15962508,5075808,-1514661,-11534600,-33102500,9160280,8473550,-3256838 }, { 24900749,14435722,17209120,-15292541,-22592275,9878983,-7689309,-16335821,-24568481,11788948 }, }, { { -3118155,-11395194,-13802089,14797441,9652448,-6845904,-20037437,10410733,-24568470,-1458691 }, { -15659161,16736706,-22467150,10215878,-9097177,7563911,11871841,-12505194,-18513325,8464118 }, { -23400612,8348507,-14585951,-861714,-3950205,-6373419,14325289,8628612,33313881,-8370517 }, }, { { -20186973,-4967935,22367356,5271547,-1097117,-4788838,-24805667,-10236854,-8940735,-5818269 }, { -6948785,-1795212,-32625683,-16021179,32635414,-7374245,15989197,-12838188,28358192,-4253904 }, { -23561781,-2799059,-32351682,-1661963,-9147719,10429267,-16637684,4072016,-5351664,5596589 }, }, { { -28236598,-3390048,12312896,6213178,3117142,16078565,29266239,2557221,1768301,15373193 }, { -7243358,-3246960,-4593467,-7553353,-127927,-912245,-1090902,-4504991,-24660491,3442910 }, { -30210571,5124043,14181784,8197961,18964734,-11939093,22597931,7176455,-18585478,13365930 }, }, { { -7877390,-1499958,8324673,4690079,6261860,890446,24538107,-8570186,-9689599,-3031667 }, { 25008904,-10771599,-4305031,-9638010,16265036,15721635,683793,-11823784,15723479,-15163481 }, { -9660625,12374379,-27006999,-7026148,-7724114,-12314514,11879682,5400171,519526,-1235876 }, }, { { 22258397,-16332233,-7869817,14613016,-22520255,-2950923,-20353881,7315967,16648397,7605640 }, { -8081308,-8464597,-8223311,9719710,19259459,-15348212,23994942,-5281555,-9468848,4763278 }, { -21699244,9220969,-15730624,1084137,-25476107,-2852390,31088447,-7764523,-11356529,728112 }, }, { { 26047220,-11751471,-6900323,-16521798,24092068,9158119,-4273545,-12555558,-29365436,-5498272 }, { 17510331,-322857,5854289,8403524,17133918,-3112612,-28111007,12327945,10750447,10014012 }, { -10312768,3936952,9156313,-8897683,16498692,-994647,-27481051,-666732,3424691,7540221 }, }, { { 30322361,-6964110,11361005,-4143317,7433304,4989748,-7071422,-16317219,-9244265,15258046 }, { 13054562,-2779497,19155474,469045,-12482797,4566042,5631406,2711395,1062915,-5136345 }, { -19240248,-11254599,-29509029,-7499965,-5835763,13005411,-6066489,12194497,32960380,1459310 }, }, }, { { { 19852034,7027924,23669353,10020366,8586503,-6657907,394197,-6101885,18638003,-11174937 }, { 31395534,15098109,26581030,8030562,-16527914,-5007134,9012486,-7584354,-6643087,-5442636 }, { -9192165,-2347377,-1997099,4529534,25766844,607986,-13222,9677543,-32294889,-6456008 }, }, { { -2444496,-149937,29348902,8186665,1873760,12489863,-30934579,-7839692,-7852844,-8138429 }, { -15236356,-15433509,7766470,746860,26346930,-10221762,-27333451,10754588,-9431476,5203576 }, { 31834314,14135496,-770007,5159118,20917671,-16768096,-7467973,-7337524,31809243,7347066 }, }, { { -9606723,-11874240,20414459,13033986,13716524,-11691881,19797970,-12211255,15192876,-2087490 }, { -12663563,-2181719,1168162,-3804809,26747877,-14138091,10609330,12694420,33473243,-13382104 }, { 33184999,11180355,15832085,-11385430,-1633671,225884,15089336,-11023903,-6135662,14480053 }, }, { { 31308717,-5619998,31030840,-1897099,15674547,-6582883,5496208,13685227,27595050,8737275 }, { -20318852,-15150239,10933843,-16178022,8335352,-7546022,-31008351,-12610604,26498114,66511 }, { 22644454,-8761729,-16671776,4884562,-3105614,-13559366,30540766,-4286747,-13327787,-7515095 }, }, { { -28017847,9834845,18617207,-2681312,-3401956,-13307506,8205540,13585437,-17127465,15115439 }, { 23711543,-672915,31206561,-8362711,6164647,-9709987,-33535882,-1426096,8236921,16492939 }, { -23910559,-13515526,-26299483,-4503841,25005590,-7687270,19574902,10071562,6708380,-6222424 }, }, { { 2101391,-4930054,19702731,2367575,-15427167,1047675,5301017,9328700,29955601,-11678310 }, { 3096359,9271816,-21620864,-15521844,-14847996,-7592937,-25892142,-12635595,-9917575,6216608 }, { -32615849,338663,-25195611,2510422,-29213566,-13820213,24822830,-6146567,-26767480,7525079 }, }, { { -23066649,-13985623,16133487,-7896178,-3389565,778788,-910336,-2782495,-19386633,11994101 }, { 21691500,-13624626,-641331,-14367021,3285881,-3483596,-25064666,9718258,-7477437,13381418 }, { 18445390,-4202236,14979846,11622458,-1727110,-3582980,23111648,-6375247,28535282,15779576 }, }, { { 30098053,3089662,-9234387,16662135,-21306940,11308411,-14068454,12021730,9955285,-16303356 }, { 9734894,-14576830,-7473633,-9138735,2060392,11313496,-18426029,9924399,20194861,13380996 }, { -26378102,-7965207,-22167821,15789297,-18055342,-6168792,-1984914,15707771,26342023,10146099 }, }, }, { { { -26016874,-219943,21339191,-41388,19745256,-2878700,-29637280,2227040,21612326,-545728 }, { -13077387,1184228,23562814,-5970442,-20351244,-6348714,25764461,12243797,-20856566,11649658 }, { -10031494,11262626,27384172,2271902,26947504,-15997771,39944,6114064,33514190,2333242 }, }, { { -21433588,-12421821,8119782,7219913,-21830522,-9016134,-6679750,-12670638,24350578,-13450001 }, { -4116307,-11271533,-23886186,4843615,-30088339,690623,-31536088,-10406836,8317860,12352766 }, { 18200138,-14475911,-33087759,-2696619,-23702521,-9102511,-23552096,-2287550,20712163,6719373 }, }, { { 26656208,6075253,-7858556,1886072,-28344043,4262326,11117530,-3763210,26224235,-3297458 }, { -17168938,-14854097,-3395676,-16369877,-19954045,14050420,21728352,9493610,18620611,-16428628 }, { -13323321,13325349,11432106,5964811,18609221,6062965,-5269471,-9725556,-30701573,-16479657 }, }, { { -23860538,-11233159,26961357,1640861,-32413112,-16737940,12248509,-5240639,13735342,1934062 }, { 25089769,6742589,17081145,-13406266,21909293,-16067981,-15136294,-3765346,-21277997,5473616 }, { 31883677,-7961101,1083432,-11572403,22828471,13290673,-7125085,12469656,29111212,-5451014 }, }, { { 24244947,-15050407,-26262976,2791540,-14997599,16666678,24367466,6388839,-10295587,452383 }, { -25640782,-3417841,5217916,16224624,19987036,-4082269,-24236251,-5915248,15766062,8407814 }, { -20406999,13990231,15495425,16395525,5377168,15166495,-8917023,-4388953,-8067909,2276718 }, }, { { 30157918,12924066,-17712050,9245753,19895028,3368142,-23827587,5096219,22740376,-7303417 }, { 2041139,-14256350,7783687,13876377,-25946985,-13352459,24051124,13742383,-15637599,13295222 }, { 33338237,-8505733,12532113,7977527,9106186,-1715251,-17720195,-4612972,-4451357,-14669444 }, }, { { -20045281,5454097,-14346548,6447146,28862071,1883651,-2469266,-4141880,7770569,9620597 }, { 23208068,7979712,33071466,8149229,1758231,-10834995,30945528,-1694323,-33502340,-14767970 }, { 1439958,-16270480,-1079989,-793782,4625402,10647766,-5043801,1220118,30494170,-11440799 }, }, { { -5037580,-13028295,-2970559,-3061767,15640974,-6701666,-26739026,926050,-1684339,-13333647 }, { 13908495,-3549272,30919928,-6273825,-21521863,7989039,9021034,9078865,3353509,4033511 }, { -29663431,-15113610,32259991,-344482,24295849,-12912123,23161163,8839127,27485041,7356032 }, }, }, { { { 9661027,705443,11980065,-5370154,-1628543,14661173,-6346142,2625015,28431036,-16771834 }, { -23839233,-8311415,-25945511,7480958,-17681669,-8354183,-22545972,14150565,15970762,4099461 }, { 29262576,16756590,26350592,-8793563,8529671,-11208050,13617293,-9937143,11465739,8317062 }, }, { { -25493081,-6962928,32500200,-9419051,-23038724,-2302222,14898637,3848455,20969334,-5157516 }, { -20384450,-14347713,-18336405,13884722,-33039454,2842114,-21610826,-3649888,11177095,14989547 }, { -24496721,-11716016,16959896,2278463,12066309,10137771,13515641,2581286,-28487508,9930240 }, }, { { -17751622,-2097826,16544300,-13009300,-15914807,-14949081,18345767,-13403753,16291481,-5314038 }, { -33229194,2553288,32678213,9875984,8534129,6889387,-9676774,6957617,4368891,9788741 }, { 16660756,7281060,-10830758,12911820,20108584,-8101676,-21722536,-8613148,16250552,-11111103 }, }, { { -19765507,2390526,-16551031,14161980,1905286,6414907,4689584,10604807,-30190403,4782747 }, { -1354539,14736941,-7367442,-13292886,7710542,-14155590,-9981571,4383045,22546403,437323 }, { 31665577,-12180464,-16186830,1491339,-18368625,3294682,27343084,2786261,-30633590,-14097016 }, }, { { -14467279,-683715,-33374107,7448552,19294360,14334329,-19690631,2355319,-19284671,-6114373 }, { 15121312,-15796162,6377020,-6031361,-10798111,-12957845,18952177,15496498,-29380133,11754228 }, { -2637277,-13483075,8488727,-14303896,12728761,-1622493,7141596,11724556,22761615,-10134141 }, }, { { 16918416,11729663,-18083579,3022987,-31015732,-13339659,-28741185,-12227393,32851222,11717399 }, { 11166634,7338049,-6722523,4531520,-29468672,-7302055,31474879,3483633,-1193175,-4030831 }, { -185635,9921305,31456609,-13536438,-12013818,13348923,33142652,6546660,-19985279,-3948376 }, }, { { -32460596,11266712,-11197107,-7899103,31703694,3855903,-8537131,-12833048,-30772034,-15486313 }, { -18006477,12709068,3991746,-6479188,-21491523,-10550425,-31135347,-16049879,10928917,3011958 }, { -6957757,-15594337,31696059,334240,29576716,14796075,-30831056,-12805180,18008031,10258577 }, }, { { -22448644,15655569,7018479,-4410003,-30314266,-1201591,-1853465,1367120,25127874,6671743 }, { 29701166,-14373934,-10878120,9279288,-17568,13127210,21382910,11042292,25838796,4642684 }, { -20430234,14955537,-24126347,8124619,-5369288,-5990470,30468147,-13900640,18423289,4177476 }, }, }, ed25519-1.2.4/ext/ed25519_ref10/fe.c0000644000004100000410000007363113260523700016105 0ustar www-datawww-data#include "fe.h" #include "ed25519_ref10.h" /* h = 0 */ void fe_0(fe h) { h[0] = 0; h[1] = 0; h[2] = 0; h[3] = 0; h[4] = 0; h[5] = 0; h[6] = 0; h[7] = 0; h[8] = 0; h[9] = 0; } /* h = 1 */ void fe_1(fe h) { h[0] = 1; h[1] = 0; h[2] = 0; h[3] = 0; h[4] = 0; h[5] = 0; h[6] = 0; h[7] = 0; h[8] = 0; h[9] = 0; } /* h = f + g Can overlap h with f or g. Preconditions: |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. Postconditions: |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. */ void fe_add(fe h,const fe f,const fe g) { int32_t f0 = f[0]; int32_t f1 = f[1]; int32_t f2 = f[2]; int32_t f3 = f[3]; int32_t f4 = f[4]; int32_t f5 = f[5]; int32_t f6 = f[6]; int32_t f7 = f[7]; int32_t f8 = f[8]; int32_t f9 = f[9]; int32_t g0 = g[0]; int32_t g1 = g[1]; int32_t g2 = g[2]; int32_t g3 = g[3]; int32_t g4 = g[4]; int32_t g5 = g[5]; int32_t g6 = g[6]; int32_t g7 = g[7]; int32_t g8 = g[8]; int32_t g9 = g[9]; int32_t h0 = f0 + g0; int32_t h1 = f1 + g1; int32_t h2 = f2 + g2; int32_t h3 = f3 + g3; int32_t h4 = f4 + g4; int32_t h5 = f5 + g5; int32_t h6 = f6 + g6; int32_t h7 = f7 + g7; int32_t h8 = f8 + g8; int32_t h9 = f9 + g9; h[0] = h0; h[1] = h1; h[2] = h2; h[3] = h3; h[4] = h4; h[5] = h5; h[6] = h6; h[7] = h7; h[8] = h8; h[9] = h9; } /* Replace (f,g) with (g,g) if b == 1; replace (f,g) with (f,g) if b == 0. Preconditions: b in {0,1}. */ void fe_cmov(fe f,const fe g,unsigned int b) { int32_t f0 = f[0]; int32_t f1 = f[1]; int32_t f2 = f[2]; int32_t f3 = f[3]; int32_t f4 = f[4]; int32_t f5 = f[5]; int32_t f6 = f[6]; int32_t f7 = f[7]; int32_t f8 = f[8]; int32_t f9 = f[9]; int32_t g0 = g[0]; int32_t g1 = g[1]; int32_t g2 = g[2]; int32_t g3 = g[3]; int32_t g4 = g[4]; int32_t g5 = g[5]; int32_t g6 = g[6]; int32_t g7 = g[7]; int32_t g8 = g[8]; int32_t g9 = g[9]; int32_t x0 = f0 ^ g0; int32_t x1 = f1 ^ g1; int32_t x2 = f2 ^ g2; int32_t x3 = f3 ^ g3; int32_t x4 = f4 ^ g4; int32_t x5 = f5 ^ g5; int32_t x6 = f6 ^ g6; int32_t x7 = f7 ^ g7; int32_t x8 = f8 ^ g8; int32_t x9 = f9 ^ g9; b = -b; x0 &= b; x1 &= b; x2 &= b; x3 &= b; x4 &= b; x5 &= b; x6 &= b; x7 &= b; x8 &= b; x9 &= b; f[0] = f0 ^ x0; f[1] = f1 ^ x1; f[2] = f2 ^ x2; f[3] = f3 ^ x3; f[4] = f4 ^ x4; f[5] = f5 ^ x5; f[6] = f6 ^ x6; f[7] = f7 ^ x7; f[8] = f8 ^ x8; f[9] = f9 ^ x9; } /* h = f */ void fe_copy(fe h,const fe f) { int32_t f0 = f[0]; int32_t f1 = f[1]; int32_t f2 = f[2]; int32_t f3 = f[3]; int32_t f4 = f[4]; int32_t f5 = f[5]; int32_t f6 = f[6]; int32_t f7 = f[7]; int32_t f8 = f[8]; int32_t f9 = f[9]; h[0] = f0; h[1] = f1; h[2] = f2; h[3] = f3; h[4] = f4; h[5] = f5; h[6] = f6; h[7] = f7; h[8] = f8; h[9] = f9; } static uint64_t load_3(const unsigned char *in) { uint64_t result; result = (uint64_t) in[0]; result |= ((uint64_t) in[1]) << 8; result |= ((uint64_t) in[2]) << 16; return result; } static uint64_t load_4(const unsigned char *in) { uint64_t result; result = (uint64_t) in[0]; result |= ((uint64_t) in[1]) << 8; result |= ((uint64_t) in[2]) << 16; result |= ((uint64_t) in[3]) << 24; return result; } /* Ignores top bit of h. */ void fe_frombytes(fe h,const unsigned char *s) { int64_t h0 = load_4(s); int64_t h1 = load_3(s + 4) << 6; int64_t h2 = load_3(s + 7) << 5; int64_t h3 = load_3(s + 10) << 3; int64_t h4 = load_3(s + 13) << 2; int64_t h5 = load_4(s + 16); int64_t h6 = load_3(s + 20) << 7; int64_t h7 = load_3(s + 23) << 5; int64_t h8 = load_3(s + 26) << 4; int64_t h9 = (load_3(s + 29) & 8388607) << 2; int64_t carry0; int64_t carry1; int64_t carry2; int64_t carry3; int64_t carry4; int64_t carry5; int64_t carry6; int64_t carry7; int64_t carry8; int64_t carry9; carry9 = (h9 + (int64_t) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; carry1 = (h1 + (int64_t) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25; carry3 = (h3 + (int64_t) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25; carry5 = (h5 + (int64_t) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25; carry7 = (h7 + (int64_t) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25; carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; carry2 = (h2 + (int64_t) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26; carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; carry6 = (h6 + (int64_t) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26; carry8 = (h8 + (int64_t) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26; h[0] = (int32_t)h0; h[1] = (int32_t)h1; h[2] = (int32_t)h2; h[3] = (int32_t)h3; h[4] = (int32_t)h4; h[5] = (int32_t)h5; h[6] = (int32_t)h6; h[7] = (int32_t)h7; h[8] = (int32_t)h8; h[9] = (int32_t)h9; } void fe_invert(fe out,const fe z) { fe t0; fe t1; fe t2; fe t3; int i; #include "pow225521.h" return; } /* return 1 if f is in {1,3,5,...,q-2} return 0 if f is in {0,2,4,...,q-1} Preconditions: |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. */ int fe_isnegative(const fe f) { unsigned char s[32]; fe_tobytes(s,f); return s[0] & 1; } /* return 1 if f == 0 return 0 if f != 0 Preconditions: |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. */ static const unsigned char zero[32]; int fe_isnonzero(const fe f) { unsigned char s[32]; fe_tobytes(s,f); return crypto_verify_32(s,zero); } /* h = f * g Can overlap h with f or g. Preconditions: |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. |g| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. Postconditions: |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc. */ /* Notes on implementation strategy: Using schoolbook multiplication. Karatsuba would save a little in some cost models. Most multiplications by 2 and 19 are 32-bit precomputations; cheaper than 64-bit postcomputations. There is one remaining multiplication by 19 in the carry chain; one *19 precomputation can be merged into this, but the resulting data flow is considerably less clean. There are 12 carries below. 10 of them are 2-way parallelizable and vectorizable. Can get away with 11 carries, but then data flow is much deeper. With tighter constraints on inputs can squeeze carries into int32. */ void fe_mul(fe h,const fe f,const fe g) { int32_t f0 = f[0]; int32_t f1 = f[1]; int32_t f2 = f[2]; int32_t f3 = f[3]; int32_t f4 = f[4]; int32_t f5 = f[5]; int32_t f6 = f[6]; int32_t f7 = f[7]; int32_t f8 = f[8]; int32_t f9 = f[9]; int32_t g0 = g[0]; int32_t g1 = g[1]; int32_t g2 = g[2]; int32_t g3 = g[3]; int32_t g4 = g[4]; int32_t g5 = g[5]; int32_t g6 = g[6]; int32_t g7 = g[7]; int32_t g8 = g[8]; int32_t g9 = g[9]; int32_t g1_19 = 19 * g1; /* 1.959375*2^29 */ int32_t g2_19 = 19 * g2; /* 1.959375*2^30; still ok */ int32_t g3_19 = 19 * g3; int32_t g4_19 = 19 * g4; int32_t g5_19 = 19 * g5; int32_t g6_19 = 19 * g6; int32_t g7_19 = 19 * g7; int32_t g8_19 = 19 * g8; int32_t g9_19 = 19 * g9; int32_t f1_2 = 2 * f1; int32_t f3_2 = 2 * f3; int32_t f5_2 = 2 * f5; int32_t f7_2 = 2 * f7; int32_t f9_2 = 2 * f9; int64_t f0g0 = f0 * (int64_t) g0; int64_t f0g1 = f0 * (int64_t) g1; int64_t f0g2 = f0 * (int64_t) g2; int64_t f0g3 = f0 * (int64_t) g3; int64_t f0g4 = f0 * (int64_t) g4; int64_t f0g5 = f0 * (int64_t) g5; int64_t f0g6 = f0 * (int64_t) g6; int64_t f0g7 = f0 * (int64_t) g7; int64_t f0g8 = f0 * (int64_t) g8; int64_t f0g9 = f0 * (int64_t) g9; int64_t f1g0 = f1 * (int64_t) g0; int64_t f1g1_2 = f1_2 * (int64_t) g1; int64_t f1g2 = f1 * (int64_t) g2; int64_t f1g3_2 = f1_2 * (int64_t) g3; int64_t f1g4 = f1 * (int64_t) g4; int64_t f1g5_2 = f1_2 * (int64_t) g5; int64_t f1g6 = f1 * (int64_t) g6; int64_t f1g7_2 = f1_2 * (int64_t) g7; int64_t f1g8 = f1 * (int64_t) g8; int64_t f1g9_38 = f1_2 * (int64_t) g9_19; int64_t f2g0 = f2 * (int64_t) g0; int64_t f2g1 = f2 * (int64_t) g1; int64_t f2g2 = f2 * (int64_t) g2; int64_t f2g3 = f2 * (int64_t) g3; int64_t f2g4 = f2 * (int64_t) g4; int64_t f2g5 = f2 * (int64_t) g5; int64_t f2g6 = f2 * (int64_t) g6; int64_t f2g7 = f2 * (int64_t) g7; int64_t f2g8_19 = f2 * (int64_t) g8_19; int64_t f2g9_19 = f2 * (int64_t) g9_19; int64_t f3g0 = f3 * (int64_t) g0; int64_t f3g1_2 = f3_2 * (int64_t) g1; int64_t f3g2 = f3 * (int64_t) g2; int64_t f3g3_2 = f3_2 * (int64_t) g3; int64_t f3g4 = f3 * (int64_t) g4; int64_t f3g5_2 = f3_2 * (int64_t) g5; int64_t f3g6 = f3 * (int64_t) g6; int64_t f3g7_38 = f3_2 * (int64_t) g7_19; int64_t f3g8_19 = f3 * (int64_t) g8_19; int64_t f3g9_38 = f3_2 * (int64_t) g9_19; int64_t f4g0 = f4 * (int64_t) g0; int64_t f4g1 = f4 * (int64_t) g1; int64_t f4g2 = f4 * (int64_t) g2; int64_t f4g3 = f4 * (int64_t) g3; int64_t f4g4 = f4 * (int64_t) g4; int64_t f4g5 = f4 * (int64_t) g5; int64_t f4g6_19 = f4 * (int64_t) g6_19; int64_t f4g7_19 = f4 * (int64_t) g7_19; int64_t f4g8_19 = f4 * (int64_t) g8_19; int64_t f4g9_19 = f4 * (int64_t) g9_19; int64_t f5g0 = f5 * (int64_t) g0; int64_t f5g1_2 = f5_2 * (int64_t) g1; int64_t f5g2 = f5 * (int64_t) g2; int64_t f5g3_2 = f5_2 * (int64_t) g3; int64_t f5g4 = f5 * (int64_t) g4; int64_t f5g5_38 = f5_2 * (int64_t) g5_19; int64_t f5g6_19 = f5 * (int64_t) g6_19; int64_t f5g7_38 = f5_2 * (int64_t) g7_19; int64_t f5g8_19 = f5 * (int64_t) g8_19; int64_t f5g9_38 = f5_2 * (int64_t) g9_19; int64_t f6g0 = f6 * (int64_t) g0; int64_t f6g1 = f6 * (int64_t) g1; int64_t f6g2 = f6 * (int64_t) g2; int64_t f6g3 = f6 * (int64_t) g3; int64_t f6g4_19 = f6 * (int64_t) g4_19; int64_t f6g5_19 = f6 * (int64_t) g5_19; int64_t f6g6_19 = f6 * (int64_t) g6_19; int64_t f6g7_19 = f6 * (int64_t) g7_19; int64_t f6g8_19 = f6 * (int64_t) g8_19; int64_t f6g9_19 = f6 * (int64_t) g9_19; int64_t f7g0 = f7 * (int64_t) g0; int64_t f7g1_2 = f7_2 * (int64_t) g1; int64_t f7g2 = f7 * (int64_t) g2; int64_t f7g3_38 = f7_2 * (int64_t) g3_19; int64_t f7g4_19 = f7 * (int64_t) g4_19; int64_t f7g5_38 = f7_2 * (int64_t) g5_19; int64_t f7g6_19 = f7 * (int64_t) g6_19; int64_t f7g7_38 = f7_2 * (int64_t) g7_19; int64_t f7g8_19 = f7 * (int64_t) g8_19; int64_t f7g9_38 = f7_2 * (int64_t) g9_19; int64_t f8g0 = f8 * (int64_t) g0; int64_t f8g1 = f8 * (int64_t) g1; int64_t f8g2_19 = f8 * (int64_t) g2_19; int64_t f8g3_19 = f8 * (int64_t) g3_19; int64_t f8g4_19 = f8 * (int64_t) g4_19; int64_t f8g5_19 = f8 * (int64_t) g5_19; int64_t f8g6_19 = f8 * (int64_t) g6_19; int64_t f8g7_19 = f8 * (int64_t) g7_19; int64_t f8g8_19 = f8 * (int64_t) g8_19; int64_t f8g9_19 = f8 * (int64_t) g9_19; int64_t f9g0 = f9 * (int64_t) g0; int64_t f9g1_38 = f9_2 * (int64_t) g1_19; int64_t f9g2_19 = f9 * (int64_t) g2_19; int64_t f9g3_38 = f9_2 * (int64_t) g3_19; int64_t f9g4_19 = f9 * (int64_t) g4_19; int64_t f9g5_38 = f9_2 * (int64_t) g5_19; int64_t f9g6_19 = f9 * (int64_t) g6_19; int64_t f9g7_38 = f9_2 * (int64_t) g7_19; int64_t f9g8_19 = f9 * (int64_t) g8_19; int64_t f9g9_38 = f9_2 * (int64_t) g9_19; int64_t h0 = f0g0+f1g9_38+f2g8_19+f3g7_38+f4g6_19+f5g5_38+f6g4_19+f7g3_38+f8g2_19+f9g1_38; int64_t h1 = f0g1+f1g0 +f2g9_19+f3g8_19+f4g7_19+f5g6_19+f6g5_19+f7g4_19+f8g3_19+f9g2_19; int64_t h2 = f0g2+f1g1_2 +f2g0 +f3g9_38+f4g8_19+f5g7_38+f6g6_19+f7g5_38+f8g4_19+f9g3_38; int64_t h3 = f0g3+f1g2 +f2g1 +f3g0 +f4g9_19+f5g8_19+f6g7_19+f7g6_19+f8g5_19+f9g4_19; int64_t h4 = f0g4+f1g3_2 +f2g2 +f3g1_2 +f4g0 +f5g9_38+f6g8_19+f7g7_38+f8g6_19+f9g5_38; int64_t h5 = f0g5+f1g4 +f2g3 +f3g2 +f4g1 +f5g0 +f6g9_19+f7g8_19+f8g7_19+f9g6_19; int64_t h6 = f0g6+f1g5_2 +f2g4 +f3g3_2 +f4g2 +f5g1_2 +f6g0 +f7g9_38+f8g8_19+f9g7_38; int64_t h7 = f0g7+f1g6 +f2g5 +f3g4 +f4g3 +f5g2 +f6g1 +f7g0 +f8g9_19+f9g8_19; int64_t h8 = f0g8+f1g7_2 +f2g6 +f3g5_2 +f4g4 +f5g3_2 +f6g2 +f7g1_2 +f8g0 +f9g9_38; int64_t h9 = f0g9+f1g8 +f2g7 +f3g6 +f4g5 +f5g4 +f6g3 +f7g2 +f8g1 +f9g0 ; int64_t carry0; int64_t carry1; int64_t carry2; int64_t carry3; int64_t carry4; int64_t carry5; int64_t carry6; int64_t carry7; int64_t carry8; int64_t carry9; /* |h0| <= (1.65*1.65*2^52*(1+19+19+19+19)+1.65*1.65*2^50*(38+38+38+38+38)) i.e. |h0| <= 1.4*2^60; narrower ranges for h2, h4, h6, h8 |h1| <= (1.65*1.65*2^51*(1+1+19+19+19+19+19+19+19+19)) i.e. |h1| <= 1.7*2^59; narrower ranges for h3, h5, h7, h9 */ carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; /* |h0| <= 2^25 */ /* |h4| <= 2^25 */ /* |h1| <= 1.71*2^59 */ /* |h5| <= 1.71*2^59 */ carry1 = (h1 + (int64_t) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25; carry5 = (h5 + (int64_t) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25; /* |h1| <= 2^24; from now on fits into int32 */ /* |h5| <= 2^24; from now on fits into int32 */ /* |h2| <= 1.41*2^60 */ /* |h6| <= 1.41*2^60 */ carry2 = (h2 + (int64_t) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26; carry6 = (h6 + (int64_t) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26; /* |h2| <= 2^25; from now on fits into int32 unchanged */ /* |h6| <= 2^25; from now on fits into int32 unchanged */ /* |h3| <= 1.71*2^59 */ /* |h7| <= 1.71*2^59 */ carry3 = (h3 + (int64_t) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25; carry7 = (h7 + (int64_t) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25; /* |h3| <= 2^24; from now on fits into int32 unchanged */ /* |h7| <= 2^24; from now on fits into int32 unchanged */ /* |h4| <= 1.72*2^34 */ /* |h8| <= 1.41*2^60 */ carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; carry8 = (h8 + (int64_t) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26; /* |h4| <= 2^25; from now on fits into int32 unchanged */ /* |h8| <= 2^25; from now on fits into int32 unchanged */ /* |h5| <= 1.01*2^24 */ /* |h9| <= 1.71*2^59 */ carry9 = (h9 + (int64_t) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; /* |h9| <= 2^24; from now on fits into int32 unchanged */ /* |h0| <= 1.1*2^39 */ carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; /* |h0| <= 2^25; from now on fits into int32 unchanged */ /* |h1| <= 1.01*2^24 */ h[0] = (int32_t)h0; h[1] = (int32_t)h1; h[2] = (int32_t)h2; h[3] = (int32_t)h3; h[4] = (int32_t)h4; h[5] = (int32_t)h5; h[6] = (int32_t)h6; h[7] = (int32_t)h7; h[8] = (int32_t)h8; h[9] = (int32_t)h9; } /* h = -f Preconditions: |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. Postconditions: |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. */ void fe_neg(fe h,const fe f) { int32_t f0 = f[0]; int32_t f1 = f[1]; int32_t f2 = f[2]; int32_t f3 = f[3]; int32_t f4 = f[4]; int32_t f5 = f[5]; int32_t f6 = f[6]; int32_t f7 = f[7]; int32_t f8 = f[8]; int32_t f9 = f[9]; int32_t h0 = -f0; int32_t h1 = -f1; int32_t h2 = -f2; int32_t h3 = -f3; int32_t h4 = -f4; int32_t h5 = -f5; int32_t h6 = -f6; int32_t h7 = -f7; int32_t h8 = -f8; int32_t h9 = -f9; h[0] = h0; h[1] = h1; h[2] = h2; h[3] = h3; h[4] = h4; h[5] = h5; h[6] = h6; h[7] = h7; h[8] = h8; h[9] = h9; } void fe_pow22523(fe out,const fe z) { fe t0; fe t1; fe t2; int i; #include "pow22523.h" return; } /* h = f * f Can overlap h with f. Preconditions: |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. Postconditions: |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc. */ /* See fe_mul.c for discussion of implementation strategy. */ void fe_sq(fe h,const fe f) { int32_t f0 = f[0]; int32_t f1 = f[1]; int32_t f2 = f[2]; int32_t f3 = f[3]; int32_t f4 = f[4]; int32_t f5 = f[5]; int32_t f6 = f[6]; int32_t f7 = f[7]; int32_t f8 = f[8]; int32_t f9 = f[9]; int32_t f0_2 = 2 * f0; int32_t f1_2 = 2 * f1; int32_t f2_2 = 2 * f2; int32_t f3_2 = 2 * f3; int32_t f4_2 = 2 * f4; int32_t f5_2 = 2 * f5; int32_t f6_2 = 2 * f6; int32_t f7_2 = 2 * f7; int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */ int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */ int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */ int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */ int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */ int64_t f0f0 = f0 * (int64_t) f0; int64_t f0f1_2 = f0_2 * (int64_t) f1; int64_t f0f2_2 = f0_2 * (int64_t) f2; int64_t f0f3_2 = f0_2 * (int64_t) f3; int64_t f0f4_2 = f0_2 * (int64_t) f4; int64_t f0f5_2 = f0_2 * (int64_t) f5; int64_t f0f6_2 = f0_2 * (int64_t) f6; int64_t f0f7_2 = f0_2 * (int64_t) f7; int64_t f0f8_2 = f0_2 * (int64_t) f8; int64_t f0f9_2 = f0_2 * (int64_t) f9; int64_t f1f1_2 = f1_2 * (int64_t) f1; int64_t f1f2_2 = f1_2 * (int64_t) f2; int64_t f1f3_4 = f1_2 * (int64_t) f3_2; int64_t f1f4_2 = f1_2 * (int64_t) f4; int64_t f1f5_4 = f1_2 * (int64_t) f5_2; int64_t f1f6_2 = f1_2 * (int64_t) f6; int64_t f1f7_4 = f1_2 * (int64_t) f7_2; int64_t f1f8_2 = f1_2 * (int64_t) f8; int64_t f1f9_76 = f1_2 * (int64_t) f9_38; int64_t f2f2 = f2 * (int64_t) f2; int64_t f2f3_2 = f2_2 * (int64_t) f3; int64_t f2f4_2 = f2_2 * (int64_t) f4; int64_t f2f5_2 = f2_2 * (int64_t) f5; int64_t f2f6_2 = f2_2 * (int64_t) f6; int64_t f2f7_2 = f2_2 * (int64_t) f7; int64_t f2f8_38 = f2_2 * (int64_t) f8_19; int64_t f2f9_38 = f2 * (int64_t) f9_38; int64_t f3f3_2 = f3_2 * (int64_t) f3; int64_t f3f4_2 = f3_2 * (int64_t) f4; int64_t f3f5_4 = f3_2 * (int64_t) f5_2; int64_t f3f6_2 = f3_2 * (int64_t) f6; int64_t f3f7_76 = f3_2 * (int64_t) f7_38; int64_t f3f8_38 = f3_2 * (int64_t) f8_19; int64_t f3f9_76 = f3_2 * (int64_t) f9_38; int64_t f4f4 = f4 * (int64_t) f4; int64_t f4f5_2 = f4_2 * (int64_t) f5; int64_t f4f6_38 = f4_2 * (int64_t) f6_19; int64_t f4f7_38 = f4 * (int64_t) f7_38; int64_t f4f8_38 = f4_2 * (int64_t) f8_19; int64_t f4f9_38 = f4 * (int64_t) f9_38; int64_t f5f5_38 = f5 * (int64_t) f5_38; int64_t f5f6_38 = f5_2 * (int64_t) f6_19; int64_t f5f7_76 = f5_2 * (int64_t) f7_38; int64_t f5f8_38 = f5_2 * (int64_t) f8_19; int64_t f5f9_76 = f5_2 * (int64_t) f9_38; int64_t f6f6_19 = f6 * (int64_t) f6_19; int64_t f6f7_38 = f6 * (int64_t) f7_38; int64_t f6f8_38 = f6_2 * (int64_t) f8_19; int64_t f6f9_38 = f6 * (int64_t) f9_38; int64_t f7f7_38 = f7 * (int64_t) f7_38; int64_t f7f8_38 = f7_2 * (int64_t) f8_19; int64_t f7f9_76 = f7_2 * (int64_t) f9_38; int64_t f8f8_19 = f8 * (int64_t) f8_19; int64_t f8f9_38 = f8 * (int64_t) f9_38; int64_t f9f9_38 = f9 * (int64_t) f9_38; int64_t h0 = f0f0 +f1f9_76+f2f8_38+f3f7_76+f4f6_38+f5f5_38; int64_t h1 = f0f1_2+f2f9_38+f3f8_38+f4f7_38+f5f6_38; int64_t h2 = f0f2_2+f1f1_2 +f3f9_76+f4f8_38+f5f7_76+f6f6_19; int64_t h3 = f0f3_2+f1f2_2 +f4f9_38+f5f8_38+f6f7_38; int64_t h4 = f0f4_2+f1f3_4 +f2f2 +f5f9_76+f6f8_38+f7f7_38; int64_t h5 = f0f5_2+f1f4_2 +f2f3_2 +f6f9_38+f7f8_38; int64_t h6 = f0f6_2+f1f5_4 +f2f4_2 +f3f3_2 +f7f9_76+f8f8_19; int64_t h7 = f0f7_2+f1f6_2 +f2f5_2 +f3f4_2 +f8f9_38; int64_t h8 = f0f8_2+f1f7_4 +f2f6_2 +f3f5_4 +f4f4 +f9f9_38; int64_t h9 = f0f9_2+f1f8_2 +f2f7_2 +f3f6_2 +f4f5_2; int64_t carry0; int64_t carry1; int64_t carry2; int64_t carry3; int64_t carry4; int64_t carry5; int64_t carry6; int64_t carry7; int64_t carry8; int64_t carry9; carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; carry1 = (h1 + (int64_t) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25; carry5 = (h5 + (int64_t) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25; carry2 = (h2 + (int64_t) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26; carry6 = (h6 + (int64_t) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26; carry3 = (h3 + (int64_t) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25; carry7 = (h7 + (int64_t) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25; carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; carry8 = (h8 + (int64_t) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26; carry9 = (h9 + (int64_t) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; h[0] = (int32_t)h0; h[1] = (int32_t)h1; h[2] = (int32_t)h2; h[3] = (int32_t)h3; h[4] = (int32_t)h4; h[5] = (int32_t)h5; h[6] = (int32_t)h6; h[7] = (int32_t)h7; h[8] = (int32_t)h8; h[9] = (int32_t)h9; } /* h = 2 * f * f Can overlap h with f. Preconditions: |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. Postconditions: |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc. */ /* See fe_mul.c for discussion of implementation strategy. */ void fe_sq2(fe h,const fe f) { int32_t f0 = f[0]; int32_t f1 = f[1]; int32_t f2 = f[2]; int32_t f3 = f[3]; int32_t f4 = f[4]; int32_t f5 = f[5]; int32_t f6 = f[6]; int32_t f7 = f[7]; int32_t f8 = f[8]; int32_t f9 = f[9]; int32_t f0_2 = 2 * f0; int32_t f1_2 = 2 * f1; int32_t f2_2 = 2 * f2; int32_t f3_2 = 2 * f3; int32_t f4_2 = 2 * f4; int32_t f5_2 = 2 * f5; int32_t f6_2 = 2 * f6; int32_t f7_2 = 2 * f7; int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */ int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */ int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */ int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */ int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */ int64_t f0f0 = f0 * (int64_t) f0; int64_t f0f1_2 = f0_2 * (int64_t) f1; int64_t f0f2_2 = f0_2 * (int64_t) f2; int64_t f0f3_2 = f0_2 * (int64_t) f3; int64_t f0f4_2 = f0_2 * (int64_t) f4; int64_t f0f5_2 = f0_2 * (int64_t) f5; int64_t f0f6_2 = f0_2 * (int64_t) f6; int64_t f0f7_2 = f0_2 * (int64_t) f7; int64_t f0f8_2 = f0_2 * (int64_t) f8; int64_t f0f9_2 = f0_2 * (int64_t) f9; int64_t f1f1_2 = f1_2 * (int64_t) f1; int64_t f1f2_2 = f1_2 * (int64_t) f2; int64_t f1f3_4 = f1_2 * (int64_t) f3_2; int64_t f1f4_2 = f1_2 * (int64_t) f4; int64_t f1f5_4 = f1_2 * (int64_t) f5_2; int64_t f1f6_2 = f1_2 * (int64_t) f6; int64_t f1f7_4 = f1_2 * (int64_t) f7_2; int64_t f1f8_2 = f1_2 * (int64_t) f8; int64_t f1f9_76 = f1_2 * (int64_t) f9_38; int64_t f2f2 = f2 * (int64_t) f2; int64_t f2f3_2 = f2_2 * (int64_t) f3; int64_t f2f4_2 = f2_2 * (int64_t) f4; int64_t f2f5_2 = f2_2 * (int64_t) f5; int64_t f2f6_2 = f2_2 * (int64_t) f6; int64_t f2f7_2 = f2_2 * (int64_t) f7; int64_t f2f8_38 = f2_2 * (int64_t) f8_19; int64_t f2f9_38 = f2 * (int64_t) f9_38; int64_t f3f3_2 = f3_2 * (int64_t) f3; int64_t f3f4_2 = f3_2 * (int64_t) f4; int64_t f3f5_4 = f3_2 * (int64_t) f5_2; int64_t f3f6_2 = f3_2 * (int64_t) f6; int64_t f3f7_76 = f3_2 * (int64_t) f7_38; int64_t f3f8_38 = f3_2 * (int64_t) f8_19; int64_t f3f9_76 = f3_2 * (int64_t) f9_38; int64_t f4f4 = f4 * (int64_t) f4; int64_t f4f5_2 = f4_2 * (int64_t) f5; int64_t f4f6_38 = f4_2 * (int64_t) f6_19; int64_t f4f7_38 = f4 * (int64_t) f7_38; int64_t f4f8_38 = f4_2 * (int64_t) f8_19; int64_t f4f9_38 = f4 * (int64_t) f9_38; int64_t f5f5_38 = f5 * (int64_t) f5_38; int64_t f5f6_38 = f5_2 * (int64_t) f6_19; int64_t f5f7_76 = f5_2 * (int64_t) f7_38; int64_t f5f8_38 = f5_2 * (int64_t) f8_19; int64_t f5f9_76 = f5_2 * (int64_t) f9_38; int64_t f6f6_19 = f6 * (int64_t) f6_19; int64_t f6f7_38 = f6 * (int64_t) f7_38; int64_t f6f8_38 = f6_2 * (int64_t) f8_19; int64_t f6f9_38 = f6 * (int64_t) f9_38; int64_t f7f7_38 = f7 * (int64_t) f7_38; int64_t f7f8_38 = f7_2 * (int64_t) f8_19; int64_t f7f9_76 = f7_2 * (int64_t) f9_38; int64_t f8f8_19 = f8 * (int64_t) f8_19; int64_t f8f9_38 = f8 * (int64_t) f9_38; int64_t f9f9_38 = f9 * (int64_t) f9_38; int64_t h0 = f0f0 +f1f9_76+f2f8_38+f3f7_76+f4f6_38+f5f5_38; int64_t h1 = f0f1_2+f2f9_38+f3f8_38+f4f7_38+f5f6_38; int64_t h2 = f0f2_2+f1f1_2 +f3f9_76+f4f8_38+f5f7_76+f6f6_19; int64_t h3 = f0f3_2+f1f2_2 +f4f9_38+f5f8_38+f6f7_38; int64_t h4 = f0f4_2+f1f3_4 +f2f2 +f5f9_76+f6f8_38+f7f7_38; int64_t h5 = f0f5_2+f1f4_2 +f2f3_2 +f6f9_38+f7f8_38; int64_t h6 = f0f6_2+f1f5_4 +f2f4_2 +f3f3_2 +f7f9_76+f8f8_19; int64_t h7 = f0f7_2+f1f6_2 +f2f5_2 +f3f4_2 +f8f9_38; int64_t h8 = f0f8_2+f1f7_4 +f2f6_2 +f3f5_4 +f4f4 +f9f9_38; int64_t h9 = f0f9_2+f1f8_2 +f2f7_2 +f3f6_2 +f4f5_2; int64_t carry0; int64_t carry1; int64_t carry2; int64_t carry3; int64_t carry4; int64_t carry5; int64_t carry6; int64_t carry7; int64_t carry8; int64_t carry9; h0 += h0; h1 += h1; h2 += h2; h3 += h3; h4 += h4; h5 += h5; h6 += h6; h7 += h7; h8 += h8; h9 += h9; carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; carry1 = (h1 + (int64_t) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25; carry5 = (h5 + (int64_t) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25; carry2 = (h2 + (int64_t) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26; carry6 = (h6 + (int64_t) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26; carry3 = (h3 + (int64_t) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25; carry7 = (h7 + (int64_t) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25; carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; carry8 = (h8 + (int64_t) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26; carry9 = (h9 + (int64_t) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; h[0] = (int32_t)h0; h[1] = (int32_t)h1; h[2] = (int32_t)h2; h[3] = (int32_t)h3; h[4] = (int32_t)h4; h[5] = (int32_t)h5; h[6] = (int32_t)h6; h[7] = (int32_t)h7; h[8] = (int32_t)h8; h[9] = (int32_t)h9; } /* h = f - g Can overlap h with f or g. Preconditions: |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. Postconditions: |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. */ void fe_sub(fe h,const fe f,const fe g) { int32_t f0 = f[0]; int32_t f1 = f[1]; int32_t f2 = f[2]; int32_t f3 = f[3]; int32_t f4 = f[4]; int32_t f5 = f[5]; int32_t f6 = f[6]; int32_t f7 = f[7]; int32_t f8 = f[8]; int32_t f9 = f[9]; int32_t g0 = g[0]; int32_t g1 = g[1]; int32_t g2 = g[2]; int32_t g3 = g[3]; int32_t g4 = g[4]; int32_t g5 = g[5]; int32_t g6 = g[6]; int32_t g7 = g[7]; int32_t g8 = g[8]; int32_t g9 = g[9]; int32_t h0 = f0 - g0; int32_t h1 = f1 - g1; int32_t h2 = f2 - g2; int32_t h3 = f3 - g3; int32_t h4 = f4 - g4; int32_t h5 = f5 - g5; int32_t h6 = f6 - g6; int32_t h7 = f7 - g7; int32_t h8 = f8 - g8; int32_t h9 = f9 - g9; h[0] = h0; h[1] = h1; h[2] = h2; h[3] = h3; h[4] = h4; h[5] = h5; h[6] = h6; h[7] = h7; h[8] = h8; h[9] = h9; } /* Preconditions: |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. Write p=2^255-19; q=floor(h/p). Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))). Proof: Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4. Also have |h-2^230 h9|<2^231 so |19 2^(-255)(h-2^230 h9)|<1/4. Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9). Then 0> 25; q = (h0 + q) >> 26; q = (h1 + q) >> 25; q = (h2 + q) >> 26; q = (h3 + q) >> 25; q = (h4 + q) >> 26; q = (h5 + q) >> 25; q = (h6 + q) >> 26; q = (h7 + q) >> 25; q = (h8 + q) >> 26; q = (h9 + q) >> 25; /* Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. */ h0 += 19 * q; /* Goal: Output h-2^255 q, which is between 0 and 2^255-20. */ carry0 = h0 >> 26; h1 += carry0; h0 -= carry0 << 26; carry1 = h1 >> 25; h2 += carry1; h1 -= carry1 << 25; carry2 = h2 >> 26; h3 += carry2; h2 -= carry2 << 26; carry3 = h3 >> 25; h4 += carry3; h3 -= carry3 << 25; carry4 = h4 >> 26; h5 += carry4; h4 -= carry4 << 26; carry5 = h5 >> 25; h6 += carry5; h5 -= carry5 << 25; carry6 = h6 >> 26; h7 += carry6; h6 -= carry6 << 26; carry7 = h7 >> 25; h8 += carry7; h7 -= carry7 << 25; carry8 = h8 >> 26; h9 += carry8; h8 -= carry8 << 26; carry9 = h9 >> 25; h9 -= carry9 << 25; /* h10 = carry9 */ /* Goal: Output h0+...+2^255 h10-2^255 q, which is between 0 and 2^255-20. Have h0+...+2^230 h9 between 0 and 2^255-1; evidently 2^255 h10-2^255 q = 0. Goal: Output h0+...+2^230 h9. */ s[0] = h0 >> 0; s[1] = h0 >> 8; s[2] = h0 >> 16; s[3] = (h0 >> 24) | (h1 << 2); s[4] = h1 >> 6; s[5] = h1 >> 14; s[6] = (h1 >> 22) | (h2 << 3); s[7] = h2 >> 5; s[8] = h2 >> 13; s[9] = (h2 >> 21) | (h3 << 5); s[10] = h3 >> 3; s[11] = h3 >> 11; s[12] = (h3 >> 19) | (h4 << 6); s[13] = h4 >> 2; s[14] = h4 >> 10; s[15] = h4 >> 18; s[16] = h5 >> 0; s[17] = h5 >> 8; s[18] = h5 >> 16; s[19] = (h5 >> 24) | (h6 << 1); s[20] = h6 >> 7; s[21] = h6 >> 15; s[22] = (h6 >> 23) | (h7 << 3); s[23] = h7 >> 5; s[24] = h7 >> 13; s[25] = (h7 >> 21) | (h8 << 4); s[26] = h8 >> 4; s[27] = h8 >> 12; s[28] = (h8 >> 20) | (h9 << 6); s[29] = h9 >> 2; s[30] = h9 >> 10; s[31] = h9 >> 18; } ed25519-1.2.4/ext/ed25519_ref10/sc_reduce.c0000644000004100000410000001716113260523700017443 0ustar www-datawww-data#include "sc.h" static uint64_t load_3(const unsigned char *in) { uint64_t result; result = (uint64_t) in[0]; result |= ((uint64_t) in[1]) << 8; result |= ((uint64_t) in[2]) << 16; return result; } static uint64_t load_4(const unsigned char *in) { uint64_t result; result = (uint64_t) in[0]; result |= ((uint64_t) in[1]) << 8; result |= ((uint64_t) in[2]) << 16; result |= ((uint64_t) in[3]) << 24; return result; } /* Input: s[0]+256*s[1]+...+256^63*s[63] = s Output: s[0]+256*s[1]+...+256^31*s[31] = s mod l where l = 2^252 + 27742317777372353535851937790883648493. Overwrites s in place. */ void sc_reduce(uint8_t *s) { int64_t s0 = 2097151 & load_3(s); int64_t s1 = 2097151 & (load_4(s + 2) >> 5); int64_t s2 = 2097151 & (load_3(s + 5) >> 2); int64_t s3 = 2097151 & (load_4(s + 7) >> 7); int64_t s4 = 2097151 & (load_4(s + 10) >> 4); int64_t s5 = 2097151 & (load_3(s + 13) >> 1); int64_t s6 = 2097151 & (load_4(s + 15) >> 6); int64_t s7 = 2097151 & (load_3(s + 18) >> 3); int64_t s8 = 2097151 & load_3(s + 21); int64_t s9 = 2097151 & (load_4(s + 23) >> 5); int64_t s10 = 2097151 & (load_3(s + 26) >> 2); int64_t s11 = 2097151 & (load_4(s + 28) >> 7); int64_t s12 = 2097151 & (load_4(s + 31) >> 4); int64_t s13 = 2097151 & (load_3(s + 34) >> 1); int64_t s14 = 2097151 & (load_4(s + 36) >> 6); int64_t s15 = 2097151 & (load_3(s + 39) >> 3); int64_t s16 = 2097151 & load_3(s + 42); int64_t s17 = 2097151 & (load_4(s + 44) >> 5); int64_t s18 = 2097151 & (load_3(s + 47) >> 2); int64_t s19 = 2097151 & (load_4(s + 49) >> 7); int64_t s20 = 2097151 & (load_4(s + 52) >> 4); int64_t s21 = 2097151 & (load_3(s + 55) >> 1); int64_t s22 = 2097151 & (load_4(s + 57) >> 6); int64_t s23 = (load_4(s + 60) >> 3); int64_t carry0; int64_t carry1; int64_t carry2; int64_t carry3; int64_t carry4; int64_t carry5; int64_t carry6; int64_t carry7; int64_t carry8; int64_t carry9; int64_t carry10; int64_t carry11; int64_t carry12; int64_t carry13; int64_t carry14; int64_t carry15; int64_t carry16; s11 += s23 * 666643; s12 += s23 * 470296; s13 += s23 * 654183; s14 -= s23 * 997805; s15 += s23 * 136657; s16 -= s23 * 683901; s23 = 0; s10 += s22 * 666643; s11 += s22 * 470296; s12 += s22 * 654183; s13 -= s22 * 997805; s14 += s22 * 136657; s15 -= s22 * 683901; s22 = 0; s9 += s21 * 666643; s10 += s21 * 470296; s11 += s21 * 654183; s12 -= s21 * 997805; s13 += s21 * 136657; s14 -= s21 * 683901; s21 = 0; s8 += s20 * 666643; s9 += s20 * 470296; s10 += s20 * 654183; s11 -= s20 * 997805; s12 += s20 * 136657; s13 -= s20 * 683901; s20 = 0; s7 += s19 * 666643; s8 += s19 * 470296; s9 += s19 * 654183; s10 -= s19 * 997805; s11 += s19 * 136657; s12 -= s19 * 683901; s19 = 0; s6 += s18 * 666643; s7 += s18 * 470296; s8 += s18 * 654183; s9 -= s18 * 997805; s10 += s18 * 136657; s11 -= s18 * 683901; s18 = 0; carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21; carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21; carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21; carry12 = (s12 + (1<<20)) >> 21; s13 += carry12; s12 -= carry12 << 21; carry14 = (s14 + (1<<20)) >> 21; s15 += carry14; s14 -= carry14 << 21; carry16 = (s16 + (1<<20)) >> 21; s17 += carry16; s16 -= carry16 << 21; carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21; carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21; carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21; carry13 = (s13 + (1<<20)) >> 21; s14 += carry13; s13 -= carry13 << 21; carry15 = (s15 + (1<<20)) >> 21; s16 += carry15; s15 -= carry15 << 21; s5 += s17 * 666643; s6 += s17 * 470296; s7 += s17 * 654183; s8 -= s17 * 997805; s9 += s17 * 136657; s10 -= s17 * 683901; s17 = 0; s4 += s16 * 666643; s5 += s16 * 470296; s6 += s16 * 654183; s7 -= s16 * 997805; s8 += s16 * 136657; s9 -= s16 * 683901; s16 = 0; s3 += s15 * 666643; s4 += s15 * 470296; s5 += s15 * 654183; s6 -= s15 * 997805; s7 += s15 * 136657; s8 -= s15 * 683901; s15 = 0; s2 += s14 * 666643; s3 += s14 * 470296; s4 += s14 * 654183; s5 -= s14 * 997805; s6 += s14 * 136657; s7 -= s14 * 683901; s14 = 0; s1 += s13 * 666643; s2 += s13 * 470296; s3 += s13 * 654183; s4 -= s13 * 997805; s5 += s13 * 136657; s6 -= s13 * 683901; s13 = 0; s0 += s12 * 666643; s1 += s12 * 470296; s2 += s12 * 654183; s3 -= s12 * 997805; s4 += s12 * 136657; s5 -= s12 * 683901; s12 = 0; carry0 = (s0 + (1<<20)) >> 21; s1 += carry0; s0 -= carry0 << 21; carry2 = (s2 + (1<<20)) >> 21; s3 += carry2; s2 -= carry2 << 21; carry4 = (s4 + (1<<20)) >> 21; s5 += carry4; s4 -= carry4 << 21; carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21; carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21; carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21; carry1 = (s1 + (1<<20)) >> 21; s2 += carry1; s1 -= carry1 << 21; carry3 = (s3 + (1<<20)) >> 21; s4 += carry3; s3 -= carry3 << 21; carry5 = (s5 + (1<<20)) >> 21; s6 += carry5; s5 -= carry5 << 21; carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21; carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21; carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21; s0 += s12 * 666643; s1 += s12 * 470296; s2 += s12 * 654183; s3 -= s12 * 997805; s4 += s12 * 136657; s5 -= s12 * 683901; s12 = 0; carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21; carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21; carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21; carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21; carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21; carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21; carry11 = s11 >> 21; s12 += carry11; s11 -= carry11 << 21; s0 += s12 * 666643; s1 += s12 * 470296; s2 += s12 * 654183; s3 -= s12 * 997805; s4 += s12 * 136657; s5 -= s12 * 683901; s12 = 0; carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21; carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21; carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21; carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21; carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21; carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21; s[0] = s0 >> 0; s[1] = s0 >> 8; s[2] = (s0 >> 16) | (s1 << 5); s[3] = s1 >> 3; s[4] = s1 >> 11; s[5] = (s1 >> 19) | (s2 << 2); s[6] = s2 >> 6; s[7] = (s2 >> 14) | (s3 << 7); s[8] = s3 >> 1; s[9] = s3 >> 9; s[10] = (s3 >> 17) | (s4 << 4); s[11] = s4 >> 4; s[12] = s4 >> 12; s[13] = (s4 >> 20) | (s5 << 1); s[14] = s5 >> 7; s[15] = (s5 >> 15) | (s6 << 6); s[16] = s6 >> 2; s[17] = s6 >> 10; s[18] = (s6 >> 18) | (s7 << 3); s[19] = s7 >> 5; s[20] = s7 >> 13; s[21] = s8 >> 0; s[22] = s8 >> 8; s[23] = (s8 >> 16) | (s9 << 5); s[24] = s9 >> 3; s[25] = s9 >> 11; s[26] = (s9 >> 19) | (s10 << 2); s[27] = s10 >> 6; s[28] = (s10 >> 14) | (s11 << 7); s[29] = s11 >> 1; s[30] = s11 >> 9; s[31] = s11 >> 17; } ed25519-1.2.4/ext/ed25519_ref10/ed25519_ref10.h0000644000004100000410000000153313260523700017503 0ustar www-datawww-data#ifndef ED25519_REF10_H #define ED25519_REF10_H #include #define SECRETKEYBYTES 64 #define PUBLICKEYBYTES 32 #define SIGNATUREBYTES 64 #define ED25519_KEYSIZE_BYTES 32 typedef uint8_t ED25519_KEY[ED25519_KEYSIZE_BYTES]; /* Generate an Ed25519 keypair from a seed value */ int crypto_sign_ed25519_ref10_seed_keypair(uint8_t *pk, uint8_t *sk, const uint8_t *seed); /* Compute an Ed25519 signature over the given message */ int crypto_sign_ed25519_ref10( uint8_t *sm, uint64_t *smlen, const uint8_t *m, uint64_t mlen, const uint8_t *sk ); /* Verify the given signature is authentic */ int crypto_sign_open_ed25519_ref10( uint8_t *m, uint64_t *mlen, const uint8_t *sm, uint64_t smlen, const uint8_t *pk ); /* Constant-time comparison function */ int crypto_verify_32(const uint8_t *x,const uint8_t *y); #endif /* ED25519_REF10_H */ ed25519-1.2.4/ext/ed25519_ref10/ge.c0000644000004100000410000001701713260523700016102 0ustar www-datawww-data#include "ge.h" /* r = p + q */ void ge_add(ge_p1p1 *r,const ge_p3 *p,const ge_cached *q) { fe t0; #include "ge_add.h" } static void slide(signed char *r,const unsigned char *a) { int i; int b; int k; for (i = 0;i < 256;++i) r[i] = 1 & (a[i >> 3] >> (i & 7)); for (i = 0;i < 256;++i) if (r[i]) { for (b = 1;b <= 6 && i + b < 256;++b) { if (r[i + b]) { if (r[i] + (r[i + b] << b) <= 15) { r[i] += r[i + b] << b; r[i + b] = 0; } else if (r[i] - (r[i + b] << b) >= -15) { r[i] -= r[i + b] << b; for (k = i + b;k < 256;++k) { if (!r[k]) { r[k] = 1; break; } r[k] = 0; } } else break; } } } } static ge_precomp Bi[8] = { #include "base2.h" } ; /* r = a * A + b * B where a = a[0]+256*a[1]+...+256^31 a[31]. and b = b[0]+256*b[1]+...+256^31 b[31]. B is the Ed25519 base point (x,4/5) with x positive. */ void ge_double_scalarmult_vartime(ge_p2 *r,const unsigned char *a,const ge_p3 *A,const unsigned char *b) { signed char aslide[256]; signed char bslide[256]; ge_cached Ai[8]; /* A,3A,5A,7A,9A,11A,13A,15A */ ge_p1p1 t; ge_p3 u; ge_p3 A2; int i; slide(aslide,a); slide(bslide,b); ge_p3_to_cached(&Ai[0],A); ge_p3_dbl(&t,A); ge_p1p1_to_p3(&A2,&t); ge_add(&t,&A2,&Ai[0]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[1],&u); ge_add(&t,&A2,&Ai[1]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[2],&u); ge_add(&t,&A2,&Ai[2]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[3],&u); ge_add(&t,&A2,&Ai[3]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[4],&u); ge_add(&t,&A2,&Ai[4]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[5],&u); ge_add(&t,&A2,&Ai[5]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[6],&u); ge_add(&t,&A2,&Ai[6]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[7],&u); ge_p2_0(r); for (i = 255;i >= 0;--i) { if (aslide[i] || bslide[i]) break; } for (;i >= 0;--i) { ge_p2_dbl(&t,r); if (aslide[i] > 0) { ge_p1p1_to_p3(&u,&t); ge_add(&t,&u,&Ai[aslide[i]/2]); } else if (aslide[i] < 0) { ge_p1p1_to_p3(&u,&t); ge_sub(&t,&u,&Ai[(-aslide[i])/2]); } if (bslide[i] > 0) { ge_p1p1_to_p3(&u,&t); ge_madd(&t,&u,&Bi[bslide[i]/2]); } else if (bslide[i] < 0) { ge_p1p1_to_p3(&u,&t); ge_msub(&t,&u,&Bi[(-bslide[i])/2]); } ge_p1p1_to_p2(r,&t); } } static const fe d = { #include "d.h" } ; static const fe sqrtm1 = { #include "sqrtm1.h" } ; int ge_frombytes_negate_vartime(ge_p3 *h,const unsigned char *s) { fe u; fe v; fe v3; fe vxx; fe check; fe_frombytes(h->Y,s); fe_1(h->Z); fe_sq(u,h->Y); fe_mul(v,u,d); fe_sub(u,u,h->Z); /* u = y^2-1 */ fe_add(v,v,h->Z); /* v = dy^2+1 */ fe_sq(v3,v); fe_mul(v3,v3,v); /* v3 = v^3 */ fe_sq(h->X,v3); fe_mul(h->X,h->X,v); fe_mul(h->X,h->X,u); /* x = uv^7 */ fe_pow22523(h->X,h->X); /* x = (uv^7)^((q-5)/8) */ fe_mul(h->X,h->X,v3); fe_mul(h->X,h->X,u); /* x = uv^3(uv^7)^((q-5)/8) */ fe_sq(vxx,h->X); fe_mul(vxx,vxx,v); fe_sub(check,vxx,u); /* vx^2-u */ if (fe_isnonzero(check)) { fe_add(check,vxx,u); /* vx^2+u */ if (fe_isnonzero(check)) return -1; fe_mul(h->X,h->X,sqrtm1); } if (fe_isnegative(h->X) == (s[31] >> 7)) fe_neg(h->X,h->X); fe_mul(h->T,h->X,h->Y); return 0; } /* r = p + q */ void ge_madd(ge_p1p1 *r,const ge_p3 *p,const ge_precomp *q) { fe t0; #include "ge_madd.h" } /* r = p - q */ void ge_msub(ge_p1p1 *r,const ge_p3 *p,const ge_precomp *q) { fe t0; #include "ge_msub.h" } /* r = p */ extern void ge_p1p1_to_p2(ge_p2 *r,const ge_p1p1 *p) { fe_mul(r->X,p->X,p->T); fe_mul(r->Y,p->Y,p->Z); fe_mul(r->Z,p->Z,p->T); } /* r = p */ extern void ge_p1p1_to_p3(ge_p3 *r,const ge_p1p1 *p) { fe_mul(r->X,p->X,p->T); fe_mul(r->Y,p->Y,p->Z); fe_mul(r->Z,p->Z,p->T); fe_mul(r->T,p->X,p->Y); } void ge_p2_0(ge_p2 *h) { fe_0(h->X); fe_1(h->Y); fe_1(h->Z); } /* r = 2 * p */ void ge_p2_dbl(ge_p1p1 *r,const ge_p2 *p) { fe t0; #include "ge_p2_dbl.h" } void ge_p3_0(ge_p3 *h) { fe_0(h->X); fe_1(h->Y); fe_1(h->Z); fe_0(h->T); } /* r = 2 * p */ void ge_p3_dbl(ge_p1p1 *r,const ge_p3 *p) { ge_p2 q; ge_p3_to_p2(&q,p); ge_p2_dbl(r,&q); } /* r = p */ static const fe d2 = { #include "d2.h" } ; extern void ge_p3_to_cached(ge_cached *r,const ge_p3 *p) { fe_add(r->YplusX,p->Y,p->X); fe_sub(r->YminusX,p->Y,p->X); fe_copy(r->Z,p->Z); fe_mul(r->T2d,p->T,d2); } /* r = p */ extern void ge_p3_to_p2(ge_p2 *r,const ge_p3 *p) { fe_copy(r->X,p->X); fe_copy(r->Y,p->Y); fe_copy(r->Z,p->Z); } void ge_p3_tobytes(unsigned char *s,const ge_p3 *h) { fe recip; fe x; fe y; fe_invert(recip,h->Z); fe_mul(x,h->X,recip); fe_mul(y,h->Y,recip); fe_tobytes(s,y); s[31] ^= fe_isnegative(x) << 7; } void ge_precomp_0(ge_precomp *h) { fe_1(h->yplusx); fe_1(h->yminusx); fe_0(h->xy2d); } static uint8_t equal(int8_t b,int8_t c) { uint8_t ub = b; uint8_t uc = c; uint8_t x = ub ^ uc; /* 0: yes; 1..255: no */ uint32_t y = x; /* 0: yes; 1..255: no */ y -= 1; /* 4294967295: yes; 0..254: no */ y >>= 31; /* 1: yes; 0: no */ return y; } static uint8_t negative(int8_t b) { unsigned long long x = b; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */ x >>= 63; /* 1: yes; 0: no */ return x; } static void cmov(ge_precomp *t,ge_precomp *u,int8_t b) { fe_cmov(t->yplusx,u->yplusx,b); fe_cmov(t->yminusx,u->yminusx,b); fe_cmov(t->xy2d,u->xy2d,b); } /* base[i][j] = (j+1)*256^i*B */ static ge_precomp base[32][8] = { #include "base.h" } ; static void select(ge_precomp *t,int pos,int8_t b) { ge_precomp minust; uint8_t bnegative = negative(b); uint8_t babs = b - (((-bnegative) & b) << 1); ge_precomp_0(t); cmov(t,&base[pos][0],equal(babs,1)); cmov(t,&base[pos][1],equal(babs,2)); cmov(t,&base[pos][2],equal(babs,3)); cmov(t,&base[pos][3],equal(babs,4)); cmov(t,&base[pos][4],equal(babs,5)); cmov(t,&base[pos][5],equal(babs,6)); cmov(t,&base[pos][6],equal(babs,7)); cmov(t,&base[pos][7],equal(babs,8)); fe_copy(minust.yplusx,t->yminusx); fe_copy(minust.yminusx,t->yplusx); fe_neg(minust.xy2d,t->xy2d); cmov(t,&minust,bnegative); } /* h = a * B where a = a[0]+256*a[1]+...+256^31 a[31] B is the Ed25519 base point (x,4/5) with x positive. Preconditions: a[31] <= 127 */ void ge_scalarmult_base(ge_p3 *h,const uint8_t *a) { int8_t e[64]; int8_t carry; ge_p1p1 r; ge_p2 s; ge_precomp t; int i; for (i = 0;i < 32;++i) { e[2 * i + 0] = (a[i] >> 0) & 15; e[2 * i + 1] = (a[i] >> 4) & 15; } /* each e[i] is between 0 and 15 */ /* e[63] is between 0 and 7 */ carry = 0; for (i = 0;i < 63;++i) { e[i] += carry; carry = e[i] + 8; carry >>= 4; e[i] -= carry << 4; } e[63] += carry; /* each e[i] is between -8 and 8 */ ge_p3_0(h); for (i = 1;i < 64;i += 2) { select(&t,i / 2,e[i]); ge_madd(&r,h,&t); ge_p1p1_to_p3(h,&r); } ge_p3_dbl(&r,h); ge_p1p1_to_p2(&s,&r); ge_p2_dbl(&r,&s); ge_p1p1_to_p2(&s,&r); ge_p2_dbl(&r,&s); ge_p1p1_to_p2(&s,&r); ge_p2_dbl(&r,&s); ge_p1p1_to_p3(h,&r); for (i = 0;i < 64;i += 2) { select(&t,i / 2,e[i]); ge_madd(&r,h,&t); ge_p1p1_to_p3(h,&r); } } /* r = p - q */ void ge_sub(ge_p1p1 *r,const ge_p3 *p,const ge_cached *q) { fe t0; #include "ge_sub.h" } void ge_tobytes(unsigned char *s,const ge_p2 *h) { fe recip; fe x; fe y; fe_invert(recip,h->Z); fe_mul(x,h->X,recip); fe_mul(y,h->Y,recip); fe_tobytes(s,y); s[31] ^= fe_isnegative(x) << 7; } ed25519-1.2.4/ext/ed25519_ref10/keypair.c0000644000004100000410000000064213260523700017147 0ustar www-datawww-data#include #include "ed25519_ref10.h" #include "sha512.h" #include "ge.h" int crypto_sign_ed25519_ref10_seed_keypair(uint8_t *pk, uint8_t *sk, const uint8_t *seed) { ge_p3 A; crypto_hash_sha512(sk, seed, 32); sk[0] &= 248; sk[31] &= 127; sk[31] |= 64; ge_scalarmult_base(&A, sk); ge_p3_tobytes(pk, &A); memmove(sk, seed, 32); memmove(sk + 32, pk, 32); return 0; } ed25519-1.2.4/ext/ed25519_ref10/open.c0000644000004100000410000000171613260523700016447 0ustar www-datawww-data#include #include "sha512.h" #include "ed25519_ref10.h" #include "ge.h" #include "sc.h" int crypto_sign_open_ed25519_ref10( uint8_t *m, uint64_t *mlen, const uint8_t *sm, uint64_t smlen, const uint8_t *pk ) { unsigned char pkcopy[32]; unsigned char rcopy[32]; unsigned char scopy[32]; unsigned char h[64]; unsigned char rcheck[32]; ge_p3 A; ge_p2 R; if (smlen < 64) goto badsig; if (sm[63] & 224) goto badsig; if (ge_frombytes_negate_vartime(&A,pk) != 0) goto badsig; memmove(pkcopy,pk,32); memmove(rcopy,sm,32); memmove(scopy,sm + 32,32); memmove(m,sm,smlen); memmove(m + 32,pkcopy,32); crypto_hash_sha512(h,m,smlen); sc_reduce(h); ge_double_scalarmult_vartime(&R,h,&A,scopy); ge_tobytes(rcheck,&R); if (crypto_verify_32(rcheck,rcopy) == 0) { memmove(m,m + 64,smlen - 64); memset(m + smlen - 64,0,64); *mlen = smlen - 64; return 0; } badsig: *mlen = -1; memset(m,0,smlen); return -1; } ed25519-1.2.4/ext/ed25519_ref10/d2.h0000644000004100000410000000013213260523700016007 0ustar www-datawww-data-21827239,-5839606,-30745221,13898782,229458,15978800,-12551817,-6495438,29715968,9444199 ed25519-1.2.4/ext/ed25519_ref10/fe.h0000644000004100000410000000361713260523700016107 0ustar www-datawww-data#ifndef FE_H #define FE_H #include "ed25519_ref10.h" typedef int32_t fe[10]; /* fe means field element. Here the field is \Z/(2^255-19). An element t, entries t[0]...t[9], represents the integer t[0]+2^26 t[1]+2^51 t[2]+2^77 t[3]+2^102 t[4]+...+2^230 t[9]. Bounds on each t[i] vary depending on context. */ #define fe_frombytes crypto_sign_ed25519_ref10_fe_frombytes #define fe_tobytes crypto_sign_ed25519_ref10_fe_tobytes #define fe_copy crypto_sign_ed25519_ref10_fe_copy #define fe_isnonzero crypto_sign_ed25519_ref10_fe_isnonzero #define fe_isnegative crypto_sign_ed25519_ref10_fe_isnegative #define fe_0 crypto_sign_ed25519_ref10_fe_0 #define fe_1 crypto_sign_ed25519_ref10_fe_1 #define fe_cswap crypto_sign_ed25519_ref10_fe_cswap #define fe_cmov crypto_sign_ed25519_ref10_fe_cmov #define fe_add crypto_sign_ed25519_ref10_fe_add #define fe_sub crypto_sign_ed25519_ref10_fe_sub #define fe_neg crypto_sign_ed25519_ref10_fe_neg #define fe_mul crypto_sign_ed25519_ref10_fe_mul #define fe_sq crypto_sign_ed25519_ref10_fe_sq #define fe_sq2 crypto_sign_ed25519_ref10_fe_sq2 #define fe_mul121666 crypto_sign_ed25519_ref10_fe_mul121666 #define fe_invert crypto_sign_ed25519_ref10_fe_invert #define fe_pow22523 crypto_sign_ed25519_ref10_fe_pow22523 extern void fe_frombytes(fe,const unsigned char *); extern void fe_tobytes(unsigned char *,const fe); extern void fe_copy(fe,const fe); extern int fe_isnonzero(const fe); extern int fe_isnegative(const fe); extern void fe_0(fe); extern void fe_1(fe); extern void fe_cswap(fe,fe,unsigned int); extern void fe_cmov(fe,const fe,unsigned int); extern void fe_add(fe,const fe,const fe); extern void fe_sub(fe,const fe,const fe); extern void fe_neg(fe,const fe); extern void fe_mul(fe,const fe,const fe); extern void fe_sq(fe,const fe); extern void fe_sq2(fe,const fe); extern void fe_mul121666(fe,const fe); extern void fe_invert(fe,const fe); extern void fe_pow22523(fe,const fe); #endif ed25519-1.2.4/ext/ed25519_ref10/pow22523.h0000644000004100000410000001261613260523700016717 0ustar www-datawww-data /* qhasm: fe z1 */ /* qhasm: fe z2 */ /* qhasm: fe z8 */ /* qhasm: fe z9 */ /* qhasm: fe z11 */ /* qhasm: fe z22 */ /* qhasm: fe z_5_0 */ /* qhasm: fe z_10_5 */ /* qhasm: fe z_10_0 */ /* qhasm: fe z_20_10 */ /* qhasm: fe z_20_0 */ /* qhasm: fe z_40_20 */ /* qhasm: fe z_40_0 */ /* qhasm: fe z_50_10 */ /* qhasm: fe z_50_0 */ /* qhasm: fe z_100_50 */ /* qhasm: fe z_100_0 */ /* qhasm: fe z_200_100 */ /* qhasm: fe z_200_0 */ /* qhasm: fe z_250_50 */ /* qhasm: fe z_250_0 */ /* qhasm: fe z_252_2 */ /* qhasm: fe z_252_3 */ /* qhasm: enter pow22523 */ /* qhasm: z2 = z1^2^1 */ /* asm 1: fe_sq(>z2=fe#1,z2=fe#1,>z2=fe#1); */ /* asm 2: fe_sq(>z2=t0,z2=t0,>z2=t0); */ fe_sq(t0,z); for (i = 1;i < 1;++i) fe_sq(t0,t0); /* qhasm: z8 = z2^2^2 */ /* asm 1: fe_sq(>z8=fe#2,z8=fe#2,>z8=fe#2); */ /* asm 2: fe_sq(>z8=t1,z8=t1,>z8=t1); */ fe_sq(t1,t0); for (i = 1;i < 2;++i) fe_sq(t1,t1); /* qhasm: z9 = z1*z8 */ /* asm 1: fe_mul(>z9=fe#2,z9=t1,z11=fe#1,z11=t0,z22=fe#1,z22=fe#1,>z22=fe#1); */ /* asm 2: fe_sq(>z22=t0,z22=t0,>z22=t0); */ fe_sq(t0,t0); for (i = 1;i < 1;++i) fe_sq(t0,t0); /* qhasm: z_5_0 = z9*z22 */ /* asm 1: fe_mul(>z_5_0=fe#1,z_5_0=t0,z_10_5=fe#2,z_10_5=fe#2,>z_10_5=fe#2); */ /* asm 2: fe_sq(>z_10_5=t1,z_10_5=t1,>z_10_5=t1); */ fe_sq(t1,t0); for (i = 1;i < 5;++i) fe_sq(t1,t1); /* qhasm: z_10_0 = z_10_5*z_5_0 */ /* asm 1: fe_mul(>z_10_0=fe#1,z_10_0=t0,z_20_10=fe#2,z_20_10=fe#2,>z_20_10=fe#2); */ /* asm 2: fe_sq(>z_20_10=t1,z_20_10=t1,>z_20_10=t1); */ fe_sq(t1,t0); for (i = 1;i < 10;++i) fe_sq(t1,t1); /* qhasm: z_20_0 = z_20_10*z_10_0 */ /* asm 1: fe_mul(>z_20_0=fe#2,z_20_0=t1,z_40_20=fe#3,z_40_20=fe#3,>z_40_20=fe#3); */ /* asm 2: fe_sq(>z_40_20=t2,z_40_20=t2,>z_40_20=t2); */ fe_sq(t2,t1); for (i = 1;i < 20;++i) fe_sq(t2,t2); /* qhasm: z_40_0 = z_40_20*z_20_0 */ /* asm 1: fe_mul(>z_40_0=fe#2,z_40_0=t1,z_50_10=fe#2,z_50_10=fe#2,>z_50_10=fe#2); */ /* asm 2: fe_sq(>z_50_10=t1,z_50_10=t1,>z_50_10=t1); */ fe_sq(t1,t1); for (i = 1;i < 10;++i) fe_sq(t1,t1); /* qhasm: z_50_0 = z_50_10*z_10_0 */ /* asm 1: fe_mul(>z_50_0=fe#1,z_50_0=t0,z_100_50=fe#2,z_100_50=fe#2,>z_100_50=fe#2); */ /* asm 2: fe_sq(>z_100_50=t1,z_100_50=t1,>z_100_50=t1); */ fe_sq(t1,t0); for (i = 1;i < 50;++i) fe_sq(t1,t1); /* qhasm: z_100_0 = z_100_50*z_50_0 */ /* asm 1: fe_mul(>z_100_0=fe#2,z_100_0=t1,z_200_100=fe#3,z_200_100=fe#3,>z_200_100=fe#3); */ /* asm 2: fe_sq(>z_200_100=t2,z_200_100=t2,>z_200_100=t2); */ fe_sq(t2,t1); for (i = 1;i < 100;++i) fe_sq(t2,t2); /* qhasm: z_200_0 = z_200_100*z_100_0 */ /* asm 1: fe_mul(>z_200_0=fe#2,z_200_0=t1,z_250_50=fe#2,z_250_50=fe#2,>z_250_50=fe#2); */ /* asm 2: fe_sq(>z_250_50=t1,z_250_50=t1,>z_250_50=t1); */ fe_sq(t1,t1); for (i = 1;i < 50;++i) fe_sq(t1,t1); /* qhasm: z_250_0 = z_250_50*z_50_0 */ /* asm 1: fe_mul(>z_250_0=fe#1,z_250_0=t0,z_252_2=fe#1,z_252_2=fe#1,>z_252_2=fe#1); */ /* asm 2: fe_sq(>z_252_2=t0,z_252_2=t0,>z_252_2=t0); */ fe_sq(t0,t0); for (i = 1;i < 2;++i) fe_sq(t0,t0); /* qhasm: z_252_3 = z_252_2*z1 */ /* asm 1: fe_mul(>z_252_3=fe#12,z_252_3=out,YpX1=fe#1,YpX1=r->X,Y,X); */ fe_add(r->X,p->Y,p->X); /* qhasm: YmX1 = Y1-X1 */ /* asm 1: fe_sub(>YmX1=fe#2,YmX1=r->Y,Y,X); */ fe_sub(r->Y,p->Y,p->X); /* qhasm: A = YpX1*YmX2 */ /* asm 1: fe_mul(>A=fe#3,A=r->Z,X,YminusX); */ fe_mul(r->Z,r->X,q->YminusX); /* qhasm: B = YmX1*YpX2 */ /* asm 1: fe_mul(>B=fe#2,B=r->Y,Y,YplusX); */ fe_mul(r->Y,r->Y,q->YplusX); /* qhasm: C = T2d2*T1 */ /* asm 1: fe_mul(>C=fe#4,C=r->T,T2d,T); */ fe_mul(r->T,q->T2d,p->T); /* qhasm: ZZ = Z1*Z2 */ /* asm 1: fe_mul(>ZZ=fe#1,ZZ=r->X,Z,Z); */ fe_mul(r->X,p->Z,q->Z); /* qhasm: D = 2*ZZ */ /* asm 1: fe_add(>D=fe#5,D=t0,X,X); */ fe_add(t0,r->X,r->X); /* qhasm: X3 = A-B */ /* asm 1: fe_sub(>X3=fe#1,X3=r->X,Z,Y); */ fe_sub(r->X,r->Z,r->Y); /* qhasm: Y3 = A+B */ /* asm 1: fe_add(>Y3=fe#2,Y3=r->Y,Z,Y); */ fe_add(r->Y,r->Z,r->Y); /* qhasm: Z3 = D-C */ /* asm 1: fe_sub(>Z3=fe#3,Z3=r->Z,T); */ fe_sub(r->Z,t0,r->T); /* qhasm: T3 = D+C */ /* asm 1: fe_add(>T3=fe#4,T3=r->T,T); */ fe_add(r->T,t0,r->T); /* qhasm: return */ ed25519-1.2.4/ext/ed25519_ref10/verify.c0000644000004100000410000000071213260523700017005 0ustar www-datawww-data#include "ed25519_ref10.h" int crypto_verify_32(const uint8_t *x,const uint8_t *y) { unsigned int differentbits = 0; #define F(i) differentbits |= x[i] ^ y[i]; F(0) F(1) F(2) F(3) F(4) F(5) F(6) F(7) F(8) F(9) F(10) F(11) F(12) F(13) F(14) F(15) F(16) F(17) F(18) F(19) F(20) F(21) F(22) F(23) F(24) F(25) F(26) F(27) F(28) F(29) F(30) F(31) return (1 & ((differentbits - 1) >> 8)) - 1; } ed25519-1.2.4/ext/ed25519_ref10/sc_muladd.c0000644000004100000410000002723513260523700017445 0ustar www-datawww-data#include "sc.h" static uint64_t load_3(const uint8_t *in) { uint64_t result; result = (uint64_t) in[0]; result |= ((uint64_t) in[1]) << 8; result |= ((uint64_t) in[2]) << 16; return result; } static uint64_t load_4(const uint8_t *in) { uint64_t result; result = (uint64_t) in[0]; result |= ((uint64_t) in[1]) << 8; result |= ((uint64_t) in[2]) << 16; result |= ((uint64_t) in[3]) << 24; return result; } /* Input: a[0]+256*a[1]+...+256^31*a[31] = a b[0]+256*b[1]+...+256^31*b[31] = b c[0]+256*c[1]+...+256^31*c[31] = c Output: s[0]+256*s[1]+...+256^31*s[31] = (ab+c) mod l where l = 2^252 + 27742317777372353535851937790883648493. */ void sc_muladd(uint8_t *s,const uint8_t *a,const uint8_t *b,const uint8_t *c) { int64_t a0 = 2097151 & load_3(a); int64_t a1 = 2097151 & (load_4(a + 2) >> 5); int64_t a2 = 2097151 & (load_3(a + 5) >> 2); int64_t a3 = 2097151 & (load_4(a + 7) >> 7); int64_t a4 = 2097151 & (load_4(a + 10) >> 4); int64_t a5 = 2097151 & (load_3(a + 13) >> 1); int64_t a6 = 2097151 & (load_4(a + 15) >> 6); int64_t a7 = 2097151 & (load_3(a + 18) >> 3); int64_t a8 = 2097151 & load_3(a + 21); int64_t a9 = 2097151 & (load_4(a + 23) >> 5); int64_t a10 = 2097151 & (load_3(a + 26) >> 2); int64_t a11 = (load_4(a + 28) >> 7); int64_t b0 = 2097151 & load_3(b); int64_t b1 = 2097151 & (load_4(b + 2) >> 5); int64_t b2 = 2097151 & (load_3(b + 5) >> 2); int64_t b3 = 2097151 & (load_4(b + 7) >> 7); int64_t b4 = 2097151 & (load_4(b + 10) >> 4); int64_t b5 = 2097151 & (load_3(b + 13) >> 1); int64_t b6 = 2097151 & (load_4(b + 15) >> 6); int64_t b7 = 2097151 & (load_3(b + 18) >> 3); int64_t b8 = 2097151 & load_3(b + 21); int64_t b9 = 2097151 & (load_4(b + 23) >> 5); int64_t b10 = 2097151 & (load_3(b + 26) >> 2); int64_t b11 = (load_4(b + 28) >> 7); int64_t c0 = 2097151 & load_3(c); int64_t c1 = 2097151 & (load_4(c + 2) >> 5); int64_t c2 = 2097151 & (load_3(c + 5) >> 2); int64_t c3 = 2097151 & (load_4(c + 7) >> 7); int64_t c4 = 2097151 & (load_4(c + 10) >> 4); int64_t c5 = 2097151 & (load_3(c + 13) >> 1); int64_t c6 = 2097151 & (load_4(c + 15) >> 6); int64_t c7 = 2097151 & (load_3(c + 18) >> 3); int64_t c8 = 2097151 & load_3(c + 21); int64_t c9 = 2097151 & (load_4(c + 23) >> 5); int64_t c10 = 2097151 & (load_3(c + 26) >> 2); int64_t c11 = (load_4(c + 28) >> 7); int64_t s0; int64_t s1; int64_t s2; int64_t s3; int64_t s4; int64_t s5; int64_t s6; int64_t s7; int64_t s8; int64_t s9; int64_t s10; int64_t s11; int64_t s12; int64_t s13; int64_t s14; int64_t s15; int64_t s16; int64_t s17; int64_t s18; int64_t s19; int64_t s20; int64_t s21; int64_t s22; int64_t s23; int64_t carry0; int64_t carry1; int64_t carry2; int64_t carry3; int64_t carry4; int64_t carry5; int64_t carry6; int64_t carry7; int64_t carry8; int64_t carry9; int64_t carry10; int64_t carry11; int64_t carry12; int64_t carry13; int64_t carry14; int64_t carry15; int64_t carry16; int64_t carry17; int64_t carry18; int64_t carry19; int64_t carry20; int64_t carry21; int64_t carry22; /* Merry Christmas! */ s0 = c0 + a0*b0; s1 = c1 + a0*b1 + a1*b0; s2 = c2 + a0*b2 + a1*b1 + a2*b0; s3 = c3 + a0*b3 + a1*b2 + a2*b1 + a3*b0; s4 = c4 + a0*b4 + a1*b3 + a2*b2 + a3*b1 + a4*b0; s5 = c5 + a0*b5 + a1*b4 + a2*b3 + a3*b2 + a4*b1 + a5*b0; s6 = c6 + a0*b6 + a1*b5 + a2*b4 + a3*b3 + a4*b2 + a5*b1 + a6*b0; s7 = c7 + a0*b7 + a1*b6 + a2*b5 + a3*b4 + a4*b3 + a5*b2 + a6*b1 + a7*b0; s8 = c8 + a0*b8 + a1*b7 + a2*b6 + a3*b5 + a4*b4 + a5*b3 + a6*b2 + a7*b1 + a8*b0; s9 = c9 + a0*b9 + a1*b8 + a2*b7 + a3*b6 + a4*b5 + a5*b4 + a6*b3 + a7*b2 + a8*b1 + a9*b0; s10 = c10 + a0*b10 + a1*b9 + a2*b8 + a3*b7 + a4*b6 + a5*b5 + a6*b4 + a7*b3 + a8*b2 + a9*b1 + a10*b0; s11 = c11 + a0*b11 + a1*b10 + a2*b9 + a3*b8 + a4*b7 + a5*b6 + a6*b5 + a7*b4 + a8*b3 + a9*b2 + a10*b1 + a11*b0; s12 = a1*b11 + a2*b10 + a3*b9 + a4*b8 + a5*b7 + a6*b6 + a7*b5 + a8*b4 + a9*b3 + a10*b2 + a11*b1; s13 = a2*b11 + a3*b10 + a4*b9 + a5*b8 + a6*b7 + a7*b6 + a8*b5 + a9*b4 + a10*b3 + a11*b2; s14 = a3*b11 + a4*b10 + a5*b9 + a6*b8 + a7*b7 + a8*b6 + a9*b5 + a10*b4 + a11*b3; s15 = a4*b11 + a5*b10 + a6*b9 + a7*b8 + a8*b7 + a9*b6 + a10*b5 + a11*b4; s16 = a5*b11 + a6*b10 + a7*b9 + a8*b8 + a9*b7 + a10*b6 + a11*b5; s17 = a6*b11 + a7*b10 + a8*b9 + a9*b8 + a10*b7 + a11*b6; s18 = a7*b11 + a8*b10 + a9*b9 + a10*b8 + a11*b7; s19 = a8*b11 + a9*b10 + a10*b9 + a11*b8; s20 = a9*b11 + a10*b10 + a11*b9; s21 = a10*b11 + a11*b10; s22 = a11*b11; s23 = 0; carry0 = (s0 + (1<<20)) >> 21; s1 += carry0; s0 -= carry0 << 21; carry2 = (s2 + (1<<20)) >> 21; s3 += carry2; s2 -= carry2 << 21; carry4 = (s4 + (1<<20)) >> 21; s5 += carry4; s4 -= carry4 << 21; carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21; carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21; carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21; carry12 = (s12 + (1<<20)) >> 21; s13 += carry12; s12 -= carry12 << 21; carry14 = (s14 + (1<<20)) >> 21; s15 += carry14; s14 -= carry14 << 21; carry16 = (s16 + (1<<20)) >> 21; s17 += carry16; s16 -= carry16 << 21; carry18 = (s18 + (1<<20)) >> 21; s19 += carry18; s18 -= carry18 << 21; carry20 = (s20 + (1<<20)) >> 21; s21 += carry20; s20 -= carry20 << 21; carry22 = (s22 + (1<<20)) >> 21; s23 += carry22; s22 -= carry22 << 21; carry1 = (s1 + (1<<20)) >> 21; s2 += carry1; s1 -= carry1 << 21; carry3 = (s3 + (1<<20)) >> 21; s4 += carry3; s3 -= carry3 << 21; carry5 = (s5 + (1<<20)) >> 21; s6 += carry5; s5 -= carry5 << 21; carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21; carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21; carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21; carry13 = (s13 + (1<<20)) >> 21; s14 += carry13; s13 -= carry13 << 21; carry15 = (s15 + (1<<20)) >> 21; s16 += carry15; s15 -= carry15 << 21; carry17 = (s17 + (1<<20)) >> 21; s18 += carry17; s17 -= carry17 << 21; carry19 = (s19 + (1<<20)) >> 21; s20 += carry19; s19 -= carry19 << 21; carry21 = (s21 + (1<<20)) >> 21; s22 += carry21; s21 -= carry21 << 21; s11 += s23 * 666643; s12 += s23 * 470296; s13 += s23 * 654183; s14 -= s23 * 997805; s15 += s23 * 136657; s16 -= s23 * 683901; s23 = 0; s10 += s22 * 666643; s11 += s22 * 470296; s12 += s22 * 654183; s13 -= s22 * 997805; s14 += s22 * 136657; s15 -= s22 * 683901; s22 = 0; s9 += s21 * 666643; s10 += s21 * 470296; s11 += s21 * 654183; s12 -= s21 * 997805; s13 += s21 * 136657; s14 -= s21 * 683901; s21 = 0; s8 += s20 * 666643; s9 += s20 * 470296; s10 += s20 * 654183; s11 -= s20 * 997805; s12 += s20 * 136657; s13 -= s20 * 683901; s20 = 0; s7 += s19 * 666643; s8 += s19 * 470296; s9 += s19 * 654183; s10 -= s19 * 997805; s11 += s19 * 136657; s12 -= s19 * 683901; s19 = 0; s6 += s18 * 666643; s7 += s18 * 470296; s8 += s18 * 654183; s9 -= s18 * 997805; s10 += s18 * 136657; s11 -= s18 * 683901; s18 = 0; carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21; carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21; carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21; carry12 = (s12 + (1<<20)) >> 21; s13 += carry12; s12 -= carry12 << 21; carry14 = (s14 + (1<<20)) >> 21; s15 += carry14; s14 -= carry14 << 21; carry16 = (s16 + (1<<20)) >> 21; s17 += carry16; s16 -= carry16 << 21; carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21; carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21; carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21; carry13 = (s13 + (1<<20)) >> 21; s14 += carry13; s13 -= carry13 << 21; carry15 = (s15 + (1<<20)) >> 21; s16 += carry15; s15 -= carry15 << 21; s5 += s17 * 666643; s6 += s17 * 470296; s7 += s17 * 654183; s8 -= s17 * 997805; s9 += s17 * 136657; s10 -= s17 * 683901; s17 = 0; s4 += s16 * 666643; s5 += s16 * 470296; s6 += s16 * 654183; s7 -= s16 * 997805; s8 += s16 * 136657; s9 -= s16 * 683901; s16 = 0; s3 += s15 * 666643; s4 += s15 * 470296; s5 += s15 * 654183; s6 -= s15 * 997805; s7 += s15 * 136657; s8 -= s15 * 683901; s15 = 0; s2 += s14 * 666643; s3 += s14 * 470296; s4 += s14 * 654183; s5 -= s14 * 997805; s6 += s14 * 136657; s7 -= s14 * 683901; s14 = 0; s1 += s13 * 666643; s2 += s13 * 470296; s3 += s13 * 654183; s4 -= s13 * 997805; s5 += s13 * 136657; s6 -= s13 * 683901; s13 = 0; s0 += s12 * 666643; s1 += s12 * 470296; s2 += s12 * 654183; s3 -= s12 * 997805; s4 += s12 * 136657; s5 -= s12 * 683901; s12 = 0; carry0 = (s0 + (1<<20)) >> 21; s1 += carry0; s0 -= carry0 << 21; carry2 = (s2 + (1<<20)) >> 21; s3 += carry2; s2 -= carry2 << 21; carry4 = (s4 + (1<<20)) >> 21; s5 += carry4; s4 -= carry4 << 21; carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21; carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21; carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21; carry1 = (s1 + (1<<20)) >> 21; s2 += carry1; s1 -= carry1 << 21; carry3 = (s3 + (1<<20)) >> 21; s4 += carry3; s3 -= carry3 << 21; carry5 = (s5 + (1<<20)) >> 21; s6 += carry5; s5 -= carry5 << 21; carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21; carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21; carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21; s0 += s12 * 666643; s1 += s12 * 470296; s2 += s12 * 654183; s3 -= s12 * 997805; s4 += s12 * 136657; s5 -= s12 * 683901; s12 = 0; carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21; carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21; carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21; carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21; carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21; carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21; carry11 = s11 >> 21; s12 += carry11; s11 -= carry11 << 21; s0 += s12 * 666643; s1 += s12 * 470296; s2 += s12 * 654183; s3 -= s12 * 997805; s4 += s12 * 136657; s5 -= s12 * 683901; s12 = 0; carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21; carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21; carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21; carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21; carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21; carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21; s[0] = s0 >> 0; s[1] = s0 >> 8; s[2] = (s0 >> 16) | (s1 << 5); s[3] = s1 >> 3; s[4] = s1 >> 11; s[5] = (s1 >> 19) | (s2 << 2); s[6] = s2 >> 6; s[7] = (s2 >> 14) | (s3 << 7); s[8] = s3 >> 1; s[9] = s3 >> 9; s[10] = (s3 >> 17) | (s4 << 4); s[11] = s4 >> 4; s[12] = s4 >> 12; s[13] = (s4 >> 20) | (s5 << 1); s[14] = s5 >> 7; s[15] = (s5 >> 15) | (s6 << 6); s[16] = s6 >> 2; s[17] = s6 >> 10; s[18] = (s6 >> 18) | (s7 << 3); s[19] = s7 >> 5; s[20] = s7 >> 13; s[21] = s8 >> 0; s[22] = s8 >> 8; s[23] = (s8 >> 16) | (s9 << 5); s[24] = s9 >> 3; s[25] = s9 >> 11; s[26] = (s9 >> 19) | (s10 << 2); s[27] = s10 >> 6; s[28] = (s10 >> 14) | (s11 << 7); s[29] = s11 >> 1; s[30] = s11 >> 9; s[31] = s11 >> 17; } ed25519-1.2.4/ext/ed25519_ref10/sha512.c0000644000004100000410000001770313260523700016514 0ustar www-datawww-data/* 20080913 D. J. Bernstein Public domain. */ #include "sha512.h" static void crypto_hashblocks_sha512(uint8_t *statebytes,const uint8_t *in,uint64_t inlen); #define blocks crypto_hashblocks_sha512 static const uint8_t iv[64] = { 0x6a,0x09,0xe6,0x67,0xf3,0xbc,0xc9,0x08, 0xbb,0x67,0xae,0x85,0x84,0xca,0xa7,0x3b, 0x3c,0x6e,0xf3,0x72,0xfe,0x94,0xf8,0x2b, 0xa5,0x4f,0xf5,0x3a,0x5f,0x1d,0x36,0xf1, 0x51,0x0e,0x52,0x7f,0xad,0xe6,0x82,0xd1, 0x9b,0x05,0x68,0x8c,0x2b,0x3e,0x6c,0x1f, 0x1f,0x83,0xd9,0xab,0xfb,0x41,0xbd,0x6b, 0x5b,0xe0,0xcd,0x19,0x13,0x7e,0x21,0x79 }; int crypto_hash_sha512(uint8_t *out,const uint8_t *in,uint64_t inlen) { uint8_t h[64]; uint8_t padded[256]; uint64_t i; uint64_t bytes = inlen; for (i = 0;i < 64;++i) h[i] = iv[i]; blocks(h,in,inlen); in += inlen; inlen &= 127; in -= inlen; for (i = 0;i < inlen;++i) padded[i] = in[i]; padded[inlen] = 0x80; if (inlen < 112) { for (i = inlen + 1;i < 119;++i) padded[i] = 0; padded[119] = bytes >> 61; padded[120] = bytes >> 53; padded[121] = bytes >> 45; padded[122] = bytes >> 37; padded[123] = bytes >> 29; padded[124] = bytes >> 21; padded[125] = bytes >> 13; padded[126] = bytes >> 5; padded[127] = bytes << 3; blocks(h,padded,128); } else { for (i = inlen + 1;i < 247;++i) padded[i] = 0; padded[247] = bytes >> 61; padded[248] = bytes >> 53; padded[249] = bytes >> 45; padded[250] = bytes >> 37; padded[251] = bytes >> 29; padded[252] = bytes >> 21; padded[253] = bytes >> 13; padded[254] = bytes >> 5; padded[255] = bytes << 3; blocks(h,padded,256); } for (i = 0;i < 64;++i) out[i] = h[i]; return 0; } static uint64_t load_bigendian(const unsigned char *x) { return (uint64_t) (x[7]) \ | (((uint64_t) (x[6])) << 8) \ | (((uint64_t) (x[5])) << 16) \ | (((uint64_t) (x[4])) << 24) \ | (((uint64_t) (x[3])) << 32) \ | (((uint64_t) (x[2])) << 40) \ | (((uint64_t) (x[1])) << 48) \ | (((uint64_t) (x[0])) << 56) ; } static void store_bigendian(unsigned char *x,uint64_t u) { x[7] = u; u >>= 8; x[6] = u; u >>= 8; x[5] = u; u >>= 8; x[4] = u; u >>= 8; x[3] = u; u >>= 8; x[2] = u; u >>= 8; x[1] = u; u >>= 8; x[0] = u; } #define SHR(x,c) ((x) >> (c)) #define ROTR(x,c) (((x) >> (c)) | ((x) << (64 - (c)))) #define Ch(x,y,z) ((x & y) ^ (~x & z)) #define Maj(x,y,z) ((x & y) ^ (x & z) ^ (y & z)) #define Sigma0(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39)) #define Sigma1(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41)) #define sigma0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x,7)) #define sigma1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x,6)) #define M(w0,w14,w9,w1) w0 = sigma1(w14) + w9 + sigma0(w1) + w0; #define EXPAND \ M(w0 ,w14,w9 ,w1 ) \ M(w1 ,w15,w10,w2 ) \ M(w2 ,w0 ,w11,w3 ) \ M(w3 ,w1 ,w12,w4 ) \ M(w4 ,w2 ,w13,w5 ) \ M(w5 ,w3 ,w14,w6 ) \ M(w6 ,w4 ,w15,w7 ) \ M(w7 ,w5 ,w0 ,w8 ) \ M(w8 ,w6 ,w1 ,w9 ) \ M(w9 ,w7 ,w2 ,w10) \ M(w10,w8 ,w3 ,w11) \ M(w11,w9 ,w4 ,w12) \ M(w12,w10,w5 ,w13) \ M(w13,w11,w6 ,w14) \ M(w14,w12,w7 ,w15) \ M(w15,w13,w8 ,w0 ) #define F(w,k) \ T1 = h + Sigma1(e) + Ch(e,f,g) + k + w; \ T2 = Sigma0(a) + Maj(a,b,c); \ h = g; \ g = f; \ f = e; \ e = d + T1; \ d = c; \ c = b; \ b = a; \ a = T1 + T2; static void crypto_hashblocks_sha512(uint8_t *statebytes,const uint8_t *in,uint64_t inlen) { uint64_t state[8]; uint64_t a; uint64_t b; uint64_t c; uint64_t d; uint64_t e; uint64_t f; uint64_t g; uint64_t h; uint64_t T1; uint64_t T2; a = load_bigendian(statebytes + 0); state[0] = a; b = load_bigendian(statebytes + 8); state[1] = b; c = load_bigendian(statebytes + 16); state[2] = c; d = load_bigendian(statebytes + 24); state[3] = d; e = load_bigendian(statebytes + 32); state[4] = e; f = load_bigendian(statebytes + 40); state[5] = f; g = load_bigendian(statebytes + 48); state[6] = g; h = load_bigendian(statebytes + 56); state[7] = h; while (inlen >= 128) { uint64_t w0 = load_bigendian(in + 0); uint64_t w1 = load_bigendian(in + 8); uint64_t w2 = load_bigendian(in + 16); uint64_t w3 = load_bigendian(in + 24); uint64_t w4 = load_bigendian(in + 32); uint64_t w5 = load_bigendian(in + 40); uint64_t w6 = load_bigendian(in + 48); uint64_t w7 = load_bigendian(in + 56); uint64_t w8 = load_bigendian(in + 64); uint64_t w9 = load_bigendian(in + 72); uint64_t w10 = load_bigendian(in + 80); uint64_t w11 = load_bigendian(in + 88); uint64_t w12 = load_bigendian(in + 96); uint64_t w13 = load_bigendian(in + 104); uint64_t w14 = load_bigendian(in + 112); uint64_t w15 = load_bigendian(in + 120); F(w0 ,0x428a2f98d728ae22ULL) F(w1 ,0x7137449123ef65cdULL) F(w2 ,0xb5c0fbcfec4d3b2fULL) F(w3 ,0xe9b5dba58189dbbcULL) F(w4 ,0x3956c25bf348b538ULL) F(w5 ,0x59f111f1b605d019ULL) F(w6 ,0x923f82a4af194f9bULL) F(w7 ,0xab1c5ed5da6d8118ULL) F(w8 ,0xd807aa98a3030242ULL) F(w9 ,0x12835b0145706fbeULL) F(w10,0x243185be4ee4b28cULL) F(w11,0x550c7dc3d5ffb4e2ULL) F(w12,0x72be5d74f27b896fULL) F(w13,0x80deb1fe3b1696b1ULL) F(w14,0x9bdc06a725c71235ULL) F(w15,0xc19bf174cf692694ULL) EXPAND F(w0 ,0xe49b69c19ef14ad2ULL) F(w1 ,0xefbe4786384f25e3ULL) F(w2 ,0x0fc19dc68b8cd5b5ULL) F(w3 ,0x240ca1cc77ac9c65ULL) F(w4 ,0x2de92c6f592b0275ULL) F(w5 ,0x4a7484aa6ea6e483ULL) F(w6 ,0x5cb0a9dcbd41fbd4ULL) F(w7 ,0x76f988da831153b5ULL) F(w8 ,0x983e5152ee66dfabULL) F(w9 ,0xa831c66d2db43210ULL) F(w10,0xb00327c898fb213fULL) F(w11,0xbf597fc7beef0ee4ULL) F(w12,0xc6e00bf33da88fc2ULL) F(w13,0xd5a79147930aa725ULL) F(w14,0x06ca6351e003826fULL) F(w15,0x142929670a0e6e70ULL) EXPAND F(w0 ,0x27b70a8546d22ffcULL) F(w1 ,0x2e1b21385c26c926ULL) F(w2 ,0x4d2c6dfc5ac42aedULL) F(w3 ,0x53380d139d95b3dfULL) F(w4 ,0x650a73548baf63deULL) F(w5 ,0x766a0abb3c77b2a8ULL) F(w6 ,0x81c2c92e47edaee6ULL) F(w7 ,0x92722c851482353bULL) F(w8 ,0xa2bfe8a14cf10364ULL) F(w9 ,0xa81a664bbc423001ULL) F(w10,0xc24b8b70d0f89791ULL) F(w11,0xc76c51a30654be30ULL) F(w12,0xd192e819d6ef5218ULL) F(w13,0xd69906245565a910ULL) F(w14,0xf40e35855771202aULL) F(w15,0x106aa07032bbd1b8ULL) EXPAND F(w0 ,0x19a4c116b8d2d0c8ULL) F(w1 ,0x1e376c085141ab53ULL) F(w2 ,0x2748774cdf8eeb99ULL) F(w3 ,0x34b0bcb5e19b48a8ULL) F(w4 ,0x391c0cb3c5c95a63ULL) F(w5 ,0x4ed8aa4ae3418acbULL) F(w6 ,0x5b9cca4f7763e373ULL) F(w7 ,0x682e6ff3d6b2b8a3ULL) F(w8 ,0x748f82ee5defb2fcULL) F(w9 ,0x78a5636f43172f60ULL) F(w10,0x84c87814a1f0ab72ULL) F(w11,0x8cc702081a6439ecULL) F(w12,0x90befffa23631e28ULL) F(w13,0xa4506cebde82bde9ULL) F(w14,0xbef9a3f7b2c67915ULL) F(w15,0xc67178f2e372532bULL) EXPAND F(w0 ,0xca273eceea26619cULL) F(w1 ,0xd186b8c721c0c207ULL) F(w2 ,0xeada7dd6cde0eb1eULL) F(w3 ,0xf57d4f7fee6ed178ULL) F(w4 ,0x06f067aa72176fbaULL) F(w5 ,0x0a637dc5a2c898a6ULL) F(w6 ,0x113f9804bef90daeULL) F(w7 ,0x1b710b35131c471bULL) F(w8 ,0x28db77f523047d84ULL) F(w9 ,0x32caab7b40c72493ULL) F(w10,0x3c9ebe0a15c9bebcULL) F(w11,0x431d67c49c100d4cULL) F(w12,0x4cc5d4becb3e42b6ULL) F(w13,0x597f299cfc657e2aULL) F(w14,0x5fcb6fab3ad6faecULL) F(w15,0x6c44198c4a475817ULL) a += state[0]; b += state[1]; c += state[2]; d += state[3]; e += state[4]; f += state[5]; g += state[6]; h += state[7]; state[0] = a; state[1] = b; state[2] = c; state[3] = d; state[4] = e; state[5] = f; state[6] = g; state[7] = h; in += 128; inlen -= 128; } store_bigendian(statebytes + 0,state[0]); store_bigendian(statebytes + 8,state[1]); store_bigendian(statebytes + 16,state[2]); store_bigendian(statebytes + 24,state[3]); store_bigendian(statebytes + 32,state[4]); store_bigendian(statebytes + 40,state[5]); store_bigendian(statebytes + 48,state[6]); store_bigendian(statebytes + 56,state[7]); } ed25519-1.2.4/ext/ed25519_ref10/ge_msub.h0000644000004100000410000000355413260523700017136 0ustar www-datawww-data /* qhasm: enter ge_msub */ /* qhasm: fe X1 */ /* qhasm: fe Y1 */ /* qhasm: fe Z1 */ /* qhasm: fe T1 */ /* qhasm: fe ypx2 */ /* qhasm: fe ymx2 */ /* qhasm: fe xy2d2 */ /* qhasm: fe X3 */ /* qhasm: fe Y3 */ /* qhasm: fe Z3 */ /* qhasm: fe T3 */ /* qhasm: fe YpX1 */ /* qhasm: fe YmX1 */ /* qhasm: fe A */ /* qhasm: fe B */ /* qhasm: fe C */ /* qhasm: fe D */ /* qhasm: YpX1 = Y1+X1 */ /* asm 1: fe_add(>YpX1=fe#1,YpX1=r->X,Y,X); */ fe_add(r->X,p->Y,p->X); /* qhasm: YmX1 = Y1-X1 */ /* asm 1: fe_sub(>YmX1=fe#2,YmX1=r->Y,Y,X); */ fe_sub(r->Y,p->Y,p->X); /* qhasm: A = YpX1*ymx2 */ /* asm 1: fe_mul(>A=fe#3,A=r->Z,X,yminusx); */ fe_mul(r->Z,r->X,q->yminusx); /* qhasm: B = YmX1*ypx2 */ /* asm 1: fe_mul(>B=fe#2,B=r->Y,Y,yplusx); */ fe_mul(r->Y,r->Y,q->yplusx); /* qhasm: C = xy2d2*T1 */ /* asm 1: fe_mul(>C=fe#4,C=r->T,xy2d,T); */ fe_mul(r->T,q->xy2d,p->T); /* qhasm: D = 2*Z1 */ /* asm 1: fe_add(>D=fe#5,D=t0,Z,Z); */ fe_add(t0,p->Z,p->Z); /* qhasm: X3 = A-B */ /* asm 1: fe_sub(>X3=fe#1,X3=r->X,Z,Y); */ fe_sub(r->X,r->Z,r->Y); /* qhasm: Y3 = A+B */ /* asm 1: fe_add(>Y3=fe#2,Y3=r->Y,Z,Y); */ fe_add(r->Y,r->Z,r->Y); /* qhasm: Z3 = D-C */ /* asm 1: fe_sub(>Z3=fe#3,Z3=r->Z,T); */ fe_sub(r->Z,t0,r->T); /* qhasm: T3 = D+C */ /* asm 1: fe_add(>T3=fe#4,T3=r->T,T); */ fe_add(r->T,t0,r->T); /* qhasm: return */ ed25519-1.2.4/ext/ed25519_ref10/sha512.h0000644000004100000410000000022613260523700016511 0ustar www-datawww-data#ifndef SHA512_H #define SHA512_H #include int crypto_hash_sha512(uint8_t *out,const uint8_t *in,uint64_t inlen); #endif /* SHA512_H */ ed25519-1.2.4/ext/ed25519_ref10/pow225521.h0000644000004100000410000001262713260523700017004 0ustar www-datawww-data /* qhasm: fe z1 */ /* qhasm: fe z2 */ /* qhasm: fe z8 */ /* qhasm: fe z9 */ /* qhasm: fe z11 */ /* qhasm: fe z22 */ /* qhasm: fe z_5_0 */ /* qhasm: fe z_10_5 */ /* qhasm: fe z_10_0 */ /* qhasm: fe z_20_10 */ /* qhasm: fe z_20_0 */ /* qhasm: fe z_40_20 */ /* qhasm: fe z_40_0 */ /* qhasm: fe z_50_10 */ /* qhasm: fe z_50_0 */ /* qhasm: fe z_100_50 */ /* qhasm: fe z_100_0 */ /* qhasm: fe z_200_100 */ /* qhasm: fe z_200_0 */ /* qhasm: fe z_250_50 */ /* qhasm: fe z_250_0 */ /* qhasm: fe z_255_5 */ /* qhasm: fe z_255_21 */ /* qhasm: enter pow225521 */ /* qhasm: z2 = z1^2^1 */ /* asm 1: fe_sq(>z2=fe#1,z2=fe#1,>z2=fe#1); */ /* asm 2: fe_sq(>z2=t0,z2=t0,>z2=t0); */ fe_sq(t0,z); for (i = 1;i < 1;++i) fe_sq(t0,t0); /* qhasm: z8 = z2^2^2 */ /* asm 1: fe_sq(>z8=fe#2,z8=fe#2,>z8=fe#2); */ /* asm 2: fe_sq(>z8=t1,z8=t1,>z8=t1); */ fe_sq(t1,t0); for (i = 1;i < 2;++i) fe_sq(t1,t1); /* qhasm: z9 = z1*z8 */ /* asm 1: fe_mul(>z9=fe#2,z9=t1,z11=fe#1,z11=t0,z22=fe#3,z22=fe#3,>z22=fe#3); */ /* asm 2: fe_sq(>z22=t2,z22=t2,>z22=t2); */ fe_sq(t2,t0); for (i = 1;i < 1;++i) fe_sq(t2,t2); /* qhasm: z_5_0 = z9*z22 */ /* asm 1: fe_mul(>z_5_0=fe#2,z_5_0=t1,z_10_5=fe#3,z_10_5=fe#3,>z_10_5=fe#3); */ /* asm 2: fe_sq(>z_10_5=t2,z_10_5=t2,>z_10_5=t2); */ fe_sq(t2,t1); for (i = 1;i < 5;++i) fe_sq(t2,t2); /* qhasm: z_10_0 = z_10_5*z_5_0 */ /* asm 1: fe_mul(>z_10_0=fe#2,z_10_0=t1,z_20_10=fe#3,z_20_10=fe#3,>z_20_10=fe#3); */ /* asm 2: fe_sq(>z_20_10=t2,z_20_10=t2,>z_20_10=t2); */ fe_sq(t2,t1); for (i = 1;i < 10;++i) fe_sq(t2,t2); /* qhasm: z_20_0 = z_20_10*z_10_0 */ /* asm 1: fe_mul(>z_20_0=fe#3,z_20_0=t2,z_40_20=fe#4,z_40_20=fe#4,>z_40_20=fe#4); */ /* asm 2: fe_sq(>z_40_20=t3,z_40_20=t3,>z_40_20=t3); */ fe_sq(t3,t2); for (i = 1;i < 20;++i) fe_sq(t3,t3); /* qhasm: z_40_0 = z_40_20*z_20_0 */ /* asm 1: fe_mul(>z_40_0=fe#3,z_40_0=t2,z_50_10=fe#3,z_50_10=fe#3,>z_50_10=fe#3); */ /* asm 2: fe_sq(>z_50_10=t2,z_50_10=t2,>z_50_10=t2); */ fe_sq(t2,t2); for (i = 1;i < 10;++i) fe_sq(t2,t2); /* qhasm: z_50_0 = z_50_10*z_10_0 */ /* asm 1: fe_mul(>z_50_0=fe#2,z_50_0=t1,z_100_50=fe#3,z_100_50=fe#3,>z_100_50=fe#3); */ /* asm 2: fe_sq(>z_100_50=t2,z_100_50=t2,>z_100_50=t2); */ fe_sq(t2,t1); for (i = 1;i < 50;++i) fe_sq(t2,t2); /* qhasm: z_100_0 = z_100_50*z_50_0 */ /* asm 1: fe_mul(>z_100_0=fe#3,z_100_0=t2,z_200_100=fe#4,z_200_100=fe#4,>z_200_100=fe#4); */ /* asm 2: fe_sq(>z_200_100=t3,z_200_100=t3,>z_200_100=t3); */ fe_sq(t3,t2); for (i = 1;i < 100;++i) fe_sq(t3,t3); /* qhasm: z_200_0 = z_200_100*z_100_0 */ /* asm 1: fe_mul(>z_200_0=fe#3,z_200_0=t2,z_250_50=fe#3,z_250_50=fe#3,>z_250_50=fe#3); */ /* asm 2: fe_sq(>z_250_50=t2,z_250_50=t2,>z_250_50=t2); */ fe_sq(t2,t2); for (i = 1;i < 50;++i) fe_sq(t2,t2); /* qhasm: z_250_0 = z_250_50*z_50_0 */ /* asm 1: fe_mul(>z_250_0=fe#2,z_250_0=t1,z_255_5=fe#2,z_255_5=fe#2,>z_255_5=fe#2); */ /* asm 2: fe_sq(>z_255_5=t1,z_255_5=t1,>z_255_5=t1); */ fe_sq(t1,t1); for (i = 1;i < 5;++i) fe_sq(t1,t1); /* qhasm: z_255_21 = z_255_5*z11 */ /* asm 1: fe_mul(>z_255_21=fe#12,z_255_21=out,