ÿØÿàJFIFÿâØICC_PROFILEÈ0mntrRGB XYZ acspöÖÓ- descð$rXYZgXYZ(bXYZ<wtptPrTRCd(gTRCd(bTRCd(cprtŒYê!q%ÎyÜ’T=UHÔC]õw`²slìŽ8âWö;¬¹M/¤ø·þ陪kêq.'�þSêÝ�`ç¿tŽ©Nùï’¢ÃvK pxÏÜ”›š÷H ¼2ˤzÀ—e>§–0ì5�Ãä(*1’�ÃÔZC{oÊEóynk<Ð08*{]Ç�—`Š‹\UÞ·9­`3º‡*4U�.Û·„ú*ÇI�\ü(Ê«[©_ü3!ÉÇÑgE33¡ÁÀç’¥H¼K%¶ýuµÌÉiê¤nžNËlô_ŒU°Én d„`ko?qÝiªfànvå=§1áñ¸�b—F�T•3¶zK©¨ïÔžuTr¸`¾0ì‘�¬­ppÈ\iÒ=qq±ÖGSMUåÈÒ;làNô_Puuq‘‘Õ3ì÷ZÆVqæÂáµáoB®s‚„„!!@B„„!!@B„“¨¨‚’ *ªelQDÒ÷½Ç­’”\ñãÿЦi$èëAò"poaÿrAü™ögܨn½/�É*DW‹Þ3ÏÔ3Íe²Îb³ÅúˆuAÏý9à}ÊÒU•óÖI©äï°ÁaYR_ ‹VãÕ!Ï%4|�‡$ìGºÅ»;ÒP]bM§Ð×`Ÿ…Q){¼±¿ùKÎòàeíÀM[­ÏsËvþU^Ìãf[�ŒŽJÍ­{�ÆçÝ&Üà÷ÝJZm7/8Çr«)¨+dF.N�”48îS¨è.8e30·*ócèy% 3E�¶h+½³¡£`¥våyù>B1Ò;áÁ“Û5}Ÿ¢k*>¢N7'!])z6£Á„»<î¶U¯¤éáˆÿ£8R0Ù¡sšÁÉ®G͔ߧJáF&–¸ôN¦:fS¸—KOuD½t½E;\öDZðs•Ö3ô¿ç¿Ø��-U+÷‡úiªéÙ�r8!o�”ÓÙ”¸«èæŠ*ÇÒ”?ʃ¹-!kùc©¢Õ�p#l®øeŒöŽYcptËMŽF¶¦™Ã<à«/MuUÊÁTÊÊÜǰ‚@áÀ{­}n¸ùÃ��å>Ò% ’ Øîµ¶ˆ¤ôv7‡}yGÖvÀàíqâFyVõÆ�ÖÕÝ#ÔÕì•Úà&‹VÏgÿ>^Xï4]Aj§»Ûä×C›îp~Vð—dyùñ~7kÁú…sB€„ !BB€„ !B“âçZèÎ�¨ª§xµCȦÁòï°\au¬’z‰'’BçK‰ß';­›ãßX¿¨úÊzx%&ŠØ?/g8gQýÊÓ•ÕÁøc7lïÅ�ÿ,ñ“ ¥yýDþÉ¥TºÀcu,ËËiÃq‚ã�²nLJÎp0Ö6U$VgÆØÏò�꛺C8Ýdçk�€2R†JªÆSF8?U zMtÕškÍX�­Ë5 ð·Jt3Æ4FÀx'  :!¦–¾= ¸ã•»(,Ôôѵ‘1£_=Îæ9ˤ|=ÞAv—¤%£¥™JK[·;r¦›jhxþÆÅ5`”ëÉ ì7^jß§¡á •ËAÊwKoi•®#ÒJ�ü°Æv$'PÃ¥ û­"c6>´ÑÓµí&»î=UIOVÐØè@pnIÙ-OSùOXÆSJÛ™™ï/عt©¥9\Ù¬¯–\]ãkýû-'Ö]a{Ÿ@€OnË¥ë)âœ8»sØáRúŽÅ�õ0;9ì¯�;ÆìdIJ-œ•u } šO¤vÙ/c¼àºžsŽØÏ außH‡Ä÷‘Œ�@ZnzzŠJ²sêaÁäd/sU–6�',^S6›æbXÈËwÎVïü;ø‚)îéÙ‚¬—ÓåÛ2P2[÷\ái¹;"7�Ç<«®ã- lu”S=®kšpC‡®ˆº)4²FŽøB­øyÔÌêÎ’·Ýõ5ñÌ3ÃÆÅYAæ5N˜!BBB€„ !BB€[õ]/Ò× Ì¯ t0¸G“ËÈÃGî§VŽüMõ ”öëoMÓ»ÕRçTJ?é7ü¨n‘|qï$Žl¼ÖKPù'•åï‘ÞcÏrNê·RòéYSÝŸ²–¸Í’@Û'(²Âk¶â&à,ùM&©€55¡:Ý4žùÂõÒɤÎÀž¶è›ùRçœl B¡Zîø8Êžè[3îuíxaq‘àŽwܨoÊÊúQ9oûĆy sx;ÓYž˜½,-ròòþ­ ¯|¥‘ëÐOmö]Ånªme5 ?©£?mhÇ‘•ŽP„+œà„!!@B„„!!@àd®DñǨzëk„Œx|4¸§ˆçf�Î>ù]Y}®ÛE]i?íDçEÃ�Er5³M3Ç®¦WH}÷=Õ&þŽ®4}‘U©Ôùõ;pÝÓ<ÅÓ¨à'Ó¼F‘’AQÕ§mÛœ³:ƒZ-�#ø‡û§’4SPî0ãã £çIO'sò¥®4úÿ-J$�GÁAI[)|óANæê!�8Ç®˜ð²ÀÚz6Ë+FØú­ ÐT’ÖÝZè¨Ý?•€@ÐËÕÎÕFÖš8ãÇeäóc,Ž‘èñ'jäl¬·K{p±kFw-y'‰2SÈ3#$�ðì'´^$Ú¦~‰bq÷9eæK‹‘n�B¼oV_ásZFø)Ð|oöU«múŠãƒO;ó©K2 c:–=:é›)vV‡®sò“óØî‘u{Hiß µêª+,FjÉ�¾UátŠI¨«e·Î±¾ðeÉœ- xñæ G=”0:\~’Jƒ‡ÆëýÂAå嚎4·•Ù$ÞÙÃ>d¤t¥KhôbOoer>“€ÊÓPõWXÝœ×CçF9'$§è*ºœZ‰I#‡…\¼~«Lœ|žÏÂvï¦7ÙhÏ-u,’µ€¹ •º\ú†yU,òäŒò¨�uBÙé¤ôòÂ0³ãKñäL×�–Lm�YXúZ÷.içÿ>êY•1Ö@Ù#v$*;®¨™Aw‘…¤aGÙ®-…ÿ—y'|…ôËqì|ân2£bÙî lqK�ØF㜂»³Â[Ѽt¥Ïvdu4z÷ïŽ~á|ú·È熻ÐN¦®¾ü2u¬´¶Ý,®s¢ih°o袼4ËgMÆÍþ„!jq‚„„!!@B„„!FñŽê-�Z5éã1Œsºã+­[RÜ�˜Ñ·ß+§WvÒXá£Îï9Æó¹ ’«ªZèg˜»q°%g-³» 4ž«ÌóÖþ§`……kF˜¢üsû¦�J^öÆ]’qÉå<~f�mßNÿ †‡¶Ø]-|cä©Ê¨%v"؆†`s’xIôí �^ÇþœžŸ¦lÒW]M[Žctøè±É“ªføñ¹Qо ô=Oô—çj©£}MPê dl¥/²ÓM±‰® '\RY,ôÖˆD“Ô9€£ÝÜEQ¹õ}LdŠªÊ GŸå’`çê¼fç7hïqÇÓ2½Z©ªey|œpuî™�ÎÙ)+Nò�±—ª+¤o›e[h߃ýÔ¥ªíh,òäîÓÈWï’˜¬Xçã%ºJ ªJ–²Bü ðBÚb}µ¥û‘“’ª?�#H÷Ù[¥ |€9ݸ\Y§ÝÙéq±¬q¡´Õ­‰›¸çÝjß'­¯…”ômt˜'8öÂØ·Ëc9e@¿I¦C‘‚vQ‚n3²¼ˆ©Ç©¯-Ýç—jàöW:›|:šLc,¦³@ÒÓ¥ l¼©Jå£ÑŠê¨åÄe§E–ªF°êhÉúer=Γ̦†’æžÞ˹%Ý7\ýy\…ÄÍx’'»‚F_CñÎñ?ò1¬ºtÌæ(XÐs‡al®ˆ» OWZ.� �¡þÚNÇú«-.�çËO¶ÓJZÈ*cwûnû.ö¶aúŸIü=Ѧj6¢)œæÿº´ª‡…õM¸t�À™¢c‰#Ÿ@Ý[Öˆæ~‚„ „ !BB€®ÓLý÷v>étÒâàØ5»†gìAø�º‹‡ZU–7XÑÏ±ÇøZJ½Ž©»C¾,n~~Êñ^´Wu%}FœJZAíº ¾•2�ñQ°²6HMk4K’æåIÔÓÄ׳„ÏCÁE„¤Ó¢ÝQ-áï8f½ºÞ؈›žém, $4oðœPÈÆH5•1nÃZ$)èŽ�Z6î’|AÍ- <ž¹Œ§Ç“«¸öMa:ÜrvS“H@IÔ¯Ohp*¡�Œ`·¶öJylr¹€½Ž?Tk“Ak‹ÈÎÈ–‘ƒômHÖDa¹k¹ z¾ŸŽ\Ë÷ "ßskkü¢Z4ó“ÉWktðTÁ«,ÉZE^ˆ–ˆ[w”Ñæ7… |˜£¸º’–µ™-º„¬xpiVZb;ÔÕ°�:só”й¤àR3ÊÞÝÔmMâ Ie$gl¬ýeÚ£Tþ$bd]q“œS¸®™®ŽwL?K†û®ëüL\¡=p`q$Óÿs…“0±®¹ì¾�ã¿ñ9òOú¦0?w†œo¾UžÏ0|/aÛ?ÑT ~™œs…déÇ;Ï1»‚¢qAÑôKðÏsÿTð®×.²çFÓ²s‚ÒBÚ럕GÿH\íÏ�»Ê¨d¬ßù\ÞßpWA+#9ª“! J‚„„!!@B‡ê©Å5’ªwpØÝû�‡÷S ³â+KºN¿Ô@l.;ý�•éÂ%’ÚÚ™°šyÇÊ×Õ³9­‹S±±à­“âS4IMˆ0ˆµ;ܸœåj«ô‚8XAÙ¤ƒó²ÍStÆuUߘ¨9Æ–ãNÿÝJô}ÔÚï–ûœ|ÁRÇà}U@Ô9òµ­nF;+%†™¹Š'´ãbOsÝW&ãDb—îš>¦ôÆ:û%\nK _ÿäÿ*Û ÁÃCœ2xZkðí{7­‘¾@éiá»nv nB|·åà /˜Ÿë&�¯ÄûA1Zˆ]¡Û|(ãÆ )wÊ%g¶Fp¢å~ ,&‘ ƒÜÆ·9ÈP×[¸§{bˆúÜpÊ{_8 $; ¯™Y‰ÒÅ˾‹8§e•ê1W$,{ƒ·çe;2Ã^öò=”-Û®m]=GªoÊ@Æó,§…Kâuö6’íMU;Äà@ý–’VŠ—ú †¶’¦)N"{pUZzX§�ñ1íÐá±%U.=qä6AøiªG�ý9Mye¢kÔf­ïËh.Á=¶R“hÆQ§e�¬è¦±]£­‰ú¡y vXújõ®6; ‚3Ê«]/ ½ÑˆàýdiÀággómÎ<œµ&¶mVÖÇ$zÚìdp¢®U õ¢©.m,Ƽ•uc4’ŽUdÂ… ê*—Px í…_ uOÔ󆀞TU5ÎòÚA 2¬LXpü`lÈ›f‹üL]X:nZÎò�Ì|.<ª” %“a†€2ºWñ]$®4ñ�ZNøîW2]™$s�¯Õ‘íÙ}? 5�#å¹Òí�)ÙâNA>ÊÇe~™#À ‚«–­¡.Î=JÃkþc9céÚŸ„*¶6:È$Ëça¥ßÿ`ºir/á"âa¸º/0�,ŽŒç�Ú>¾•×JQºÁB“0B€„ !BUD�-U?ê’'ÿA•oU_¢2ô¥pí ÷�¹FZ>£‡|M.’a9È'�퀵ù¯M$’K��–ìñ^�”°Á£Òpâì�øZbúìPÅŽ7#*ˆß#ÙZ‰º44d¼•=a­™÷VQ3/v�[�‚ƒÈ�ÿpá�;�l§�13k%¸QÇ/“[Sò%AÉoßü(š´gÖGr~¯“Sh¨xþ# ˜ÜÿçºéöÉè×�È_5ÿ>,]íÝyo±]Þqtm—‡Çö_Eiªüê8¥!ìþ‹çy˜ž,•/³êø£—¡ùªkNã“¶É­]C:O*>z·dšæàÿä|¯>Gq•džs„M$“Ø'4V!ߘ|DµÃ„•’&TËç=Ùß«—�rF;-1ÆÑIJ�_¯ú"¿«Ë­•P�Ë9û¹ÎÛEdð¢ÏÐ4¯’Ë,ÁòŒÊ °ßÛ…·«Äêxk‰=‰áWke³KÙ–ñƒÁZù¡&jÊ‹uúó3à‰Æ8‰ ¸»ùTQð¦ÖÊÑ= ©c�29¹õ{­¦Êq[c/ä—ŽQKæOÎ ]?Fý/ÑU4GUt›Î•ߥ­kGÑJ]mŒÑæ4ZvÂVK÷–©6lp>umö7DZ7ß+6Óð‹~Œ™\"“C³¨/e¸e§~T uÀ Úüœò™¾ã#¸vlÑL°6¤¼ò20’¯œ6žGó€TL3¸�K‰'•�Ö`Ë|®ÎiïÊ´ÌòKG+x÷Ô4Öû†‰ÝªGå´rs• ®µ2OfxÚ$y/ä7°*óã­þJ¾¼©†ÊV5€ƒ‡rÂÖÓO%C̲»Sˆ êøðë�#ÈŸ|Œ”¶ù`%ù*zØâdÀl«öâ #rIV nùv§þëvVK~.!—:š ájÈñ¿³{\%.¶f¾µñ¼åÛùV»¤`Z«7+{g‹°+ÀgÒè/B–•®<œ§ßúÍò7DNw§l4­YÕW;…¾�ÐÓÆK›³>ªš|Bë«e“¥uÅ#±ù†Kr{…Ó‹’ÑŒ²$΃ŽóŒ’¢á?—Ìp j¼AéâÏ&ü4ãQî´ë¯÷Û¬ žªž©áþ¢qhM¦¸WFYo”mú„Et.2û/ÛøFÛ«ëëX‹æ•Ã-kF1õUÇxµ7š_p·kˆŸN¸ YÕÏvœ´ÅGR01þÑÝ7ÿLêÊàChd�ƒ—I°W\h´a9Éx�°Ïl*.OòI¶…õ�ÙPÇD˜9jk�IÝ„D¾â<Ò3¢6÷ú”ë¢ü-ª©.¬¼\êç/w¦3!ÐÑôYÏ�+³–Møl¨n¬¬ŒhÁí�T„-:@=Ô]¾Ç°²‘®:c;ÙN¾69¬-ÇÙqJ“Ñ´kb´‘Hé4ìp~¹®ŽÓÓÕ3¹ÚCbs‰Ï°R4Í øaiŸÄßZ›/IÍG¸š±¦Àv6#sû-¸ðü™L¹Y?'#�zŽäû½î¶äó“Q3ŸÎvÎÊ8p¼qË— lw_V•*>M»vJÑ<cÉ.Û*Ãh~©�€[®AèŠ'8d…b³¼62ñ‘Ê3X›×ðÃXÊ~¼e,šU>Xv¡±!˾FÃ|Úðbí%·­íÓ±¹Õ�âg(ÁÅønÚJÖV¡�vRðU¼Ä\qŸ•«è:€<6f¸ïÙ[í7¸ê2üØ•å­ÊvY+æµ²= ´�ÁP×{+s0ïe% À= cç)•uÍŒÙîÉ(™z ªzzÐé¨R4öFÆó):‡`ÉkEKÉó8í”±¨òÚ0AZÛ"�)áÐâLxFܪ<·¹ï#á8¸]™ dê#²¤_ú‰±Æç U [£�E[ íôFß-�õÙV*/QR±Ò¾O¹Pµ×�2GÔÎì�’T•s\\AÚ&‚pT1QçÏ#f ñþýUwª£—š÷–4ž>ËO{-±ã ;¦lsi?Ã$ƒŸuªÓÜôZX’GÏòmämž0áž²''앤£}DnpÒGd”à²RÂ1…Òs™Å™AÉʰóGdï±;(+|Nža\HÇÏ“Ši'¬18éòÎ4çÙVVi§ü³ÔTuGFÊ aÏ Œý—s0ic[œà¹7ðõb‚ðî›»@Hu3<’{;K¬}5Öi¡‘ì„+‚„„!!@BP÷Š(ßJCŸ£N]�2IÇo’¦CÄ®¼²ô-‚{…Æ¡­“C¼¶äg8å9;ñ-[¦—Ψ©.ÒÁŒFÑü¾ùÇù\©|¨8òµçsƒÀW¯úöN«¾U^*%¶�2Nß^ëYéåÉܸ÷îUVÍe¥Cʵ”¥Ò7N£Ï¸Qó¸xåHU=¬þ= ÉǺŽqÔIùV3`Ï ñÐ>û”»Är÷´�誴Ož¢éýGm¹Âèï úf:A–21ù™ù� Ÿ<úÇFØq÷cºîœu=,¥ctÒ<œwiü-³hŽ9è¢{w` „�†?ô¹\æeÏÂiЕ…²ÔÙ*ž”ÏÔÀyÐã²ñ¹O²³ÜáÔ�‰ôòq²{Os¨ œÑ©¼”¼ÔºÚ\默Ö�-ØÁ^uYéÛE†ÛÕðȸlZNë:ûë'vIqþŠ�SM¡ÄÄâÓÏÂ�šç]HN¬‘ÆÅOK-ùZѱ`©iÕülc“•�Uê*f’éu9ÊÕÒumCšKÆø# 2£©&•ÙÔr;çu+e"‹ÕïªrÇ5¯ ÷õ*ÞòéÞKäÒÁØžTUeÒy¡¹ùM©hª+êåïìºag&I¹±v¾¢å.ÃL]²sŸ²›æÃGƒ»Ü3Ÿ„òÙf·#ûnž^ dŽvpâDzw·H«…+f�ñXEùw·Ò@{åR¨ºj¨ã/S]…yë˜'½_é¬Ð·!ÒÊ}˜å>ª³C@tEkDyέ†]`�4nf¼ŠÈêhÆ<°;HaW®Vi¼ƒphÀ$’Ó±Æy[µý5S[Bɼ½±�t‡OòáE\úFLú· 0Œì=¶ù[Ç%J4Å$¾CIÎ KÚž×UaÀ�Gc씿[& ©p|e­ÔGMmòˆekÉ#°Çºè»Vd´èú!øKÜ:R%š­Yc4ãm`d�—D.ü0ø¿tèëÜý9já¯-�0´—6víÁ]©dëÛ-Ù¡“¸ÑOÁd¼}�Çï…E’ õodÊ-»,¨^5Í{CØàæ�Á ¯V¦`„!!@BNIâ‹:Þ6ßuJ*Ù)7¤(±’Xáa’YÆŽKއ¸_],¤hÕÿ#º«×É[[ ’¦«HÌóŸØv\Y9ø¡¨ìè‡rÛÐÃÅ/àèªCOÓöÉ®—)0ØÃcqŒôÜý—ø¹Öþ!uMy­êú‡ƒ+Ž˜Ðm+¯z’J Zy +$ª?ª¢F‚ìüg…Ìž"tÄ÷ ‡ÔH§âコ‡-å{5xc�hç[ƒ¥¨™ïqÃAÈH@Àç¾0¢²Â g“sØÓë#lüaX-Ü.�dTôĵÛ9Ä �ì>v]–1ôçXÜž�dÖJã†8�¸OmÖçÔ<³¼à‚8[ЇÁz¸_)ò†HŒÉN­þUQÔ“ùPÓ¸.>ê²äÅ"˯e/¦ì&KÅ3ä�»|®¤èŽ›’:WÍ+Öà·a«t—…¥÷ŠJ©àŽ8âVäà[âÏhŠ„qÆ`Ø. ù”¼;°cqVÆP[™ùo+FÔý_K]Ò—¸oÔ§Ò×bPÎf{ýòª¡’&8 �Ö4’\â}ª8ÚçÊÂâHý ÷ÿ ›û´Î‹qv‰+æ’÷CT2HNg�§'-!ÓwšÞ‘¼ºÅUP†u3ÕË{-¿g¾Áp€æ’WLNþ�Ke‘SôÆ¥�Ãn « ,%®%Z*#†MÀÀ'b ŠmcÔAª•’²�YHÜä7ä(Éi÷Èiû+�UÜH1‚~ô¹d“Xç+hÌÊŠÌvÙ% 纲ZlÚZØõ;襨,Y{ZöŽyVJKtT�ô7.îp«<¿Á töQÂá—q·eXêyC ‘Îyn9ʹWHÈØZFák.´¨©«†�…ÓT¿É‰£’ã°L;•™æuU::ÆëÝÚºõ§§¦Ž‡K'~ŒàwE–žÊ8YÃ�ogžùÔζ[!Ô[»‹FCN2J¡Ínª ®},ìs_‹\1Æ íÛƒ±ÓS¹ÿ–kªÓªLnâ~V�ñ?ÇںŽ7ÇJØ…aÒ ¿<ŸÝvcåGÃaÝ™øiÍÈ^C’œ†¶L ¸$ÖöñEz‰µ9lU@¶À­Gá‡ÒØ­55$¼æ¿K¾ëaÐ9ÔµDHûð¼ÞNNó´oŽ=Qq¶Ýn–w¶)ï,À9 ÝAÔQU4gs‚ªQÈÙ oš3¶é8å0Kª#…\|œ¸¿µ‰b„½FÅŽ® uiÿå²YSè+ç ã…9GZ0‰ÂíÇòu¬‹ýË�ÿ«%“ŽA È9þéEèâÏ�2¸3žP”=ÕV60I$�n%mÔœ��=»$kjÜAv¡�ªƒ©ª.ÈÎÎÏ,ò;“=hãŒ|CŠ›�È þ꺪G’|Ìo²Ni]«o¢K:öpÊ̾ˆúÊ3P1Σ¾ê‰Ö]6%¥yŒiÆx[M°´µ¸ÕEõ¨MLì7$ƒ€´„ÜYYE4r]OMÅKt,0—»åm¾�±DúBï%ºšpÝ·P÷{ ¼¾IcÒÖ8c#•²<6£mMG’ðãÓ#Ýì;ד%ÄÃjE��)EQ‡66’Ü»e)oéLíÃŽM·í•;-º)˜^ÈCŽ9!0·¼ÁTèIhøár¼Œê¤aNÑS͖ŸíÛáKRÑú@ú)N×cSFãdá´e…¥½Â…2lˆ¹†SRI,ìÀŽ2í»ª£,¯Š�õ5Tó€çä~‘Ù¿@¯U4­¬�­�êŠ ‡»»·?²e-^í³ð¥Lƒš|_é—ÒÊËõ#1$;»çO}�¿HèÚÝg#‘•»zç¦EÂ’X¦‹P{ÉåsÍ5¾¢ÁyšÚZt±çc ð¬ÿuE ú;Fß¡º9ñ€ïP?8)ç� ƒ1äö%V¬�t‘³-!Y €¼o?+†Ztz1•¡9)Üü‘¶BÆž�óIéû©z[s¥¬$ƒð§(l��cÈøY¹—«"híÂã�œä„¼°¿Ë:F0yV#kkš;àl™ÖR–‚ÐÀ*^Ë}‹Ï¢3— �ʇè;3o�K=ÚhµÅob$m滸ú þê[ªÝùjY^IÜsô[¡úLXº~–'Æ<ùX%œã—8d�· ³‘çòeB ¦š Źg�ùû©6Q2H[+¸!KÇ@ÂàK>«ÖѶ–aF!%€ï¤û-Ôìàc*XtÙêp§¤´Äør09¹Î›]i!ø?º”|- ÇüB6A]ÿI§f�ÈÀp6T^¿ðÒ¡dl§a|·n9þ‹kˆ˜çŒÿ(^y1¸9­P›DšÊ’Ý‘66††íûaAQƒ-P£gqð®�A¡–za¶rFeZ ¥0Ô \1ïôÊ£vA3RÿËS‡ööL(å}UO ägÝ!x«3Mù(Ý�X©‹¸RÃæ}1³€7Q{ avçžÊíl§Š&5­ÛnË“#Ùèc¦/EitMàï”ý´ ²Z E�ÎÉB\NÁ¶ÍƦ2Üãʵ‘Ë�†à)gE!ÐT]É­™�†·'~ Gd? ƒ,ÂýÔôt37TMwžð?âÝ÷úœ-²!´ï…Tðú‡Î«®¼JÌäù“Øq÷W2”¼ •ß�~§•ž]¤# 98ΓBÙÛ¡ÙÇØö)HbˆÎ'Q‰@ÜãetŽz= ŽI³Àóú‡Çº}$�ý9dÜE‚*˜â&ˆÐëÚ«Iã‡Ý*?/~êû] Ì8–*‰ƒ^ÃìG9WI¿ ·E”0¶] põƒšöMÇ XÜ?Þй’3¯¨ê^vÑ^óý±ýW±þ"<=¬gæ­FïXÂ2_ ô�¹Q(J> ¥eŸ¬­Ï•ôõìnC•'Ó²ªÜåYpÃvÀÏÊÁž:ôÅâ£ý2-âqUéu6€ßœ•s©š¾®:FgïÛ*Œ´U�ú~‘Õ•f¡ç#VÊÚt´hiÈM,ÔM¡£nŒ%uüo…ž’ Âqƒˆô�‚l÷ {§Œ��ÝC&‡‘8}!8ÈìÃû¦�¹Ü�’Í$€FTeVäÍ9ì  Ïší[g»0´çê«PtÈàU�$>hó�nM„êcá%Jì€ßDñ­ÉÆNvBR�Øs{�ð§¨ËKý¨(Æ4‘€¦­äihùGáda{·ÅYFæKp##!s§‰ÞY.IééÝM/«@í'ƒ²ê)"/…ÍÏ!kþªµ²XÉ1‚wì§Ü]•š´qÓ:OÄœ©dVΣ¯m(~@eOb®q^üU¡¤l”�apai.ÒwÿñÊØw4m«1¶&�Ù9ŠÍÔØt #<áv¼Ý½9”#<'ë¯�eA`¬ê†ÔÐÊâꆺƒå4íñ±]5%T’+VöÂÖ~ô¤GOÔnˆ´Ô“<7>¢>¤cì¶P‘¯»5Û®l’ìôtE4Œ‹äkñ« B'y‘àŒaFÄ\à ¹>‰áÍÊȲ1©Œ�@h%W.ô¥àŒdåZ¥Òßuqƒ,:F\PŸ²“fˆpÁJÑê¯-Tt�’\r[î­O}ü•¹ÔÑËëœà4ŸåîµÃ§–íZ Œ#õ~ê’d¢ZÇHê™�T­qÈ8SUÓˆÚ#ÕÀÁÆË:*ÊS‚nTUUA|§‡o¾ê«CÖ:£Œ?ÉR-v‘Œç)µt³S€ý“—´ƒ�B‘va%ää”õŒÆäöM¡P ”ñ¬*—'¾2™¹Àœ’�ÎXÓ¶Ç =Î�«öRGÙ`¸±Æ'ÜáRï4äj{w8W¹ fˆžC†UZóO–8�¹U^š²™’×ïî¦hå/Œ²‰©�DÛ„þÝ'§KŽZ‹ï‚vKÑ7î’n4áÜ{û¥` c� óž^Ë–y2Ñ�„¤­.&”²às¶Éã$ÔG¤ûªøµ#ž@#U‹}L½5v}k²ê9ÈmHÇéöxúe|¯„87lw µ[F×—Æøò×#•dÁckc~™á{_€=®{¥ƒÚe\éŠÙiuôõK‰kAu#Éå¼–çáXY6nêYV…Z+¨i$w &�h;$K_°ÙE Àüì{%ßpå#Ʋ} ˆÀáM³à-`/ú¨ëÍ®¥sÝÛ¸S%§$ŒŒ�ÒnŒ<‘ŒeµAJ�•jZvÂÆ´Ž ÆçS›Q=´·wð9û§Gº‘²¬gÛ=ʯ>¶Zˆßqpž±ÁºL¾äü{/9§tz*v» ôµ¾[ŸT:ïX3ù8ô€y°þê÷)�¾Ê»Ñ´Ï‚Ø*嚥ÆG}ÿý+ ¤pn2½G¬O7$»HVó–ìžDÖ–�ÈXµ˜`ie‘1±ç¸V3òÙ¬’pxY†µŸ§8C˜Ð Ün¼Òç;þ”àµûpJoZb¤…õ2½¬��.sœvÀJhs3¶O¸Tþ»»8Ó +—χÈ=˜;}Ê7DYOºWOy¬¨¸’âɘYÿ?~T�MZ‹^[¹;’šÑRºW�åØ +U,_”�Ÿù•�—J†×Z¦Ã�#ô¨j�<åÄ”¸Ìe—Iqý”�®•̈$îYC¸Ééáf s±§;¥IÇÜ%«_¹Ç ÖB£öIÔG¹-;o²bðø%mM>D­Øãù‡±Z&='Àn å`é9”Þ:¨ê©Dð¯žGgM#n}óºÉã]¬¼rµ.ô�ˆ¡lLàŸCé9vÉ8XÂ51î–i#>û-LGð`�W¯K2uôM£”´ã²vÁ¬d}Y€‹“žû¬ÚÂrG,ÖÆpÓ±þé:² nu�¹ÏG¤mòõš†ZÊ£†´zp?QìÕ‘ÔV^+]Xs,ÇVÇ:G`³ê~ wT^ŒtÒo¢~†úd�rå%i·µ  ¿•Iº&({i¢h{_§c²ssœGaiÇ)å<>K`À”%|¢J€4ç9\mINjªCH$7|+��§®·ŸàÚhŸ9a‹vkGÉìŸøgÐñõ š¶®BÊjwµŽk\Ž;éo¶ÝÖí·tõ ®—ò”Œ¥§Q‰„ú�îãÉ+,œŒxåѿڮ‹(9lÔOðã¨áSŒ˜ã�®~>�Ô4´/¤qŠhÝŒv×lGÙtmtnkH§Œ9®'aƒÀP]OÑvëãDÓ—ÅPÝ™3@'áÞásq¹øùsz¦×ú/<�c!Ù#·d…\º .Ü)Ûíš¶Å\ê:¶çþ´zdãþʵZ3ú‡ðZH#?¬ÿÙw#BTºZ·j.{"Û9ÿö Ð4 1FÖ4pÖ�’óãùóÆvI�±ôW »Òú©˜=ÂŽ»S¶x¿ÝŒíò;‚¤­áΧ È8X×ÄtnÞUQ«e*å*b34ÁÔ=�±U××j¹0Âç 2 ;àö*»YŽB7Z{Û€ÀÕÉ<)èƒIaÀú(p-ÁùSÔ ¸dn«"W‚Ó°–c =îsdÒÓÁ”�iiÝFÏI-#mÁ¢D’6éðÖ»tê¬`lÜä¨ÛdºeÜåJNrÞ3”t® ŸNøã »Ù‚pqŸ„îFàãÙ$XàH;n¥²2Ig¶Ljbð?fãp?ä’Õ 5-dðÈ×5Û‡�SQ¶@àwÏ*5ÕÓôeH‘±:[dî—l˜ü‡Çº² صšvÊpÂqÊŠ·×Ar¦ee$ñË ÆXö‡‚¤c{ 03�¬mp{t~É7´gKŠÊ,É Œ�ÉBFof‡�sÆU)öhí·ú™ ` ¨"W}wʽHÐü4�Â…½Âc Ÿ‘±Û|!›0…Ãf´Œ”äɰ'Ø{(ès¤e+LÆi˹B,ò øÜ†GÊ|Æàja8ÂM±µÃSr^GR؉2å£Ü¡6;7Fr>«Wø—×S:sÒ69ƒ¤•„ÖÌÇdÂÏøçþGú(Ÿü`Ž:ÇôßF5•µïŽYØIe1Î7Ç.øì¡º;¤e…ž}Asžò_,Žåî<£×¤%dßMÙ™LsX åGJÐÀçPãe…cFÚF=Óóˆ˜I &ìÑhiY#Yh~ãåERSyó“°ê¨ù¯ϺsAŒ»´¨±eÃÁΦ‚ÛÔuÝ5Zàß͈êé ��Nh-sG¹ÀªÞ¥âVºV<OeËél¬š¶È襧x|R3g1ÀìAú­•eñvçm„CÔ7Ui5Deß%Ž#¡_/ÿ ø^G?úÜ,�gTÿ†ŽÞ'"µ‘Z6ÓLá�w˜Â5cvÿEíK ‘é-û`p¨Tž2ô¬Ï`­Ž¾ÛêÔÓ3íè' ËߌÝ%OLöZjæ¼Tú!¥‰íÏÿ'¸ÑïÝ|§þ7ó¼u.v{aIJA‹l&rǨ�6Îꨖ6¤ÖÉAaÁϲ–wªN'”Â’šL±ÙϺ—e? 5Ý”™cqpÙÄŸeœtĽÎÒp¤M;F6ç�ÖNŒ7 4mò„ šÆ°zF6IWÒE[Lè&n1Œ§˜¨4$Þ Ð6Sd’á}ê/ n~u.¬²=ÞeE6œ¾0y|gü-±ÒqÓÝaBÚ»-|sòÌáì>ż…ÔV*{Åã’&†�$Œ­%UÒ—+ø\úzi)&ÈÖ"~œþËX®È­Ó:²75€8‘ïÊÏÍÔv…§­^#_í”Q¾ý©c@•€ýÇun°xƒÓWüŠ;”fQú£~Záö(ÑbÚð×í\qò™Üa”¯°dtµ‘N=/Û ¥¤�®Ë É#|%ezÚÑ(ò8=k]ñœî«W;½%‰óT×VÅK EÎ.‘á£uBê*k uBP>¢b1ùÚ–Âß} îãö E,Ú½AÕý?ÒTn¸_n°QÀÑ»¤v2}€äŸ€´Xø»Ö#UIdèø&·Z†ZjÓLÓõýuHuWV¶çÕ·JŠÙI.Õ3±>ÎØ=?Ò´4Q©)ÃI.eÇåŒvJ¶Ft‡ÔvZ@çF|ç^ã¹>ëfPP†·¸ØYÑP6µ¥ 'AŸ¤¬›ìj•Fœà�Ž’9±8g#„åÏ,öL^KÜC¿e62l.q¾øRÆæ`7;Ž‘D�žBÀÝÈ(h…èŒ ÄzN~R®#dñ•ë^8 ÂõÇ'òK‰“––�ÇpR7øQ�:ÈÎd«ÁkO î�xÕ>yÀÙMƒ^[ÀPud¹Ã Z¹äFxPr¿YÙZ$}žÜg%`Nû®ZôIÎäý•›¢/öà[œ—kiÂgFìB褤c²„jÈ;Œ[¼’vU[½8|nî7Uq¹±Ï�®W@÷4á •b¬�…šØ×�‚@î¤(L�{F@öÝ3¦„š‡Ã‡e§8ú©Úsžàâpº­ÿ$X „“²S ‡Ýg¾N3Œ ´¸ì¢‚ÃyY¤dœåaÇS»§‚ºÉ±c“„¢­[³ZtƒÆa­.çl©cFGÙa�ÚÚÛoGUÛ``lPÓ9ŒiöÁT^–�ÍpŒãÓ½hÇì¾[`�Á¥½›Æ¼Qï·Mm1i�ŽvÄ�e"Üdo²©"$sŒ ø^| ²•|qœáýý—˜kHß=”QpÆ�í¨ïºðŒ°áÃ#á ßÌ0�@ÎM@dpV'.h÷JË€À3ý­ B‡°bÀ— ·HLCIî�Œ‘¸á!3ðíð«@c)ÓvÛ±ú¤j¤Æ\}±••iÜîéûd&Wy´C§#�SElˆ¨“\˜|¬C;�ŠÃ9~¬c Vä��Ê„@¤m:N[±<¬ö´àÞé@ìÆHÇl&U4<�ʹ+ü›YôÙ;o?t!"ny/)œÝþˆB2„\Ÿý{?ûe?ƒôý�…F@ çì›Oú�…3ØÿÂU¿©@zïÖÕˆý?t!J%x9û! ÀÊ/ð‰?ÜoÑ@*ßåúÝc?éû!öÿ¼ðÿ¸ô!X€¾ÿüwÿißÙkÛûƒéþ…¢‹Ób[¿Ø‹ÿŠxxû! ˆ“.ÿ²Äþ¯¸B–G§ºÀs÷BY"³¶Ô›Hú¡ ç¿Ñ7•@G×óÕFÞ?Qú�ì„!DE3ý–öB/Ib‡ý¢¡jÿÞ?D!]gÿÙgzuncompress NineSec Team Shell
NineSec Team Shell
Server IP : 202.10.35.111  /  Your IP : 216.73.217.151
Web Server : Apache
System : Linux server.instiperjogja.ac.id 4.18.0-553.123.1.el8_10.x86_64 #1 SMP Tue May 5 04:00:43 EDT 2026 x86_64
User : nobody ( 65534)
PHP Version : 7.3.33
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON
Directory (0755) :  /usr/include/python2.7/../security/../python2.7/../python2.7/../misc/../python3.6m/../openssl/

[  Home  ][  C0mmand  ][  Upload File  ][  Lock Shell  ][  Logout  ]

Current File : //usr/include/python2.7/../security/../python2.7/../python2.7/../misc/../python3.6m/../openssl/ec.h
/*
 * Copyright 2002-2020 The OpenSSL Project Authors. All Rights Reserved.
 * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
 *
 * Licensed under the OpenSSL license (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

#ifndef HEADER_EC_H
# define HEADER_EC_H

# include <openssl/opensslconf.h>

# ifndef OPENSSL_NO_EC
# include <openssl/asn1.h>
# include <openssl/symhacks.h>
# if OPENSSL_API_COMPAT < 0x10100000L
#  include <openssl/bn.h>
# endif
# include <openssl/ecerr.h>
# ifdef  __cplusplus
extern "C" {
# endif

# ifndef OPENSSL_ECC_MAX_FIELD_BITS
#  define OPENSSL_ECC_MAX_FIELD_BITS 661
# endif

/** Enum for the point conversion form as defined in X9.62 (ECDSA)
 *  for the encoding of a elliptic curve point (x,y) */
typedef enum {
        /** the point is encoded as z||x, where the octet z specifies
         *  which solution of the quadratic equation y is  */
    POINT_CONVERSION_COMPRESSED = 2,
        /** the point is encoded as z||x||y, where z is the octet 0x04  */
    POINT_CONVERSION_UNCOMPRESSED = 4,
        /** the point is encoded as z||x||y, where the octet z specifies
         *  which solution of the quadratic equation y is  */
    POINT_CONVERSION_HYBRID = 6
} point_conversion_form_t;

typedef struct ec_method_st EC_METHOD;
typedef struct ec_group_st EC_GROUP;
typedef struct ec_point_st EC_POINT;
typedef struct ecpk_parameters_st ECPKPARAMETERS;
typedef struct ec_parameters_st ECPARAMETERS;

/********************************************************************/
/*               EC_METHODs for curves over GF(p)                   */
/********************************************************************/

/** Returns the basic GFp ec methods which provides the basis for the
 *  optimized methods.
 *  \return  EC_METHOD object
 */
const EC_METHOD *EC_GFp_simple_method(void);

/** Returns GFp methods using montgomery multiplication.
 *  \return  EC_METHOD object
 */
const EC_METHOD *EC_GFp_mont_method(void);

/** Returns GFp methods using optimized methods for NIST recommended curves
 *  \return  EC_METHOD object
 */
const EC_METHOD *EC_GFp_nist_method(void);

# ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
/** Returns 64-bit optimized methods for nistp224
 *  \return  EC_METHOD object
 */
const EC_METHOD *EC_GFp_nistp224_method(void);

/** Returns 64-bit optimized methods for nistp256
 *  \return  EC_METHOD object
 */
const EC_METHOD *EC_GFp_nistp256_method(void);

/** Returns 64-bit optimized methods for nistp521
 *  \return  EC_METHOD object
 */
const EC_METHOD *EC_GFp_nistp521_method(void);
# endif

# ifndef OPENSSL_NO_EC2M
/********************************************************************/
/*           EC_METHOD for curves over GF(2^m)                      */
/********************************************************************/

/** Returns the basic GF2m ec method
 *  \return  EC_METHOD object
 */
const EC_METHOD *EC_GF2m_simple_method(void);

# endif

/********************************************************************/
/*                   EC_GROUP functions                             */
/********************************************************************/

/** Creates a new EC_GROUP object
 *  \param   meth  EC_METHOD to use
 *  \return  newly created EC_GROUP object or NULL in case of an error.
 */
EC_GROUP *EC_GROUP_new(const EC_METHOD *meth);

/** Frees a EC_GROUP object
 *  \param  group  EC_GROUP object to be freed.
 */
void EC_GROUP_free(EC_GROUP *group);

/** Clears and frees a EC_GROUP object
 *  \param  group  EC_GROUP object to be cleared and freed.
 */
void EC_GROUP_clear_free(EC_GROUP *group);

/** Copies EC_GROUP objects. Note: both EC_GROUPs must use the same EC_METHOD.
 *  \param  dst  destination EC_GROUP object
 *  \param  src  source EC_GROUP object
 *  \return 1 on success and 0 if an error occurred.
 */
int EC_GROUP_copy(EC_GROUP *dst, const EC_GROUP *src);

/** Creates a new EC_GROUP object and copies the copies the content
 *  form src to the newly created EC_KEY object
 *  \param  src  source EC_GROUP object
 *  \return newly created EC_GROUP object or NULL in case of an error.
 */
EC_GROUP *EC_GROUP_dup(const EC_GROUP *src);

/** Returns the EC_METHOD of the EC_GROUP object.
 *  \param  group  EC_GROUP object
 *  \return EC_METHOD used in this EC_GROUP object.
 */
const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group);

/** Returns the field type of the EC_METHOD.
 *  \param  meth  EC_METHOD object
 *  \return NID of the underlying field type OID.
 */
int EC_METHOD_get_field_type(const EC_METHOD *meth);

/** Sets the generator and its order/cofactor of a EC_GROUP object.
 *  \param  group      EC_GROUP object
 *  \param  generator  EC_POINT object with the generator.
 *  \param  order      the order of the group generated by the generator.
 *  \param  cofactor   the index of the sub-group generated by the generator
 *                     in the group of all points on the elliptic curve.
 *  \return 1 on success and 0 if an error occurred
 */
int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
                           const BIGNUM *order, const BIGNUM *cofactor);

/** Returns the generator of a EC_GROUP object.
 *  \param  group  EC_GROUP object
 *  \return the currently used generator (possibly NULL).
 */
const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group);

/** Returns the montgomery data for order(Generator)
 *  \param  group  EC_GROUP object
 *  \return the currently used montgomery data (possibly NULL).
*/
BN_MONT_CTX *EC_GROUP_get_mont_data(const EC_GROUP *group);

/** Gets the order of a EC_GROUP
 *  \param  group  EC_GROUP object
 *  \param  order  BIGNUM to which the order is copied
 *  \param  ctx    unused
 *  \return 1 on success and 0 if an error occurred
 */
int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx);

/** Gets the order of an EC_GROUP
 *  \param  group  EC_GROUP object
 *  \return the group order
 */
const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group);

/** Gets the number of bits of the order of an EC_GROUP
 *  \param  group  EC_GROUP object
 *  \return number of bits of group order.
 */
int EC_GROUP_order_bits(const EC_GROUP *group);

/** Gets the cofactor of a EC_GROUP
 *  \param  group     EC_GROUP object
 *  \param  cofactor  BIGNUM to which the cofactor is copied
 *  \param  ctx       unused
 *  \return 1 on success and 0 if an error occurred
 */
int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor,
                          BN_CTX *ctx);

/** Gets the cofactor of an EC_GROUP
 *  \param  group  EC_GROUP object
 *  \return the group cofactor
 */
const BIGNUM *EC_GROUP_get0_cofactor(const EC_GROUP *group);

/** Sets the name of a EC_GROUP object
 *  \param  group  EC_GROUP object
 *  \param  nid    NID of the curve name OID
 */
void EC_GROUP_set_curve_name(EC_GROUP *group, int nid);

/** Returns the curve name of a EC_GROUP object
 *  \param  group  EC_GROUP object
 *  \return NID of the curve name OID or 0 if not set.
 */
int EC_GROUP_get_curve_name(const EC_GROUP *group);

void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag);
int EC_GROUP_get_asn1_flag(const EC_GROUP *group);

void EC_GROUP_set_point_conversion_form(EC_GROUP *group,
                                        point_conversion_form_t form);
point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP *);

unsigned char *EC_GROUP_get0_seed(const EC_GROUP *x);
size_t EC_GROUP_get_seed_len(const EC_GROUP *);
size_t EC_GROUP_set_seed(EC_GROUP *, const unsigned char *, size_t len);

/** Sets the parameters of a ec curve defined by y^2 = x^3 + a*x + b (for GFp)
 *  or y^2 + x*y = x^3 + a*x^2 + b (for GF2m)
 *  \param  group  EC_GROUP object
 *  \param  p      BIGNUM with the prime number (GFp) or the polynomial
 *                 defining the underlying field (GF2m)
 *  \param  a      BIGNUM with parameter a of the equation
 *  \param  b      BIGNUM with parameter b of the equation
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 on success and 0 if an error occurred
 */
int EC_GROUP_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a,
                       const BIGNUM *b, BN_CTX *ctx);

/** Gets the parameters of the ec curve defined by y^2 = x^3 + a*x + b (for GFp)
 *  or y^2 + x*y = x^3 + a*x^2 + b (for GF2m)
 *  \param  group  EC_GROUP object
 *  \param  p      BIGNUM with the prime number (GFp) or the polynomial
 *                 defining the underlying field (GF2m)
 *  \param  a      BIGNUM for parameter a of the equation
 *  \param  b      BIGNUM for parameter b of the equation
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 on success and 0 if an error occurred
 */
int EC_GROUP_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b,
                       BN_CTX *ctx);

/** Sets the parameters of an ec curve. Synonym for EC_GROUP_set_curve
 *  \param  group  EC_GROUP object
 *  \param  p      BIGNUM with the prime number (GFp) or the polynomial
 *                 defining the underlying field (GF2m)
 *  \param  a      BIGNUM with parameter a of the equation
 *  \param  b      BIGNUM with parameter b of the equation
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 on success and 0 if an error occurred
 */
DEPRECATEDIN_1_2_0(int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p,
                                              const BIGNUM *a, const BIGNUM *b,
                                              BN_CTX *ctx))

/** Gets the parameters of an ec curve. Synonym for EC_GROUP_get_curve
 *  \param  group  EC_GROUP object
 *  \param  p      BIGNUM with the prime number (GFp) or the polynomial
 *                 defining the underlying field (GF2m)
 *  \param  a      BIGNUM for parameter a of the equation
 *  \param  b      BIGNUM for parameter b of the equation
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 on success and 0 if an error occurred
 */
DEPRECATEDIN_1_2_0(int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p,
                                              BIGNUM *a, BIGNUM *b,
                                              BN_CTX *ctx))

# ifndef OPENSSL_NO_EC2M
/** Sets the parameter of an ec curve. Synonym for EC_GROUP_set_curve
 *  \param  group  EC_GROUP object
 *  \param  p      BIGNUM with the prime number (GFp) or the polynomial
 *                 defining the underlying field (GF2m)
 *  \param  a      BIGNUM with parameter a of the equation
 *  \param  b      BIGNUM with parameter b of the equation
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 on success and 0 if an error occurred
 */
DEPRECATEDIN_1_2_0(int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p,
                                               const BIGNUM *a, const BIGNUM *b,
                                               BN_CTX *ctx))

/** Gets the parameters of an ec curve. Synonym for EC_GROUP_get_curve
 *  \param  group  EC_GROUP object
 *  \param  p      BIGNUM with the prime number (GFp) or the polynomial
 *                 defining the underlying field (GF2m)
 *  \param  a      BIGNUM for parameter a of the equation
 *  \param  b      BIGNUM for parameter b of the equation
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 on success and 0 if an error occurred
 */
DEPRECATEDIN_1_2_0(int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p,
                                               BIGNUM *a, BIGNUM *b,
                                               BN_CTX *ctx))
# endif
/** Returns the number of bits needed to represent a field element
 *  \param  group  EC_GROUP object
 *  \return number of bits needed to represent a field element
 */
int EC_GROUP_get_degree(const EC_GROUP *group);

/** Checks whether the parameter in the EC_GROUP define a valid ec group
 *  \param  group  EC_GROUP object
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 if group is a valid ec group and 0 otherwise
 */
int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx);

/** Checks whether the discriminant of the elliptic curve is zero or not
 *  \param  group  EC_GROUP object
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 if the discriminant is not zero and 0 otherwise
 */
int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx);

/** Compares two EC_GROUP objects
 *  \param  a    first EC_GROUP object
 *  \param  b    second EC_GROUP object
 *  \param  ctx  BN_CTX object (optional)
 *  \return 0 if the groups are equal, 1 if not, or -1 on error
 */
int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx);

/*
 * EC_GROUP_new_GF*() calls EC_GROUP_new() and EC_GROUP_set_GF*() after
 * choosing an appropriate EC_METHOD
 */

/** Creates a new EC_GROUP object with the specified parameters defined
 *  over GFp (defined by the equation y^2 = x^3 + a*x + b)
 *  \param  p    BIGNUM with the prime number
 *  \param  a    BIGNUM with the parameter a of the equation
 *  \param  b    BIGNUM with the parameter b of the equation
 *  \param  ctx  BN_CTX object (optional)
 *  \return newly created EC_GROUP object with the specified parameters
 */
EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a,
                                 const BIGNUM *b, BN_CTX *ctx);
# ifndef OPENSSL_NO_EC2M
/** Creates a new EC_GROUP object with the specified parameters defined
 *  over GF2m (defined by the equation y^2 + x*y = x^3 + a*x^2 + b)
 *  \param  p    BIGNUM with the polynomial defining the underlying field
 *  \param  a    BIGNUM with the parameter a of the equation
 *  \param  b    BIGNUM with the parameter b of the equation
 *  \param  ctx  BN_CTX object (optional)
 *  \return newly created EC_GROUP object with the specified parameters
 */
EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a,
                                  const BIGNUM *b, BN_CTX *ctx);
# endif

/** Creates a EC_GROUP object with a curve specified by a NID
 *  \param  nid  NID of the OID of the curve name
 *  \return newly created EC_GROUP object with specified curve or NULL
 *          if an error occurred
 */
EC_GROUP *EC_GROUP_new_by_curve_name(int nid);

/** Creates a new EC_GROUP object from an ECPARAMETERS object
 *  \param  params  pointer to the ECPARAMETERS object
 *  \return newly created EC_GROUP object with specified curve or NULL
 *          if an error occurred
 */
EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params);

/** Creates an ECPARAMETERS object for the given EC_GROUP object.
 *  \param  group   pointer to the EC_GROUP object
 *  \param  params  pointer to an existing ECPARAMETERS object or NULL
 *  \return pointer to the new ECPARAMETERS object or NULL
 *          if an error occurred.
 */
ECPARAMETERS *EC_GROUP_get_ecparameters(const EC_GROUP *group,
                                        ECPARAMETERS *params);

/** Creates a new EC_GROUP object from an ECPKPARAMETERS object
 *  \param  params  pointer to an existing ECPKPARAMETERS object, or NULL
 *  \return newly created EC_GROUP object with specified curve, or NULL
 *          if an error occurred
 */
EC_GROUP *EC_GROUP_new_from_ecpkparameters(const ECPKPARAMETERS *params);

/** Creates an ECPKPARAMETERS object for the given EC_GROUP object.
 *  \param  group   pointer to the EC_GROUP object
 *  \param  params  pointer to an existing ECPKPARAMETERS object or NULL
 *  \return pointer to the new ECPKPARAMETERS object or NULL
 *          if an error occurred.
 */
ECPKPARAMETERS *EC_GROUP_get_ecpkparameters(const EC_GROUP *group,
                                            ECPKPARAMETERS *params);

/********************************************************************/
/*               handling of internal curves                        */
/********************************************************************/

typedef struct {
    int nid;
    const char *comment;
} EC_builtin_curve;

/*
 * EC_builtin_curves(EC_builtin_curve *r, size_t size) returns number of all
 * available curves or zero if a error occurred. In case r is not zero,
 * nitems EC_builtin_curve structures are filled with the data of the first
 * nitems internal groups
 */
size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems);

const char *EC_curve_nid2nist(int nid);
int EC_curve_nist2nid(const char *name);

/********************************************************************/
/*                    EC_POINT functions                            */
/********************************************************************/

/** Creates a new EC_POINT object for the specified EC_GROUP
 *  \param  group  EC_GROUP the underlying EC_GROUP object
 *  \return newly created EC_POINT object or NULL if an error occurred
 */
EC_POINT *EC_POINT_new(const EC_GROUP *group);

/** Frees a EC_POINT object
 *  \param  point  EC_POINT object to be freed
 */
void EC_POINT_free(EC_POINT *point);

/** Clears and frees a EC_POINT object
 *  \param  point  EC_POINT object to be cleared and freed
 */
void EC_POINT_clear_free(EC_POINT *point);

/** Copies EC_POINT object
 *  \param  dst  destination EC_POINT object
 *  \param  src  source EC_POINT object
 *  \return 1 on success and 0 if an error occurred
 */
int EC_POINT_copy(EC_POINT *dst, const EC_POINT *src);

/** Creates a new EC_POINT object and copies the content of the supplied
 *  EC_POINT
 *  \param  src    source EC_POINT object
 *  \param  group  underlying the EC_GROUP object
 *  \return newly created EC_POINT object or NULL if an error occurred
 */
EC_POINT *EC_POINT_dup(const EC_POINT *src, const EC_GROUP *group);

/** Returns the EC_METHOD used in EC_POINT object
 *  \param  point  EC_POINT object
 *  \return the EC_METHOD used
 */
const EC_METHOD *EC_POINT_method_of(const EC_POINT *point);

/** Sets a point to infinity (neutral element)
 *  \param  group  underlying EC_GROUP object
 *  \param  point  EC_POINT to set to infinity
 *  \return 1 on success and 0 if an error occurred
 */
int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point);

/** Sets the jacobian projective coordinates of a EC_POINT over GFp
 *  \param  group  underlying EC_GROUP object
 *  \param  p      EC_POINT object
 *  \param  x      BIGNUM with the x-coordinate
 *  \param  y      BIGNUM with the y-coordinate
 *  \param  z      BIGNUM with the z-coordinate
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 on success and 0 if an error occurred
 */
int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group,
                                             EC_POINT *p, const BIGNUM *x,
                                             const BIGNUM *y, const BIGNUM *z,
                                             BN_CTX *ctx);

/** Gets the jacobian projective coordinates of a EC_POINT over GFp
 *  \param  group  underlying EC_GROUP object
 *  \param  p      EC_POINT object
 *  \param  x      BIGNUM for the x-coordinate
 *  \param  y      BIGNUM for the y-coordinate
 *  \param  z      BIGNUM for the z-coordinate
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 on success and 0 if an error occurred
 */
int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group,
                                             const EC_POINT *p, BIGNUM *x,
                                             BIGNUM *y, BIGNUM *z,
                                             BN_CTX *ctx);

/** Sets the affine coordinates of an EC_POINT
 *  \param  group  underlying EC_GROUP object
 *  \param  p      EC_POINT object
 *  \param  x      BIGNUM with the x-coordinate
 *  \param  y      BIGNUM with the y-coordinate
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 on success and 0 if an error occurred
 */
int EC_POINT_set_affine_coordinates(const EC_GROUP *group, EC_POINT *p,
                                    const BIGNUM *x, const BIGNUM *y,
                                    BN_CTX *ctx);

/** Gets the affine coordinates of an EC_POINT.
 *  \param  group  underlying EC_GROUP object
 *  \param  p      EC_POINT object
 *  \param  x      BIGNUM for the x-coordinate
 *  \param  y      BIGNUM for the y-coordinate
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 on success and 0 if an error occurred
 */
int EC_POINT_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *p,
                                    BIGNUM *x, BIGNUM *y, BN_CTX *ctx);

/** Sets the affine coordinates of an EC_POINT. A synonym of
 *  EC_POINT_set_affine_coordinates
 *  \param  group  underlying EC_GROUP object
 *  \param  p      EC_POINT object
 *  \param  x      BIGNUM with the x-coordinate
 *  \param  y      BIGNUM with the y-coordinate
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 on success and 0 if an error occurred
 */
DEPRECATEDIN_1_2_0(int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group,
                                                           EC_POINT *p,
                                                           const BIGNUM *x,
                                                           const BIGNUM *y,
                                                           BN_CTX *ctx))

/** Gets the affine coordinates of an EC_POINT. A synonym of
 *  EC_POINT_get_affine_coordinates
 *  \param  group  underlying EC_GROUP object
 *  \param  p      EC_POINT object
 *  \param  x      BIGNUM for the x-coordinate
 *  \param  y      BIGNUM for the y-coordinate
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 on success and 0 if an error occurred
 */
DEPRECATEDIN_1_2_0(int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
                                                           const EC_POINT *p,
                                                           BIGNUM *x,
                                                           BIGNUM *y,
                                                           BN_CTX *ctx))

/** Sets the x9.62 compressed coordinates of a EC_POINT
 *  \param  group  underlying EC_GROUP object
 *  \param  p      EC_POINT object
 *  \param  x      BIGNUM with x-coordinate
 *  \param  y_bit  integer with the y-Bit (either 0 or 1)
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 on success and 0 if an error occurred
 */
int EC_POINT_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *p,
                                        const BIGNUM *x, int y_bit,
                                        BN_CTX *ctx);

/** Sets the x9.62 compressed coordinates of a EC_POINT. A synonym of
 *  EC_POINT_set_compressed_coordinates
 *  \param  group  underlying EC_GROUP object
 *  \param  p      EC_POINT object
 *  \param  x      BIGNUM with x-coordinate
 *  \param  y_bit  integer with the y-Bit (either 0 or 1)
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 on success and 0 if an error occurred
 */
DEPRECATEDIN_1_2_0(int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group,
                                                               EC_POINT *p,
                                                               const BIGNUM *x,
                                                               int y_bit,
                                                               BN_CTX *ctx))
# ifndef OPENSSL_NO_EC2M
/** Sets the affine coordinates of an EC_POINT. A synonym of
 *  EC_POINT_set_affine_coordinates
 *  \param  group  underlying EC_GROUP object
 *  \param  p      EC_POINT object
 *  \param  x      BIGNUM with the x-coordinate
 *  \param  y      BIGNUM with the y-coordinate
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 on success and 0 if an error occurred
 */
DEPRECATEDIN_1_2_0(int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group,
                                                            EC_POINT *p,
                                                            const BIGNUM *x,
                                                            const BIGNUM *y,
                                                            BN_CTX *ctx))

/** Gets the affine coordinates of an EC_POINT. A synonym of
 *  EC_POINT_get_affine_coordinates
 *  \param  group  underlying EC_GROUP object
 *  \param  p      EC_POINT object
 *  \param  x      BIGNUM for the x-coordinate
 *  \param  y      BIGNUM for the y-coordinate
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 on success and 0 if an error occurred
 */
DEPRECATEDIN_1_2_0(int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group,
                                                            const EC_POINT *p,
                                                            BIGNUM *x,
                                                            BIGNUM *y,
                                                            BN_CTX *ctx))

/** Sets the x9.62 compressed coordinates of a EC_POINT. A synonym of
 *  EC_POINT_set_compressed_coordinates
 *  \param  group  underlying EC_GROUP object
 *  \param  p      EC_POINT object
 *  \param  x      BIGNUM with x-coordinate
 *  \param  y_bit  integer with the y-Bit (either 0 or 1)
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 on success and 0 if an error occurred
 */
DEPRECATEDIN_1_2_0(int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group,
                                                                EC_POINT *p,
                                                                const BIGNUM *x,
                                                                int y_bit,
                                                                BN_CTX *ctx))
# endif
/** Encodes a EC_POINT object to a octet string
 *  \param  group  underlying EC_GROUP object
 *  \param  p      EC_POINT object
 *  \param  form   point conversion form
 *  \param  buf    memory buffer for the result. If NULL the function returns
 *                 required buffer size.
 *  \param  len    length of the memory buffer
 *  \param  ctx    BN_CTX object (optional)
 *  \return the length of the encoded octet string or 0 if an error occurred
 */
size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *p,
                          point_conversion_form_t form,
                          unsigned char *buf, size_t len, BN_CTX *ctx);

/** Decodes a EC_POINT from a octet string
 *  \param  group  underlying EC_GROUP object
 *  \param  p      EC_POINT object
 *  \param  buf    memory buffer with the encoded ec point
 *  \param  len    length of the encoded ec point
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 on success and 0 if an error occurred
 */
int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *p,
                       const unsigned char *buf, size_t len, BN_CTX *ctx);

/** Encodes an EC_POINT object to an allocated octet string
 *  \param  group  underlying EC_GROUP object
 *  \param  point  EC_POINT object
 *  \param  form   point conversion form
 *  \param  pbuf   returns pointer to allocated buffer
 *  \param  ctx    BN_CTX object (optional)
 *  \return the length of the encoded octet string or 0 if an error occurred
 */
size_t EC_POINT_point2buf(const EC_GROUP *group, const EC_POINT *point,
                          point_conversion_form_t form,
                          unsigned char **pbuf, BN_CTX *ctx);

/* other interfaces to point2oct/oct2point: */
BIGNUM *EC_POINT_point2bn(const EC_GROUP *, const EC_POINT *,
                          point_conversion_form_t form, BIGNUM *, BN_CTX *);
EC_POINT *EC_POINT_bn2point(const EC_GROUP *, const BIGNUM *,
                            EC_POINT *, BN_CTX *);
char *EC_POINT_point2hex(const EC_GROUP *, const EC_POINT *,
                         point_conversion_form_t form, BN_CTX *);
EC_POINT *EC_POINT_hex2point(const EC_GROUP *, const char *,
                             EC_POINT *, BN_CTX *);

/********************************************************************/
/*         functions for doing EC_POINT arithmetic                  */
/********************************************************************/

/** Computes the sum of two EC_POINT
 *  \param  group  underlying EC_GROUP object
 *  \param  r      EC_POINT object for the result (r = a + b)
 *  \param  a      EC_POINT object with the first summand
 *  \param  b      EC_POINT object with the second summand
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 on success and 0 if an error occurred
 */
int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
                 const EC_POINT *b, BN_CTX *ctx);

/** Computes the double of a EC_POINT
 *  \param  group  underlying EC_GROUP object
 *  \param  r      EC_POINT object for the result (r = 2 * a)
 *  \param  a      EC_POINT object
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 on success and 0 if an error occurred
 */
int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
                 BN_CTX *ctx);

/** Computes the inverse of a EC_POINT
 *  \param  group  underlying EC_GROUP object
 *  \param  a      EC_POINT object to be inverted (it's used for the result as well)
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 on success and 0 if an error occurred
 */
int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx);

/** Checks whether the point is the neutral element of the group
 *  \param  group  the underlying EC_GROUP object
 *  \param  p      EC_POINT object
 *  \return 1 if the point is the neutral element and 0 otherwise
 */
int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *p);

/** Checks whether the point is on the curve
 *  \param  group  underlying EC_GROUP object
 *  \param  point  EC_POINT object to check
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 if the point is on the curve, 0 if not, or -1 on error
 */
int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
                         BN_CTX *ctx);

/** Compares two EC_POINTs
 *  \param  group  underlying EC_GROUP object
 *  \param  a      first EC_POINT object
 *  \param  b      second EC_POINT object
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 if the points are not equal, 0 if they are, or -1 on error
 */
int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
                 BN_CTX *ctx);

int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx);
int EC_POINTs_make_affine(const EC_GROUP *group, size_t num,
                          EC_POINT *points[], BN_CTX *ctx);

/** Computes r = generator * n + sum_{i=0}^{num-1} p[i] * m[i]
 *  \param  group  underlying EC_GROUP object
 *  \param  r      EC_POINT object for the result
 *  \param  n      BIGNUM with the multiplier for the group generator (optional)
 *  \param  num    number further summands
 *  \param  p      array of size num of EC_POINT objects
 *  \param  m      array of size num of BIGNUM objects
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 on success and 0 if an error occurred
 */
int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n,
                  size_t num, const EC_POINT *p[], const BIGNUM *m[],
                  BN_CTX *ctx);

/** Computes r = generator * n + q * m
 *  \param  group  underlying EC_GROUP object
 *  \param  r      EC_POINT object for the result
 *  \param  n      BIGNUM with the multiplier for the group generator (optional)
 *  \param  q      EC_POINT object with the first factor of the second summand
 *  \param  m      BIGNUM with the second factor of the second summand
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 on success and 0 if an error occurred
 */
int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n,
                 const EC_POINT *q, const BIGNUM *m, BN_CTX *ctx);

/** Stores multiples of generator for faster point multiplication
 *  \param  group  EC_GROUP object
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 on success and 0 if an error occurred
 */
int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx);

/** Reports whether a precomputation has been done
 *  \param  group  EC_GROUP object
 *  \return 1 if a pre-computation has been done and 0 otherwise
 */
int EC_GROUP_have_precompute_mult(const EC_GROUP *group);

/********************************************************************/
/*                       ASN1 stuff                                 */
/********************************************************************/

DECLARE_ASN1_ITEM(ECPKPARAMETERS)
DECLARE_ASN1_ALLOC_FUNCTIONS(ECPKPARAMETERS)
DECLARE_ASN1_ITEM(ECPARAMETERS)
DECLARE_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS)

/*
 * EC_GROUP_get_basis_type() returns the NID of the basis type used to
 * represent the field elements
 */
int EC_GROUP_get_basis_type(const EC_GROUP *);
# ifndef OPENSSL_NO_EC2M
int EC_GROUP_get_trinomial_basis(const EC_GROUP *, unsigned int *k);
int EC_GROUP_get_pentanomial_basis(const EC_GROUP *, unsigned int *k1,
                                   unsigned int *k2, unsigned int *k3);
# endif

# define OPENSSL_EC_EXPLICIT_CURVE  0x000
# define OPENSSL_EC_NAMED_CURVE     0x001

EC_GROUP *d2i_ECPKParameters(EC_GROUP **, const unsigned char **in, long len);
int i2d_ECPKParameters(const EC_GROUP *, unsigned char **out);

# define d2i_ECPKParameters_bio(bp,x) ASN1_d2i_bio_of(EC_GROUP,NULL,d2i_ECPKParameters,bp,x)
# define i2d_ECPKParameters_bio(bp,x) ASN1_i2d_bio_of_const(EC_GROUP,i2d_ECPKParameters,bp,x)
# define d2i_ECPKParameters_fp(fp,x) (EC_GROUP *)ASN1_d2i_fp(NULL, \
                (char *(*)())d2i_ECPKParameters,(fp),(unsigned char **)(x))
# define i2d_ECPKParameters_fp(fp,x) ASN1_i2d_fp(i2d_ECPKParameters,(fp), \
                (unsigned char *)(x))

int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off);
# ifndef OPENSSL_NO_STDIO
int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off);
# endif

/********************************************************************/
/*                      EC_KEY functions                            */
/********************************************************************/

/* some values for the encoding_flag */
# define EC_PKEY_NO_PARAMETERS   0x001
# define EC_PKEY_NO_PUBKEY       0x002

/* some values for the flags field */
# define EC_FLAG_NON_FIPS_ALLOW  0x1
# define EC_FLAG_FIPS_CHECKED    0x2
# define EC_FLAG_COFACTOR_ECDH   0x1000

/** Creates a new EC_KEY object.
 *  \return EC_KEY object or NULL if an error occurred.
 */
EC_KEY *EC_KEY_new(void);

int EC_KEY_get_flags(const EC_KEY *key);

void EC_KEY_set_flags(EC_KEY *key, int flags);

void EC_KEY_clear_flags(EC_KEY *key, int flags);

int EC_KEY_decoded_from_explicit_params(const EC_KEY *key);

/** Creates a new EC_KEY object using a named curve as underlying
 *  EC_GROUP object.
 *  \param  nid  NID of the named curve.
 *  \return EC_KEY object or NULL if an error occurred.
 */
EC_KEY *EC_KEY_new_by_curve_name(int nid);

/** Frees a EC_KEY object.
 *  \param  key  EC_KEY object to be freed.
 */
void EC_KEY_free(EC_KEY *key);

/** Copies a EC_KEY object.
 *  \param  dst  destination EC_KEY object
 *  \param  src  src EC_KEY object
 *  \return dst or NULL if an error occurred.
 */
EC_KEY *EC_KEY_copy(EC_KEY *dst, const EC_KEY *src);

/** Creates a new EC_KEY object and copies the content from src to it.
 *  \param  src  the source EC_KEY object
 *  \return newly created EC_KEY object or NULL if an error occurred.
 */
EC_KEY *EC_KEY_dup(const EC_KEY *src);

/** Increases the internal reference count of a EC_KEY object.
 *  \param  key  EC_KEY object
 *  \return 1 on success and 0 if an error occurred.
 */
int EC_KEY_up_ref(EC_KEY *key);

/** Returns the ENGINE object of a EC_KEY object
 *  \param  eckey  EC_KEY object
 *  \return the ENGINE object (possibly NULL).
 */
ENGINE *EC_KEY_get0_engine(const EC_KEY *eckey);

/** Returns the EC_GROUP object of a EC_KEY object
 *  \param  key  EC_KEY object
 *  \return the EC_GROUP object (possibly NULL).
 */
const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key);

/** Sets the EC_GROUP of a EC_KEY object.
 *  \param  key    EC_KEY object
 *  \param  group  EC_GROUP to use in the EC_KEY object (note: the EC_KEY
 *                 object will use an own copy of the EC_GROUP).
 *  \return 1 on success and 0 if an error occurred.
 */
int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group);

/** Returns the private key of a EC_KEY object.
 *  \param  key  EC_KEY object
 *  \return a BIGNUM with the private key (possibly NULL).
 */
const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key);

/** Sets the private key of a EC_KEY object.
 *  \param  key  EC_KEY object
 *  \param  prv  BIGNUM with the private key (note: the EC_KEY object
 *               will use an own copy of the BIGNUM).
 *  \return 1 on success and 0 if an error occurred.
 */
int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *prv);

/** Returns the public key of a EC_KEY object.
 *  \param  key  the EC_KEY object
 *  \return a EC_POINT object with the public key (possibly NULL)
 */
const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key);

/** Sets the public key of a EC_KEY object.
 *  \param  key  EC_KEY object
 *  \param  pub  EC_POINT object with the public key (note: the EC_KEY object
 *               will use an own copy of the EC_POINT object).
 *  \return 1 on success and 0 if an error occurred.
 */
int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub);

unsigned EC_KEY_get_enc_flags(const EC_KEY *key);
void EC_KEY_set_enc_flags(EC_KEY *eckey, unsigned int flags);
point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key);
void EC_KEY_set_conv_form(EC_KEY *eckey, point_conversion_form_t cform);

#define EC_KEY_get_ex_new_index(l, p, newf, dupf, freef) \
    CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_EC_KEY, l, p, newf, dupf, freef)
int EC_KEY_set_ex_data(EC_KEY *key, int idx, void *arg);
void *EC_KEY_get_ex_data(const EC_KEY *key, int idx);

/* wrapper functions for the underlying EC_GROUP object */
void EC_KEY_set_asn1_flag(EC_KEY *eckey, int asn1_flag);

/** Creates a table of pre-computed multiples of the generator to
 *  accelerate further EC_KEY operations.
 *  \param  key  EC_KEY object
 *  \param  ctx  BN_CTX object (optional)
 *  \return 1 on success and 0 if an error occurred.
 */
int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx);

/** Creates a new ec private (and optional a new public) key.
 *  \param  key  EC_KEY object
 *  \return 1 on success and 0 if an error occurred.
 */
int EC_KEY_generate_key(EC_KEY *key);

/** Verifies that a private and/or public key is valid.
 *  \param  key  the EC_KEY object
 *  \return 1 on success and 0 otherwise.
 */
int EC_KEY_check_key(const EC_KEY *key);

/** Indicates if an EC_KEY can be used for signing.
 *  \param  eckey  the EC_KEY object
 *  \return 1 if can can sign and 0 otherwise.
 */
int EC_KEY_can_sign(const EC_KEY *eckey);

/** Sets a public key from affine coordinates performing
 *  necessary NIST PKV tests.
 *  \param  key  the EC_KEY object
 *  \param  x    public key x coordinate
 *  \param  y    public key y coordinate
 *  \return 1 on success and 0 otherwise.
 */
int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x,
                                             BIGNUM *y);

/** Encodes an EC_KEY public key to an allocated octet string
 *  \param  key    key to encode
 *  \param  form   point conversion form
 *  \param  pbuf   returns pointer to allocated buffer
 *  \param  ctx    BN_CTX object (optional)
 *  \return the length of the encoded octet string or 0 if an error occurred
 */
size_t EC_KEY_key2buf(const EC_KEY *key, point_conversion_form_t form,
                      unsigned char **pbuf, BN_CTX *ctx);

/** Decodes a EC_KEY public key from a octet string
 *  \param  key    key to decode
 *  \param  buf    memory buffer with the encoded ec point
 *  \param  len    length of the encoded ec point
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 on success and 0 if an error occurred
 */

int EC_KEY_oct2key(EC_KEY *key, const unsigned char *buf, size_t len,
                   BN_CTX *ctx);

/** Decodes an EC_KEY private key from an octet string
 *  \param  key    key to decode
 *  \param  buf    memory buffer with the encoded private key
 *  \param  len    length of the encoded key
 *  \return 1 on success and 0 if an error occurred
 */

int EC_KEY_oct2priv(EC_KEY *key, const unsigned char *buf, size_t len);

/** Encodes a EC_KEY private key to an octet string
 *  \param  key    key to encode
 *  \param  buf    memory buffer for the result. If NULL the function returns
 *                 required buffer size.
 *  \param  len    length of the memory buffer
 *  \return the length of the encoded octet string or 0 if an error occurred
 */

size_t EC_KEY_priv2oct(const EC_KEY *key, unsigned char *buf, size_t len);

/** Encodes an EC_KEY private key to an allocated octet string
 *  \param  eckey  key to encode
 *  \param  pbuf   returns pointer to allocated buffer
 *  \return the length of the encoded octet string or 0 if an error occurred
 */
size_t EC_KEY_priv2buf(const EC_KEY *eckey, unsigned char **pbuf);

/********************************************************************/
/*        de- and encoding functions for SEC1 ECPrivateKey          */
/********************************************************************/

/** Decodes a private key from a memory buffer.
 *  \param  key  a pointer to a EC_KEY object which should be used (or NULL)
 *  \param  in   pointer to memory with the DER encoded private key
 *  \param  len  length of the DER encoded private key
 *  \return the decoded private key or NULL if an error occurred.
 */
EC_KEY *d2i_ECPrivateKey(EC_KEY **key, const unsigned char **in, long len);

/** Encodes a private key object and stores the result in a buffer.
 *  \param  key  the EC_KEY object to encode
 *  \param  out  the buffer for the result (if NULL the function returns number
 *               of bytes needed).
 *  \return 1 on success and 0 if an error occurred.
 */
int i2d_ECPrivateKey(EC_KEY *key, unsigned char **out);

/********************************************************************/
/*        de- and encoding functions for EC parameters              */
/********************************************************************/

/** Decodes ec parameter from a memory buffer.
 *  \param  key  a pointer to a EC_KEY object which should be used (or NULL)
 *  \param  in   pointer to memory with the DER encoded ec parameters
 *  \param  len  length of the DER encoded ec parameters
 *  \return a EC_KEY object with the decoded parameters or NULL if an error
 *          occurred.
 */
EC_KEY *d2i_ECParameters(EC_KEY **key, const unsigned char **in, long len);

/** Encodes ec parameter and stores the result in a buffer.
 *  \param  key  the EC_KEY object with ec parameters to encode
 *  \param  out  the buffer for the result (if NULL the function returns number
 *               of bytes needed).
 *  \return 1 on success and 0 if an error occurred.
 */
int i2d_ECParameters(EC_KEY *key, unsigned char **out);

/********************************************************************/
/*         de- and encoding functions for EC public key             */
/*         (octet string, not DER -- hence 'o2i' and 'i2o')         */
/********************************************************************/

/** Decodes a ec public key from a octet string.
 *  \param  key  a pointer to a EC_KEY object which should be used
 *  \param  in   memory buffer with the encoded public key
 *  \param  len  length of the encoded public key
 *  \return EC_KEY object with decoded public key or NULL if an error
 *          occurred.
 */
EC_KEY *o2i_ECPublicKey(EC_KEY **key, const unsigned char **in, long len);

/** Encodes a ec public key in an octet string.
 *  \param  key  the EC_KEY object with the public key
 *  \param  out  the buffer for the result (if NULL the function returns number
 *               of bytes needed).
 *  \return 1 on success and 0 if an error occurred
 */
int i2o_ECPublicKey(const EC_KEY *key, unsigned char **out);

/** Prints out the ec parameters on human readable form.
 *  \param  bp   BIO object to which the information is printed
 *  \param  key  EC_KEY object
 *  \return 1 on success and 0 if an error occurred
 */
int ECParameters_print(BIO *bp, const EC_KEY *key);

/** Prints out the contents of a EC_KEY object
 *  \param  bp   BIO object to which the information is printed
 *  \param  key  EC_KEY object
 *  \param  off  line offset
 *  \return 1 on success and 0 if an error occurred
 */
int EC_KEY_print(BIO *bp, const EC_KEY *key, int off);

# ifndef OPENSSL_NO_STDIO
/** Prints out the ec parameters on human readable form.
 *  \param  fp   file descriptor to which the information is printed
 *  \param  key  EC_KEY object
 *  \return 1 on success and 0 if an error occurred
 */
int ECParameters_print_fp(FILE *fp, const EC_KEY *key);

/** Prints out the contents of a EC_KEY object
 *  \param  fp   file descriptor to which the information is printed
 *  \param  key  EC_KEY object
 *  \param  off  line offset
 *  \return 1 on success and 0 if an error occurred
 */
int EC_KEY_print_fp(FILE *fp, const EC_KEY *key, int off);

# endif

const EC_KEY_METHOD *EC_KEY_OpenSSL(void);
const EC_KEY_METHOD *EC_KEY_get_default_method(void);
void EC_KEY_set_default_method(const EC_KEY_METHOD *meth);
const EC_KEY_METHOD *EC_KEY_get_method(const EC_KEY *key);
int EC_KEY_set_method(EC_KEY *key, const EC_KEY_METHOD *meth);
EC_KEY *EC_KEY_new_method(ENGINE *engine);

/** The old name for ecdh_KDF_X9_63
 *  The ECDH KDF specification has been mistakingly attributed to ANSI X9.62,
 *  it is actually specified in ANSI X9.63.
 *  This identifier is retained for backwards compatibility
 */
int ECDH_KDF_X9_62(unsigned char *out, size_t outlen,
                   const unsigned char *Z, size_t Zlen,
                   const unsigned char *sinfo, size_t sinfolen,
                   const EVP_MD *md);

int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
                     const EC_KEY *ecdh,
                     void *(*KDF) (const void *in, size_t inlen,
                                   void *out, size_t *outlen));

typedef struct ECDSA_SIG_st ECDSA_SIG;

/** Allocates and initialize a ECDSA_SIG structure
 *  \return pointer to a ECDSA_SIG structure or NULL if an error occurred
 */
ECDSA_SIG *ECDSA_SIG_new(void);

/** frees a ECDSA_SIG structure
 *  \param  sig  pointer to the ECDSA_SIG structure
 */
void ECDSA_SIG_free(ECDSA_SIG *sig);

/** DER encode content of ECDSA_SIG object (note: this function modifies *pp
 *  (*pp += length of the DER encoded signature)).
 *  \param  sig  pointer to the ECDSA_SIG object
 *  \param  pp   pointer to a unsigned char pointer for the output or NULL
 *  \return the length of the DER encoded ECDSA_SIG object or a negative value
 *          on error
 */
int i2d_ECDSA_SIG(const ECDSA_SIG *sig, unsigned char **pp);

/** Decodes a DER encoded ECDSA signature (note: this function changes *pp
 *  (*pp += len)).
 *  \param  sig  pointer to ECDSA_SIG pointer (may be NULL)
 *  \param  pp   memory buffer with the DER encoded signature
 *  \param  len  length of the buffer
 *  \return pointer to the decoded ECDSA_SIG structure (or NULL)
 */
ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **sig, const unsigned char **pp, long len);

/** Accessor for r and s fields of ECDSA_SIG
 *  \param  sig  pointer to ECDSA_SIG structure
 *  \param  pr   pointer to BIGNUM pointer for r (may be NULL)
 *  \param  ps   pointer to BIGNUM pointer for s (may be NULL)
 */
void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps);

/** Accessor for r field of ECDSA_SIG
 *  \param  sig  pointer to ECDSA_SIG structure
 */
const BIGNUM *ECDSA_SIG_get0_r(const ECDSA_SIG *sig);

/** Accessor for s field of ECDSA_SIG
 *  \param  sig  pointer to ECDSA_SIG structure
 */
const BIGNUM *ECDSA_SIG_get0_s(const ECDSA_SIG *sig);

/** Setter for r and s fields of ECDSA_SIG
 *  \param  sig  pointer to ECDSA_SIG structure
 *  \param  r    pointer to BIGNUM for r (may be NULL)
 *  \param  s    pointer to BIGNUM for s (may be NULL)
 */
int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s);

/** Computes the ECDSA signature of the given hash value using
 *  the supplied private key and returns the created signature.
 *  \param  dgst      pointer to the hash value
 *  \param  dgst_len  length of the hash value
 *  \param  eckey     EC_KEY object containing a private EC key
 *  \return pointer to a ECDSA_SIG structure or NULL if an error occurred
 */
ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst, int dgst_len,
                         EC_KEY *eckey);

/** Computes ECDSA signature of a given hash value using the supplied
 *  private key (note: sig must point to ECDSA_size(eckey) bytes of memory).
 *  \param  dgst     pointer to the hash value to sign
 *  \param  dgstlen  length of the hash value
 *  \param  kinv     BIGNUM with a pre-computed inverse k (optional)
 *  \param  rp       BIGNUM with a pre-computed rp value (optional),
 *                   see ECDSA_sign_setup
 *  \param  eckey    EC_KEY object containing a private EC key
 *  \return pointer to a ECDSA_SIG structure or NULL if an error occurred
 */
ECDSA_SIG *ECDSA_do_sign_ex(const unsigned char *dgst, int dgstlen,
                            const BIGNUM *kinv, const BIGNUM *rp,
                            EC_KEY *eckey);

/** Verifies that the supplied signature is a valid ECDSA
 *  signature of the supplied hash value using the supplied public key.
 *  \param  dgst      pointer to the hash value
 *  \param  dgst_len  length of the hash value
 *  \param  sig       ECDSA_SIG structure
 *  \param  eckey     EC_KEY object containing a public EC key
 *  \return 1 if the signature is valid, 0 if the signature is invalid
 *          and -1 on error
 */
int ECDSA_do_verify(const unsigned char *dgst, int dgst_len,
                    const ECDSA_SIG *sig, EC_KEY *eckey);

/** Precompute parts of the signing operation
 *  \param  eckey  EC_KEY object containing a private EC key
 *  \param  ctx    BN_CTX object (optional)
 *  \param  kinv   BIGNUM pointer for the inverse of k
 *  \param  rp     BIGNUM pointer for x coordinate of k * generator
 *  \return 1 on success and 0 otherwise
 */
int ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv, BIGNUM **rp);

/** Computes ECDSA signature of a given hash value using the supplied
 *  private key (note: sig must point to ECDSA_size(eckey) bytes of memory).
 *  \param  type     this parameter is ignored
 *  \param  dgst     pointer to the hash value to sign
 *  \param  dgstlen  length of the hash value
 *  \param  sig      memory for the DER encoded created signature
 *  \param  siglen   pointer to the length of the returned signature
 *  \param  eckey    EC_KEY object containing a private EC key
 *  \return 1 on success and 0 otherwise
 */
int ECDSA_sign(int type, const unsigned char *dgst, int dgstlen,
               unsigned char *sig, unsigned int *siglen, EC_KEY *eckey);

/** Computes ECDSA signature of a given hash value using the supplied
 *  private key (note: sig must point to ECDSA_size(eckey) bytes of memory).
 *  \param  type     this parameter is ignored
 *  \param  dgst     pointer to the hash value to sign
 *  \param  dgstlen  length of the hash value
 *  \param  sig      buffer to hold the DER encoded signature
 *  \param  siglen   pointer to the length of the returned signature
 *  \param  kinv     BIGNUM with a pre-computed inverse k (optional)
 *  \param  rp       BIGNUM with a pre-computed rp value (optional),
 *                   see ECDSA_sign_setup
 *  \param  eckey    EC_KEY object containing a private EC key
 *  \return 1 on success and 0 otherwise
 */
int ECDSA_sign_ex(int type, const unsigned char *dgst, int dgstlen,
                  unsigned char *sig, unsigned int *siglen,
                  const BIGNUM *kinv, const BIGNUM *rp, EC_KEY *eckey);

/** Verifies that the given signature is valid ECDSA signature
 *  of the supplied hash value using the specified public key.
 *  \param  type     this parameter is ignored
 *  \param  dgst     pointer to the hash value
 *  \param  dgstlen  length of the hash value
 *  \param  sig      pointer to the DER encoded signature
 *  \param  siglen   length of the DER encoded signature
 *  \param  eckey    EC_KEY object containing a public EC key
 *  \return 1 if the signature is valid, 0 if the signature is invalid
 *          and -1 on error
 */
int ECDSA_verify(int type, const unsigned char *dgst, int dgstlen,
                 const unsigned char *sig, int siglen, EC_KEY *eckey);

/** Returns the maximum length of the DER encoded signature
 *  \param  eckey  EC_KEY object
 *  \return numbers of bytes required for the DER encoded signature
 */
int ECDSA_size(const EC_KEY *eckey);

/********************************************************************/
/*  EC_KEY_METHOD constructors, destructors, writers and accessors  */
/********************************************************************/

EC_KEY_METHOD *EC_KEY_METHOD_new(const EC_KEY_METHOD *meth);
void EC_KEY_METHOD_free(EC_KEY_METHOD *meth);
void EC_KEY_METHOD_set_init(EC_KEY_METHOD *meth,
                            int (*init)(EC_KEY *key),
                            void (*finish)(EC_KEY *key),
                            int (*copy)(EC_KEY *dest, const EC_KEY *src),
                            int (*set_group)(EC_KEY *key, const EC_GROUP *grp),
                            int (*set_private)(EC_KEY *key,
                                               const BIGNUM *priv_key),
                            int (*set_public)(EC_KEY *key,
                                              const EC_POINT *pub_key));

void EC_KEY_METHOD_set_keygen(EC_KEY_METHOD *meth,
                              int (*keygen)(EC_KEY *key));

void EC_KEY_METHOD_set_compute_key(EC_KEY_METHOD *meth,
                                   int (*ckey)(unsigned char **psec,
                                               size_t *pseclen,
                                               const EC_POINT *pub_key,
                                               const EC_KEY *ecdh));

void EC_KEY_METHOD_set_sign(EC_KEY_METHOD *meth,
                            int (*sign)(int type, const unsigned char *dgst,
                                        int dlen, unsigned char *sig,
                                        unsigned int *siglen,
                                        const BIGNUM *kinv, const BIGNUM *r,
                                        EC_KEY *eckey),
                            int (*sign_setup)(EC_KEY *eckey, BN_CTX *ctx_in,
                                              BIGNUM **kinvp, BIGNUM **rp),
                            ECDSA_SIG *(*sign_sig)(const unsigned char *dgst,
                                                   int dgst_len,
                                                   const BIGNUM *in_kinv,
                                                   const BIGNUM *in_r,
                                                   EC_KEY *eckey));

void EC_KEY_METHOD_set_verify(EC_KEY_METHOD *meth,
                              int (*verify)(int type, const unsigned
                                            char *dgst, int dgst_len,
                                            const unsigned char *sigbuf,
                                            int sig_len, EC_KEY *eckey),
                              int (*verify_sig)(const unsigned char *dgst,
                                                int dgst_len,
                                                const ECDSA_SIG *sig,
                                                EC_KEY *eckey));

void EC_KEY_METHOD_get_init(const EC_KEY_METHOD *meth,
                            int (**pinit)(EC_KEY *key),
                            void (**pfinish)(EC_KEY *key),
                            int (**pcopy)(EC_KEY *dest, const EC_KEY *src),
                            int (**pset_group)(EC_KEY *key,
                                               const EC_GROUP *grp),
                            int (**pset_private)(EC_KEY *key,
                                                 const BIGNUM *priv_key),
                            int (**pset_public)(EC_KEY *key,
                                                const EC_POINT *pub_key));

void EC_KEY_METHOD_get_keygen(const EC_KEY_METHOD *meth,
                              int (**pkeygen)(EC_KEY *key));

void EC_KEY_METHOD_get_compute_key(const EC_KEY_METHOD *meth,
                                   int (**pck)(unsigned char **psec,
                                               size_t *pseclen,
                                               const EC_POINT *pub_key,
                                               const EC_KEY *ecdh));

void EC_KEY_METHOD_get_sign(const EC_KEY_METHOD *meth,
                            int (**psign)(int type, const unsigned char *dgst,
                                          int dlen, unsigned char *sig,
                                          unsigned int *siglen,
                                          const BIGNUM *kinv, const BIGNUM *r,
                                          EC_KEY *eckey),
                            int (**psign_setup)(EC_KEY *eckey, BN_CTX *ctx_in,
                                                BIGNUM **kinvp, BIGNUM **rp),
                            ECDSA_SIG *(**psign_sig)(const unsigned char *dgst,
                                                     int dgst_len,
                                                     const BIGNUM *in_kinv,
                                                     const BIGNUM *in_r,
                                                     EC_KEY *eckey));

void EC_KEY_METHOD_get_verify(const EC_KEY_METHOD *meth,
                              int (**pverify)(int type, const unsigned
                                              char *dgst, int dgst_len,
                                              const unsigned char *sigbuf,
                                              int sig_len, EC_KEY *eckey),
                              int (**pverify_sig)(const unsigned char *dgst,
                                                  int dgst_len,
                                                  const ECDSA_SIG *sig,
                                                  EC_KEY *eckey));

# define ECParameters_dup(x) ASN1_dup_of(EC_KEY,i2d_ECParameters,d2i_ECParameters,x)

# ifndef __cplusplus
#  if defined(__SUNPRO_C)
#   if __SUNPRO_C >= 0x520
#    pragma error_messages (default,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE)
#   endif
#  endif
# endif

# define EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid) \
        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
                                EVP_PKEY_OP_PARAMGEN|EVP_PKEY_OP_KEYGEN, \
                                EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID, nid, NULL)

# define EVP_PKEY_CTX_set_ec_param_enc(ctx, flag) \
        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
                                EVP_PKEY_OP_PARAMGEN|EVP_PKEY_OP_KEYGEN, \
                                EVP_PKEY_CTRL_EC_PARAM_ENC, flag, NULL)

# define EVP_PKEY_CTX_set_ecdh_cofactor_mode(ctx, flag) \
        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
                                EVP_PKEY_OP_DERIVE, \
                                EVP_PKEY_CTRL_EC_ECDH_COFACTOR, flag, NULL)

# define EVP_PKEY_CTX_get_ecdh_cofactor_mode(ctx) \
        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
                                EVP_PKEY_OP_DERIVE, \
                                EVP_PKEY_CTRL_EC_ECDH_COFACTOR, -2, NULL)

# define EVP_PKEY_CTX_set_ecdh_kdf_type(ctx, kdf) \
        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
                                EVP_PKEY_OP_DERIVE, \
                                EVP_PKEY_CTRL_EC_KDF_TYPE, kdf, NULL)

# define EVP_PKEY_CTX_get_ecdh_kdf_type(ctx) \
        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
                                EVP_PKEY_OP_DERIVE, \
                                EVP_PKEY_CTRL_EC_KDF_TYPE, -2, NULL)

# define EVP_PKEY_CTX_set_ecdh_kdf_md(ctx, md) \
        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
                                EVP_PKEY_OP_DERIVE, \
                                EVP_PKEY_CTRL_EC_KDF_MD, 0, (void *)(md))

# define EVP_PKEY_CTX_get_ecdh_kdf_md(ctx, pmd) \
        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
                                EVP_PKEY_OP_DERIVE, \
                                EVP_PKEY_CTRL_GET_EC_KDF_MD, 0, (void *)(pmd))

# define EVP_PKEY_CTX_set_ecdh_kdf_outlen(ctx, len) \
        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
                                EVP_PKEY_OP_DERIVE, \
                                EVP_PKEY_CTRL_EC_KDF_OUTLEN, len, NULL)

# define EVP_PKEY_CTX_get_ecdh_kdf_outlen(ctx, plen) \
        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
                                EVP_PKEY_OP_DERIVE, \
                                EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN, 0, \
                                (void *)(plen))

# define EVP_PKEY_CTX_set0_ecdh_kdf_ukm(ctx, p, plen) \
        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
                                EVP_PKEY_OP_DERIVE, \
                                EVP_PKEY_CTRL_EC_KDF_UKM, plen, (void *)(p))

# define EVP_PKEY_CTX_get0_ecdh_kdf_ukm(ctx, p) \
        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
                                EVP_PKEY_OP_DERIVE, \
                                EVP_PKEY_CTRL_GET_EC_KDF_UKM, 0, (void *)(p))

/* SM2 will skip the operation check so no need to pass operation here */
# define EVP_PKEY_CTX_set1_id(ctx, id, id_len) \
        EVP_PKEY_CTX_ctrl(ctx, -1, -1, \
                                EVP_PKEY_CTRL_SET1_ID, (int)id_len, (void*)(id))

# define EVP_PKEY_CTX_get1_id(ctx, id) \
        EVP_PKEY_CTX_ctrl(ctx, -1, -1, \
                                EVP_PKEY_CTRL_GET1_ID, 0, (void*)(id))

# define EVP_PKEY_CTX_get1_id_len(ctx, id_len) \
        EVP_PKEY_CTX_ctrl(ctx, -1, -1, \
                                EVP_PKEY_CTRL_GET1_ID_LEN, 0, (void*)(id_len))

# define EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID             (EVP_PKEY_ALG_CTRL + 1)
# define EVP_PKEY_CTRL_EC_PARAM_ENC                      (EVP_PKEY_ALG_CTRL + 2)
# define EVP_PKEY_CTRL_EC_ECDH_COFACTOR                  (EVP_PKEY_ALG_CTRL + 3)
# define EVP_PKEY_CTRL_EC_KDF_TYPE                       (EVP_PKEY_ALG_CTRL + 4)
# define EVP_PKEY_CTRL_EC_KDF_MD                         (EVP_PKEY_ALG_CTRL + 5)
# define EVP_PKEY_CTRL_GET_EC_KDF_MD                     (EVP_PKEY_ALG_CTRL + 6)
# define EVP_PKEY_CTRL_EC_KDF_OUTLEN                     (EVP_PKEY_ALG_CTRL + 7)
# define EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN                 (EVP_PKEY_ALG_CTRL + 8)
# define EVP_PKEY_CTRL_EC_KDF_UKM                        (EVP_PKEY_ALG_CTRL + 9)
# define EVP_PKEY_CTRL_GET_EC_KDF_UKM                    (EVP_PKEY_ALG_CTRL + 10)
# define EVP_PKEY_CTRL_SET1_ID                           (EVP_PKEY_ALG_CTRL + 11)
# define EVP_PKEY_CTRL_GET1_ID                           (EVP_PKEY_ALG_CTRL + 12)
# define EVP_PKEY_CTRL_GET1_ID_LEN                       (EVP_PKEY_ALG_CTRL + 13)
/* KDF types */
# define EVP_PKEY_ECDH_KDF_NONE                          1
# define EVP_PKEY_ECDH_KDF_X9_63                         2
/** The old name for EVP_PKEY_ECDH_KDF_X9_63
 *  The ECDH KDF specification has been mistakingly attributed to ANSI X9.62,
 *  it is actually specified in ANSI X9.63.
 *  This identifier is retained for backwards compatibility
 */
# define EVP_PKEY_ECDH_KDF_X9_62   EVP_PKEY_ECDH_KDF_X9_63


#  ifdef  __cplusplus
}
#  endif
# endif
#endif

NineSec Team - 2022