From f02dd75fc3fda9d01fe8e0d5544f76e700aa036b Mon Sep 17 00:00:00 2001 From: Afr Schoe <58883403+q9f@users.noreply.github.com> Date: Wed, 6 Apr 2022 12:25:41 +0200 Subject: [PATCH] fix typos --- .github/coverage/index.js | 4 +- .github/coverage/run_coverage | 2 +- .../amber.png | Bin .../bcov.css | 0 .../cobertura.xml | 33 +++---- .../context.cr.d435d9a9.html | 0 .../context.cr.d435d9a9.js | 2 +- .../cov.xml | 33 +++---- .../coverage.db | Bin 407568 -> 400400 bytes .../coverage.json | 10 +- .../curve.cr.f05213da.html | 0 .../curve.cr.f05213da.js | 4 +- .../data/amber.png | Bin .../data/bcov.css | 0 .../data/glass.png | Bin .../data/js/handlebars.js | 0 .../data/js/jquery.min.js | 0 .../data/js/jquery.tablesorter.widgets.min.js | 0 .../data/js/kcov.js | 0 .../data/js/tablesorter.min.js | 0 .../data/tablesorter-theme.css | 0 .../glass.png | Bin .../index.html | 0 .../index.js | 4 +- .../key.cr.80fcd549.html | 0 .../key.cr.80fcd549.js | 10 +- .../metadata/10ecf873 | Bin .../metadata/25065a1d | Bin .../metadata/30592eb4 | Bin .../run_coverage.78460cc2/metadata/6faa13b0 | Bin 0 -> 1042 bytes .../metadata/80fcd549 | Bin .../metadata/d435d9a9 | Bin .../metadata/e684f666 | Bin .../metadata/f05213da | Bin .../num.cr.6faa13b0.html | 0 .../num.cr.6faa13b0.js | 89 ++++++++---------- .../point.cr.10ecf873.html | 0 .../point.cr.10ecf873.js | 46 ++++----- .../secp256k1.cr.30592eb4.html | 0 .../secp256k1.cr.30592eb4.js | 2 +- .../signature.cr.25065a1d.html | 0 .../signature.cr.25065a1d.js | 2 +- .../sonarqube.xml | 23 ++--- .../summary.db | Bin 276 -> 276 bytes .../util.cr.e684f666.html | 0 .../util.cr.e684f666.js | 22 ++--- .../run_coverage.e4d6ba08/metadata/6faa13b0 | Bin 1182 -> 0 bytes docs/index.json | 2 +- docs/search-index.js | 2 +- spec/secp256k1/key_spec.cr | 2 +- src/secp256k1/num.cr | 9 +- 51 files changed, 133 insertions(+), 168 deletions(-) rename .github/coverage/{run_coverage.e4d6ba08 => run_coverage.78460cc2}/amber.png (100%) rename .github/coverage/{run_coverage.e4d6ba08 => run_coverage.78460cc2}/bcov.css (100%) rename .github/coverage/{run_coverage.e4d6ba08 => run_coverage.78460cc2}/cobertura.xml (91%) rename .github/coverage/{run_coverage.e4d6ba08 => run_coverage.78460cc2}/context.cr.d435d9a9.html (100%) rename .github/coverage/{run_coverage.e4d6ba08 => run_coverage.78460cc2}/context.cr.d435d9a9.js (99%) rename .github/coverage/{run_coverage.e4d6ba08 => run_coverage.78460cc2}/cov.xml (91%) rename .github/coverage/{run_coverage.e4d6ba08 => run_coverage.78460cc2}/coverage.db (95%) rename .github/coverage/{run_coverage.e4d6ba08 => run_coverage.78460cc2}/coverage.json (86%) rename .github/coverage/{run_coverage.e4d6ba08 => run_coverage.78460cc2}/curve.cr.f05213da.html (100%) rename .github/coverage/{run_coverage.e4d6ba08 => run_coverage.78460cc2}/curve.cr.f05213da.js (99%) rename .github/coverage/{run_coverage.e4d6ba08 => run_coverage.78460cc2}/data/amber.png (100%) rename .github/coverage/{run_coverage.e4d6ba08 => run_coverage.78460cc2}/data/bcov.css (100%) rename .github/coverage/{run_coverage.e4d6ba08 => run_coverage.78460cc2}/data/glass.png (100%) rename .github/coverage/{run_coverage.e4d6ba08 => run_coverage.78460cc2}/data/js/handlebars.js (100%) rename .github/coverage/{run_coverage.e4d6ba08 => run_coverage.78460cc2}/data/js/jquery.min.js (100%) rename .github/coverage/{run_coverage.e4d6ba08 => run_coverage.78460cc2}/data/js/jquery.tablesorter.widgets.min.js (100%) rename .github/coverage/{run_coverage.e4d6ba08 => run_coverage.78460cc2}/data/js/kcov.js (100%) rename .github/coverage/{run_coverage.e4d6ba08 => run_coverage.78460cc2}/data/js/tablesorter.min.js (100%) rename .github/coverage/{run_coverage.e4d6ba08 => run_coverage.78460cc2}/data/tablesorter-theme.css (100%) rename .github/coverage/{run_coverage.e4d6ba08 => run_coverage.78460cc2}/glass.png (100%) rename .github/coverage/{run_coverage.e4d6ba08 => run_coverage.78460cc2}/index.html (100%) rename .github/coverage/{run_coverage.e4d6ba08 => run_coverage.78460cc2}/index.js (93%) rename .github/coverage/{run_coverage.e4d6ba08 => run_coverage.78460cc2}/key.cr.80fcd549.html (100%) rename .github/coverage/{run_coverage.e4d6ba08 => run_coverage.78460cc2}/key.cr.80fcd549.js (97%) rename .github/coverage/{run_coverage.e4d6ba08 => run_coverage.78460cc2}/metadata/10ecf873 (100%) rename .github/coverage/{run_coverage.e4d6ba08 => run_coverage.78460cc2}/metadata/25065a1d (100%) rename .github/coverage/{run_coverage.e4d6ba08 => run_coverage.78460cc2}/metadata/30592eb4 (100%) create mode 100644 .github/coverage/run_coverage.78460cc2/metadata/6faa13b0 rename .github/coverage/{run_coverage.e4d6ba08 => run_coverage.78460cc2}/metadata/80fcd549 (100%) rename .github/coverage/{run_coverage.e4d6ba08 => run_coverage.78460cc2}/metadata/d435d9a9 (100%) rename .github/coverage/{run_coverage.e4d6ba08 => run_coverage.78460cc2}/metadata/e684f666 (100%) rename .github/coverage/{run_coverage.e4d6ba08 => run_coverage.78460cc2}/metadata/f05213da (100%) rename .github/coverage/{run_coverage.e4d6ba08 => run_coverage.78460cc2}/num.cr.6faa13b0.html (100%) rename .github/coverage/{run_coverage.e4d6ba08 => run_coverage.78460cc2}/num.cr.6faa13b0.js (80%) rename .github/coverage/{run_coverage.e4d6ba08 => run_coverage.78460cc2}/point.cr.10ecf873.html (100%) rename .github/coverage/{run_coverage.e4d6ba08 => run_coverage.78460cc2}/point.cr.10ecf873.js (91%) rename .github/coverage/{run_coverage.e4d6ba08 => run_coverage.78460cc2}/secp256k1.cr.30592eb4.html (100%) rename .github/coverage/{run_coverage.e4d6ba08 => run_coverage.78460cc2}/secp256k1.cr.30592eb4.js (98%) rename .github/coverage/{run_coverage.e4d6ba08 => run_coverage.78460cc2}/signature.cr.25065a1d.html (100%) rename .github/coverage/{run_coverage.e4d6ba08 => run_coverage.78460cc2}/signature.cr.25065a1d.js (99%) rename .github/coverage/{run_coverage.e4d6ba08 => run_coverage.78460cc2}/sonarqube.xml (94%) rename .github/coverage/{run_coverage.e4d6ba08 => run_coverage.78460cc2}/summary.db (76%) rename .github/coverage/{run_coverage.e4d6ba08 => run_coverage.78460cc2}/util.cr.e684f666.html (100%) rename .github/coverage/{run_coverage.e4d6ba08 => run_coverage.78460cc2}/util.cr.e684f666.js (96%) delete mode 100644 .github/coverage/run_coverage.e4d6ba08/metadata/6faa13b0 diff --git a/.github/coverage/index.js b/.github/coverage/index.js index 0efbbf1..a636ad7 100644 --- a/.github/coverage/index.js +++ b/.github/coverage/index.js @@ -1,5 +1,5 @@ var data = {files:[ -{"link":"run_coverage.e4d6ba08/index.html","title":"run_coverage","summary_name":"run_coverage","covered_class":"lineCov","covered":"97.5","covered_lines":"237","uncovered_lines":"6","total_lines" : "243"}, +{"link":"run_coverage.78460cc2/index.html","title":"run_coverage","summary_name":"run_coverage","covered_class":"lineCov","covered":"97.9","covered_lines":"231","uncovered_lines":"5","total_lines" : "236"}, ], merged_files:[]}; var percent_low = 25;var percent_high = 75; -var header = { "command" : "run_coverage", "date" : "2022-04-06 11:52:18", "instrumented" : 243, "covered" : 237,}; +var header = { "command" : "run_coverage", "date" : "2022-04-06 12:16:54", "instrumented" : 236, "covered" : 231,}; diff --git a/.github/coverage/run_coverage b/.github/coverage/run_coverage index 06bd53e..8b6a729 120000 --- a/.github/coverage/run_coverage +++ b/.github/coverage/run_coverage @@ -1 +1 @@ -.github/coverage//run_coverage.e4d6ba08/ \ No newline at end of file +.github/coverage//run_coverage.78460cc2/ \ No newline at end of file diff --git a/.github/coverage/run_coverage.e4d6ba08/amber.png b/.github/coverage/run_coverage.78460cc2/amber.png similarity index 100% rename from .github/coverage/run_coverage.e4d6ba08/amber.png rename to .github/coverage/run_coverage.78460cc2/amber.png diff --git a/.github/coverage/run_coverage.e4d6ba08/bcov.css b/.github/coverage/run_coverage.78460cc2/bcov.css similarity index 100% rename from .github/coverage/run_coverage.e4d6ba08/bcov.css rename to .github/coverage/run_coverage.78460cc2/bcov.css diff --git a/.github/coverage/run_coverage.e4d6ba08/cobertura.xml b/.github/coverage/run_coverage.78460cc2/cobertura.xml similarity index 91% rename from .github/coverage/run_coverage.e4d6ba08/cobertura.xml rename to .github/coverage/run_coverage.78460cc2/cobertura.xml index 5ab0a5f..1626ae0 100644 --- a/.github/coverage/run_coverage.e4d6ba08/cobertura.xml +++ b/.github/coverage/run_coverage.78460cc2/cobertura.xml @@ -1,11 +1,11 @@ - + /home/user/.opt/q9f/secp256k1.cr/src/secp256k1/ - + @@ -205,7 +205,7 @@ - + @@ -242,25 +242,18 @@ - - - - - - + - - - - - - - + + + + + + + + + - - - - diff --git a/.github/coverage/run_coverage.e4d6ba08/context.cr.d435d9a9.html b/.github/coverage/run_coverage.78460cc2/context.cr.d435d9a9.html similarity index 100% rename from .github/coverage/run_coverage.e4d6ba08/context.cr.d435d9a9.html rename to .github/coverage/run_coverage.78460cc2/context.cr.d435d9a9.html diff --git a/.github/coverage/run_coverage.e4d6ba08/context.cr.d435d9a9.js b/.github/coverage/run_coverage.78460cc2/context.cr.d435d9a9.js similarity index 99% rename from .github/coverage/run_coverage.e4d6ba08/context.cr.d435d9a9.js rename to .github/coverage/run_coverage.78460cc2/context.cr.d435d9a9.js index aeb124f..5c334d7 100644 --- a/.github/coverage/run_coverage.e4d6ba08/context.cr.d435d9a9.js +++ b/.github/coverage/run_coverage.78460cc2/context.cr.d435d9a9.js @@ -105,5 +105,5 @@ var data = {lines:[ {"lineNum":" 104","line":"end"}, ]}; var percent_low = 25;var percent_high = 75; -var header = { "command" : "run_coverage", "date" : "2022-04-06 11:52:18", "instrumented" : 28, "covered" : 26,}; +var header = { "command" : "run_coverage", "date" : "2022-04-06 12:16:54", "instrumented" : 28, "covered" : 26,}; var merged_data = []; diff --git a/.github/coverage/run_coverage.e4d6ba08/cov.xml b/.github/coverage/run_coverage.78460cc2/cov.xml similarity index 91% rename from .github/coverage/run_coverage.e4d6ba08/cov.xml rename to .github/coverage/run_coverage.78460cc2/cov.xml index 5ab0a5f..1626ae0 100644 --- a/.github/coverage/run_coverage.e4d6ba08/cov.xml +++ b/.github/coverage/run_coverage.78460cc2/cov.xml @@ -1,11 +1,11 @@ - + /home/user/.opt/q9f/secp256k1.cr/src/secp256k1/ - + @@ -205,7 +205,7 @@ - + @@ -242,25 +242,18 @@ - - - - - - + - - - - - - - + + + + + + + + + - - - - diff --git a/.github/coverage/run_coverage.e4d6ba08/coverage.db b/.github/coverage/run_coverage.78460cc2/coverage.db similarity index 95% rename from .github/coverage/run_coverage.e4d6ba08/coverage.db rename to .github/coverage/run_coverage.78460cc2/coverage.db index 68ef4e28fb712ff18ed53695337f1070d3bbaac3..73a67002e0af4bdfb1516bdad85fee7a0dfa2400 100644 GIT binary patch literal 400400 zcmeI&d$66=S-|0wOTpBHoM22_!zDm-4;%Kr4W@uW2+#EglZ|}l6_hfsx~2| z7h7qN6r`eqBv`dnvAL1Up-H6JPL-zCfx(WH4vy9tl{ijEog~D4I`49_-&yNF|9s9& z=g|DlyVkd#{e63X`y{umyYue8zP?ks|LeQ{;4KgJ^{rmLdT_(-C{RQHe08~*c? zzD7j9BlYf||LCjq&8d$}{c!4|Qhz1&(Y<}3FZDO|_7#sue|!9S`4-1F(4Trf{_WAH zmBHTi2hNW^qtUO8esQDUlzQ5KU_HMAlQkqZa z@BHsZAASuw`K!Cn@axlsW21liS_LrH$|V>*#Fkl^Zfki!_V=_U-9^-|93RO|WB&a5{F(1hJHIu%Q}he!`=3?z zFFo&Hp8wL*{xi$|rKkPRD$oDi#{PdE$5(pVf9Cqs)Bdw2r=Iu!o9OfE`%fvprKkO8 zElu-j|Jh$jJ?($?&qkkL-+$J=)YJZFe?0nyjrk*~=lODc7uDxym)FPA^ZYBZ{({E* z)v2fXGZ#l+Sf8Krlc}fqDW6R}`Onyzdh(yWG4=HNJZD7e>GgR^d3{-2KmIwV$9(DO z_|KUV{kr=6Ig3)y^J`O2kN=$eQ%{foobvv1ePjP`#r%63{Xe5OKA)cZmgqlMpFj8F z=tdY@YQFE;wivHnf8_qX=N{KiHvzV|iy-^To=dVkvs(LY}AKlMcP`y2gm^iMSUe@8FBzbHS} zeIAGJ|0cW|{fQFdd-T&!Nj*LPb2g`*p8q+2lzMvp=Nyc_wXy$I(YH1Fq15y7{cGy! z_)ahPhfg-v|47V#vEI+0nR?p)^hcuqaby1S)YJUL<|^m6}G9!B@)hOfUdJEAx4f5yBPy>Wl@=26iX zm4)MbtpDZ(d*Y& z=h)%s_51VAv6oX%$9H^Q>go87UlzT7f8RNNd-VGKedqYS(d+m3o#Vyl_PYP^M`OP9 zeEdgJPsjhpDXI5fKb>Un-f^!neAc1~U~ny}pC}UyELTzna&7F?#v^XX@i$jed0r@jZ@j{J*50 zk8dFLe0*0#zox!^|4&C>)#yi}*WbSe`~M^Le0)EQUVncZoX{7&@%x(zV^dG-Pw0=n zwtoB*icjO;Z%kMj^QGtYi{A$u>t7r5jn}UU?@m3hzdCyT_cxuPdEdMG;-Bd5UH|)) z&d`F?d)My_ZBD)S{OAll7QOuaN_m*wb-LF_XXs1O&o3dqm;P+@`t{X$_5-Qsot>9NzoLG8J3kt|{`sb}^V8AmpKm%lzY)Fu`KGhCoS%*R)4i)= zzVzg?_dx2&XYXsNC!f7XqSt@F-Pt!fdj0p?oqgr}ssDbvv+tcTe?#4O-@52GHhOt{ zw>A3rW4`p{vwv;s$!GulsVATPe-Qmc_5Jsk^S^vPC_mOcj^XQn|FM{F+}|JE9DQRM zjPEgj@WIs6<2(5I==as<_iTv%K%+m9dRl+a)2S!FJ%>_HetVve{<+5f-;BPw(f=oU z`S(ZV$HM2pK=kb;#P`yFCiV3A4ix_~pB~?VCt`j_WBsA%I~)C_=)3BD_u=UK8~wYf z_a6V6gXR1ms?R@jLClxlJKuTcpQ1lopWo9T{rN^OufKoQ=qqCW>-D~CO7w3v`n=TB z@$cFa{cvM`d-QKt`4ZH2Tui^YJf_UcZ07 z>E>ttdh4p;&%QIN>#sSuIrZN4*BpE>^-T4C z4&9Y{UVlsKz3Z)6gby# delta 4409 zcmYM&ZE#f883*v(O$eNgKxoLGP`0@X2@qcL##I@9Mo`Ja;yo8kBT zpL6cHXV2bj*wb6K=W1E(du?ks=H=xT@++@?>*c<@yq1=h_3_x^bp<=PR6z+(s~V?( z)$EjJ?QzO@+B=Z!_EpA~QX#DpK&8xd-pS0g9vUy%6{w2RJgyjO5|ujz`C7%Tl8H!o zUf>k4b~~k6C!8{@W@xs|X_q;h%$#k==1BHOD4r_N$}W0wG8PHX&qK60#iQNYr3@@(^+AdmXmE>_# z?e(^sotnDOWdZA1Xork@3wpv_VcJCKNzs02C#45z^^#M9bqM;QWIuI^6>2rXDbA{Z zc9}V6*nQbWrqfJS(#+(a}ypBs^gtOS7Ub%S1vG5>!@H9-6R|8j8xp(c6)YH%pCfg(gsj zuW;GPT<MUv#&FHF$R%H4=g(gY1!isXkwQ7JSOLo{wvX#&j$?OhH zk?a{{)u~}xjkBN_tI#PkRI8*@jT#bygw^c*&VcJVlcId!u)k^|VJ!q8-BH`F@sNT#!xx*>W*-g+?$xb+# z%+4}RGJ71RnKKtVfX?ZZDb`+?vcrA#AJk@;{@B}Alq=S1k(1f4Hm7u{_U2K0v9C_s zT9S{=m=)Ap?0dhbEGIc6^1vQ*&574BHs+LIea$IgC7>mg8KKov&{89>hk8f&>LO}) zNXP#mdA3(HLapX*D!QQMBD>Z*jVi|?`z9+?d6v4rH1M9TNR{y85DnjEc)zCWoPUB+ zf^ytok6nkz?sSLQX>C7T9p;0l?FX;Jyt8^HX8D0xhh7D37CiwyBI<)4rNqdA{SS=1 z47H9NSkYsqe^d(nos{AJ-OyHfFx(Ao6YYT>7xhBhDbDX~ni@)d^(JZu&HYq2J0)26 zI0dXN&>^#ik|EGx(PK_#mZMHQONo6HyeOSBkiBG7{jn2|D_I5|F7mEgcEh+4t@!pXqSvTx7@0wM*?T z9;1M-_JPaHID6;E%(!qdT^ZlQkL9VUQCdy5Fq;`(22C^324K3uAz%i>dxNf*`RX4i zebrpQXe-npIu12b!2PdL`zT+1fLaq}zO2;^&}`92=tfc8DbAhM&|Hc|wVG;W7Cfv1 znkU))R+24;=F6Nbp_`<0sg-oLIVE^batb2hp$|g~WtJn*&7ur+i_B^7=oNv-9+x`1Sj^!*81OKD%L`Az|A5cGg#Yn)8BA6h5bY3M;wCA8kiyGrf8udbuE zf#UqN2yK&DR$7tSmCMi$vs(U@mmR}jZCx!Fjf6i> zfKSUIu$#J9v;$d}CBpy>oXUg;`3J{s&vY6 z7Fe0*+lXxte-q)X3#yZoorZ1|{m9A8l4m8e41#WxS%yN3L?@sY(aTOe3qOOpEBTL4 z)b27J-dmLA+IiFx=68&{+G>%9Y&8WDKBmyUk`+UnMI)R{XDRdu<;Llri{qXz2%l+w z|JJ4w-l;A8>5YWX-0ql(MnY#=dU_|_<*64@eU;LawR#(RO@^HQ2Kcjn9t3;)c>(-+ zKR*J0(a&q(DdCxs;4k~rHQ=xM(@~DRw(!aG;2V;jyfnZmzSk$k-WnA9D96RKscPT* zEoCNYRfXW3kvEsxt9=zi?E(edcY)IU^CJISs~#j-O4Mmp551eJ@x6CR7SoB^rT)cq zf$veShW|g|oukp6yvI#O-g@fhaXIScpMR!ojjujJexr2%6`CWu3f(69%qh+DegQ2? g#!5T))^6Wh>+vhZuY7(LoZMSGsN-+1)W=5uA5D$+EdT%j diff --git a/.github/coverage/run_coverage.e4d6ba08/coverage.json b/.github/coverage/run_coverage.78460cc2/coverage.json similarity index 86% rename from .github/coverage/run_coverage.e4d6ba08/coverage.json rename to .github/coverage/run_coverage.78460cc2/coverage.json index 06df28d..756fc4a 100644 --- a/.github/coverage/run_coverage.e4d6ba08/coverage.json +++ b/.github/coverage/run_coverage.78460cc2/coverage.json @@ -5,15 +5,15 @@ {"file": "/home/user/.opt/q9f/secp256k1.cr/src/secp256k1/context.cr", "percent_covered": "92.86", "covered_lines": "26", "total_lines": "28"}, {"file": "/home/user/.opt/q9f/secp256k1.cr/src/secp256k1/point.cr", "percent_covered": "100.00", "covered_lines": "36", "total_lines": "36"}, {"file": "/home/user/.opt/q9f/secp256k1.cr/src/secp256k1/key.cr", "percent_covered": "100.00", "covered_lines": "14", "total_lines": "14"}, - {"file": "/home/user/.opt/q9f/secp256k1.cr/src/secp256k1/num.cr", "percent_covered": "98.15", "covered_lines": "53", "total_lines": "54"}, + {"file": "/home/user/.opt/q9f/secp256k1.cr/src/secp256k1/num.cr", "percent_covered": "100.00", "covered_lines": "47", "total_lines": "47"}, {"file": "/home/user/.opt/q9f/secp256k1.cr/src/secp256k1/signature.cr", "percent_covered": "100.00", "covered_lines": "6", "total_lines": "6"}, {"file": "/home/user/.opt/q9f/secp256k1.cr/src/secp256k1.cr", "percent_covered": "100.00", "covered_lines": "5", "total_lines": "5"} ], - "percent_covered": "97.53", - "covered_lines": 237, - "total_lines": 243, + "percent_covered": "97.88", + "covered_lines": 231, + "total_lines": 236, "percent_low": 25, "percent_high": 75, "command": "run_coverage", - "date": "2022-04-06 11:52:18" + "date": "2022-04-06 12:16:54" } diff --git a/.github/coverage/run_coverage.e4d6ba08/curve.cr.f05213da.html b/.github/coverage/run_coverage.78460cc2/curve.cr.f05213da.html similarity index 100% rename from .github/coverage/run_coverage.e4d6ba08/curve.cr.f05213da.html rename to .github/coverage/run_coverage.78460cc2/curve.cr.f05213da.html diff --git a/.github/coverage/run_coverage.e4d6ba08/curve.cr.f05213da.js b/.github/coverage/run_coverage.78460cc2/curve.cr.f05213da.js similarity index 99% rename from .github/coverage/run_coverage.e4d6ba08/curve.cr.f05213da.js rename to .github/coverage/run_coverage.78460cc2/curve.cr.f05213da.js index cc31602..10a7c4f 100644 --- a/.github/coverage/run_coverage.e4d6ba08/curve.cr.f05213da.js +++ b/.github/coverage/run_coverage.78460cc2/curve.cr.f05213da.js @@ -163,7 +163,7 @@ var data = {lines:[ {"lineNum":" 162","line":" def mul(p : Point, s : Num | BigInt) : Point","class":"lineCov","hits":"4","order":"37","possible_hits":"4",}, {"lineNum":" 163","line":" s = s.to_big if s.is_a? Num","class":"lineCov","hits":"1","order":"136","possible_hits":"1",}, {"lineNum":" 164","line":" if s === 0 || s >= N.to_big","class":"linePartCov","hits":"3","order":"38","possible_hits":"4",}, -{"lineNum":" 165","line":" raise \"Invalid scalar: outside of Secp256k1 field dimension.\"","class":"linePartCov","hits":"1","order":"205","possible_hits":"2",}, +{"lineNum":" 165","line":" raise \"Invalid scalar: outside of Secp256k1 field dimension.\"","class":"linePartCov","hits":"1","order":"199","possible_hits":"2",}, {"lineNum":" 166","line":" end"}, {"lineNum":" 167","line":" s_bin = s.to_s 2","class":"lineCov","hits":"2","order":"39","possible_hits":"2",}, {"lineNum":" 168","line":" q = p","class":"lineCov","hits":"2","order":"40","possible_hits":"2",}, @@ -179,5 +179,5 @@ var data = {lines:[ {"lineNum":" 178","line":"end"}, ]}; var percent_low = 25;var percent_high = 75; -var header = { "command" : "run_coverage", "date" : "2022-04-06 11:52:18", "instrumented" : 56, "covered" : 56,}; +var header = { "command" : "run_coverage", "date" : "2022-04-06 12:16:54", "instrumented" : 56, "covered" : 56,}; var merged_data = []; diff --git a/.github/coverage/run_coverage.e4d6ba08/data/amber.png b/.github/coverage/run_coverage.78460cc2/data/amber.png similarity index 100% rename from .github/coverage/run_coverage.e4d6ba08/data/amber.png rename to .github/coverage/run_coverage.78460cc2/data/amber.png diff --git a/.github/coverage/run_coverage.e4d6ba08/data/bcov.css b/.github/coverage/run_coverage.78460cc2/data/bcov.css similarity index 100% rename from .github/coverage/run_coverage.e4d6ba08/data/bcov.css rename to .github/coverage/run_coverage.78460cc2/data/bcov.css diff --git a/.github/coverage/run_coverage.e4d6ba08/data/glass.png b/.github/coverage/run_coverage.78460cc2/data/glass.png similarity index 100% rename from .github/coverage/run_coverage.e4d6ba08/data/glass.png rename to .github/coverage/run_coverage.78460cc2/data/glass.png diff --git a/.github/coverage/run_coverage.e4d6ba08/data/js/handlebars.js b/.github/coverage/run_coverage.78460cc2/data/js/handlebars.js similarity index 100% rename from .github/coverage/run_coverage.e4d6ba08/data/js/handlebars.js rename to .github/coverage/run_coverage.78460cc2/data/js/handlebars.js diff --git a/.github/coverage/run_coverage.e4d6ba08/data/js/jquery.min.js b/.github/coverage/run_coverage.78460cc2/data/js/jquery.min.js similarity index 100% rename from .github/coverage/run_coverage.e4d6ba08/data/js/jquery.min.js rename to .github/coverage/run_coverage.78460cc2/data/js/jquery.min.js diff --git a/.github/coverage/run_coverage.e4d6ba08/data/js/jquery.tablesorter.widgets.min.js b/.github/coverage/run_coverage.78460cc2/data/js/jquery.tablesorter.widgets.min.js similarity index 100% rename from .github/coverage/run_coverage.e4d6ba08/data/js/jquery.tablesorter.widgets.min.js rename to .github/coverage/run_coverage.78460cc2/data/js/jquery.tablesorter.widgets.min.js diff --git a/.github/coverage/run_coverage.e4d6ba08/data/js/kcov.js b/.github/coverage/run_coverage.78460cc2/data/js/kcov.js similarity index 100% rename from .github/coverage/run_coverage.e4d6ba08/data/js/kcov.js rename to .github/coverage/run_coverage.78460cc2/data/js/kcov.js diff --git a/.github/coverage/run_coverage.e4d6ba08/data/js/tablesorter.min.js b/.github/coverage/run_coverage.78460cc2/data/js/tablesorter.min.js similarity index 100% rename from .github/coverage/run_coverage.e4d6ba08/data/js/tablesorter.min.js rename to .github/coverage/run_coverage.78460cc2/data/js/tablesorter.min.js diff --git a/.github/coverage/run_coverage.e4d6ba08/data/tablesorter-theme.css b/.github/coverage/run_coverage.78460cc2/data/tablesorter-theme.css similarity index 100% rename from .github/coverage/run_coverage.e4d6ba08/data/tablesorter-theme.css rename to .github/coverage/run_coverage.78460cc2/data/tablesorter-theme.css diff --git a/.github/coverage/run_coverage.e4d6ba08/glass.png b/.github/coverage/run_coverage.78460cc2/glass.png similarity index 100% rename from .github/coverage/run_coverage.e4d6ba08/glass.png rename to .github/coverage/run_coverage.78460cc2/glass.png diff --git a/.github/coverage/run_coverage.e4d6ba08/index.html b/.github/coverage/run_coverage.78460cc2/index.html similarity index 100% rename from .github/coverage/run_coverage.e4d6ba08/index.html rename to .github/coverage/run_coverage.78460cc2/index.html diff --git a/.github/coverage/run_coverage.e4d6ba08/index.js b/.github/coverage/run_coverage.78460cc2/index.js similarity index 93% rename from .github/coverage/run_coverage.e4d6ba08/index.js rename to .github/coverage/run_coverage.78460cc2/index.js index ac177f0..9fda395 100644 --- a/.github/coverage/run_coverage.e4d6ba08/index.js +++ b/.github/coverage/run_coverage.78460cc2/index.js @@ -4,10 +4,10 @@ var data = {files:[ {"link":"context.cr.d435d9a9.html","title":"context.cr","summary_name":"[...]/src/secp256k1/context.cr","covered_class":"lineCov","covered":"92.9","covered_lines":"26","uncovered_lines":"2","total_lines" : "28"}, {"link":"point.cr.10ecf873.html","title":"point.cr","summary_name":"[...]/src/secp256k1/point.cr","covered_class":"lineCov","covered":"100.0","covered_lines":"36","uncovered_lines":"0","total_lines" : "36"}, {"link":"key.cr.80fcd549.html","title":"key.cr","summary_name":"[...]/src/secp256k1/key.cr","covered_class":"lineCov","covered":"100.0","covered_lines":"14","uncovered_lines":"0","total_lines" : "14"}, -{"link":"num.cr.6faa13b0.html","title":"num.cr","summary_name":"[...]/src/secp256k1/num.cr","covered_class":"lineCov","covered":"98.1","covered_lines":"53","uncovered_lines":"1","total_lines" : "54"}, +{"link":"num.cr.6faa13b0.html","title":"num.cr","summary_name":"[...]/src/secp256k1/num.cr","covered_class":"lineCov","covered":"100.0","covered_lines":"47","uncovered_lines":"0","total_lines" : "47"}, {"link":"signature.cr.25065a1d.html","title":"signature.cr","summary_name":"[...]/src/secp256k1/signature.cr","covered_class":"lineCov","covered":"100.0","covered_lines":"6","uncovered_lines":"0","total_lines" : "6"}, {"link":"secp256k1.cr.30592eb4.html","title":"secp256k1.cr","summary_name":"[...]/src/secp256k1.cr","covered_class":"lineCov","covered":"100.0","covered_lines":"5","uncovered_lines":"0","total_lines" : "5"}, ]}; var percent_low = 25;var percent_high = 75; -var header = { "command" : "run_coverage", "date" : "2022-04-06 11:52:18", "instrumented" : 243, "covered" : 237,}; +var header = { "command" : "run_coverage", "date" : "2022-04-06 12:16:54", "instrumented" : 236, "covered" : 231,}; var merged_data = []; diff --git a/.github/coverage/run_coverage.e4d6ba08/key.cr.80fcd549.html b/.github/coverage/run_coverage.78460cc2/key.cr.80fcd549.html similarity index 100% rename from .github/coverage/run_coverage.e4d6ba08/key.cr.80fcd549.html rename to .github/coverage/run_coverage.78460cc2/key.cr.80fcd549.html diff --git a/.github/coverage/run_coverage.e4d6ba08/key.cr.80fcd549.js b/.github/coverage/run_coverage.78460cc2/key.cr.80fcd549.js similarity index 97% rename from .github/coverage/run_coverage.e4d6ba08/key.cr.80fcd549.js rename to .github/coverage/run_coverage.78460cc2/key.cr.80fcd549.js index 744bf10..b6c4751 100644 --- a/.github/coverage/run_coverage.e4d6ba08/key.cr.80fcd549.js +++ b/.github/coverage/run_coverage.78460cc2/key.cr.80fcd549.js @@ -103,8 +103,8 @@ var data = {lines:[ {"lineNum":" 102","line":" # Key.new(Num.new \"3ccf84820c20d5e8c536ba84c52ba410375b29b1812b5f7e722445c969a0fb30\").public_hex"}, {"lineNum":" 103","line":" # # => \"04cd4a8712ee6efc15b5abe37c0dbfa979d89c427d3fe24b076008decefe94dba281363d298e4a40ebcb13f1afa85a0b94b967f243ee59a59010cb5deaf0d7b66c\""}, {"lineNum":" 104","line":" # ```"}, -{"lineNum":" 105","line":" def public_hex : String","class":"lineCov","hits":"2","order":"188","possible_hits":"2",}, -{"lineNum":" 106","line":" @public_key.uncompressed","class":"lineCov","hits":"1","order":"189","possible_hits":"1",}, +{"lineNum":" 105","line":" def public_hex : String","class":"lineCov","hits":"2","order":"186","possible_hits":"2",}, +{"lineNum":" 106","line":" @public_key.uncompressed","class":"lineCov","hits":"1","order":"187","possible_hits":"1",}, {"lineNum":" 107","line":" end"}, {"lineNum":" 108","line":""}, {"lineNum":" 109","line":" # Returns the public key as compressed, hexadecimal string literal."}, @@ -123,8 +123,8 @@ var data = {lines:[ {"lineNum":" 122","line":" # Key.new(Num.new \"3ccf84820c20d5e8c536ba84c52ba410375b29b1812b5f7e722445c969a0fb30\").public_bytes"}, {"lineNum":" 123","line":" # # => Bytes[4, 205, 74, 135, 18, 238, 110, 252, 21, 181, 171, 227, 124, 13, 191, 169, 121, 216, 156, 66, 125, 63, 226, 75, 7, 96, 8, 222, 206, 254, 148, 219, 162, 129, 54, 61, 41, 142, 74, 64, 235, 203, 19, 241, 175, 168, 90, 11, 148, 185, 103, 242, 67, 238, 89, 165, 144, 16, 203, 93, 234, 240, 215, 182, 108]"}, {"lineNum":" 124","line":" # ```"}, -{"lineNum":" 125","line":" def public_bytes : Bytes","class":"lineCov","hits":"2","order":"190","possible_hits":"2",}, -{"lineNum":" 126","line":" Num.new(@public_key.uncompressed).to_bytes","class":"lineCov","hits":"1","order":"191","possible_hits":"1",}, +{"lineNum":" 125","line":" def public_bytes : Bytes","class":"lineCov","hits":"2","order":"188","possible_hits":"2",}, +{"lineNum":" 126","line":" Num.new(@public_key.uncompressed).to_bytes","class":"lineCov","hits":"1","order":"189","possible_hits":"1",}, {"lineNum":" 127","line":" end"}, {"lineNum":" 128","line":""}, {"lineNum":" 129","line":" # Returns the public key as compressed, binary byte slice."}, @@ -139,5 +139,5 @@ var data = {lines:[ {"lineNum":" 138","line":"end"}, ]}; var percent_low = 25;var percent_high = 75; -var header = { "command" : "run_coverage", "date" : "2022-04-06 11:52:18", "instrumented" : 14, "covered" : 14,}; +var header = { "command" : "run_coverage", "date" : "2022-04-06 12:16:54", "instrumented" : 14, "covered" : 14,}; var merged_data = []; diff --git a/.github/coverage/run_coverage.e4d6ba08/metadata/10ecf873 b/.github/coverage/run_coverage.78460cc2/metadata/10ecf873 similarity index 100% rename from .github/coverage/run_coverage.e4d6ba08/metadata/10ecf873 rename to .github/coverage/run_coverage.78460cc2/metadata/10ecf873 diff --git a/.github/coverage/run_coverage.e4d6ba08/metadata/25065a1d b/.github/coverage/run_coverage.78460cc2/metadata/25065a1d similarity index 100% rename from .github/coverage/run_coverage.e4d6ba08/metadata/25065a1d rename to .github/coverage/run_coverage.78460cc2/metadata/25065a1d diff --git a/.github/coverage/run_coverage.e4d6ba08/metadata/30592eb4 b/.github/coverage/run_coverage.78460cc2/metadata/30592eb4 similarity index 100% rename from .github/coverage/run_coverage.e4d6ba08/metadata/30592eb4 rename to .github/coverage/run_coverage.78460cc2/metadata/30592eb4 diff --git a/.github/coverage/run_coverage.78460cc2/metadata/6faa13b0 b/.github/coverage/run_coverage.78460cc2/metadata/6faa13b0 new file mode 100644 index 0000000000000000000000000000000000000000..3e6d19a9934c558bb527b45244cb17c6e0ba943b GIT binary patch literal 1042 zcmYMyIZFdk6o%m&_kG{@eNS#oRIrX)W9`~#hzK!@iMC>_tc?B*E5T@$SgM_h0soHQ zl@}c5@Vs*wra7~jI7k^|%5=9>T~=SH&Ee+pwXnvNY#UShseX3nx;&aEbe+?b@cbxC z=>@58{=Kj7m~z@DD`>B*q~~N6Ju9o}psbYr|;why(K4U?b%GxA99-Bku$XW58Q6t-gh-_XRiGkw@cSijoY#3 zQvXcizV$&qVGbX00WJE_i*q=OL5yPnV|ar5_=S7;gGCJCDz4x+W^fJjc!ld&zzuxC zSA4^FyumEq;vH_`Hh$m^e&R0rG3vC(iCDy*rz0urOC-GF|HN5aX#;! \"0x89\""}, {"lineNum":" 128","line":" # ```"}, -{"lineNum":" 129","line":" def to_prefixed_hex : String","class":"lineCov","hits":"2","order":"198","possible_hits":"2",}, -{"lineNum":" 130","line":" \"0x#{@hex}\"","class":"lineCov","hits":"1","order":"199","possible_hits":"1",}, +{"lineNum":" 129","line":" def to_prefixed_hex : String","class":"lineCov","hits":"2","order":"191","possible_hits":"2",}, +{"lineNum":" 130","line":" \"0x#{@hex}\"","class":"lineCov","hits":"1","order":"192","possible_hits":"1",}, {"lineNum":" 131","line":" end"}, {"lineNum":" 132","line":""}, {"lineNum":" 133","line":" # Returns a z-padded hexadecimal string representation."}, @@ -143,7 +143,7 @@ var data = {lines:[ {"lineNum":" 142","line":" def to_zpadded_hex(length = 32) : String","class":"lineCov","hits":"4","order":"25","possible_hits":"4",}, {"lineNum":" 143","line":" zpadded_hex = @hex","class":"lineCov","hits":"1","order":"26","possible_hits":"1",}, {"lineNum":" 144","line":" while zpadded_hex.size < length * 2","class":"linePartCov","hits":"1","order":"27","possible_hits":"2",}, -{"lineNum":" 145","line":" zpadded_hex = \"0#{zpadded_hex}\"","class":"lineCov","hits":"1","order":"192","possible_hits":"1",}, +{"lineNum":" 145","line":" zpadded_hex = \"0#{zpadded_hex}\"","class":"lineCov","hits":"1","order":"193","possible_hits":"1",}, {"lineNum":" 146","line":" end"}, {"lineNum":" 147","line":" zpadded_hex"}, {"lineNum":" 148","line":" end"}, @@ -179,52 +179,45 @@ var data = {lines:[ {"lineNum":" 178","line":" # ```"}, {"lineNum":" 179","line":" def to_zpadded_bytes(length = 32) : Bytes","class":"lineCov","hits":"3","order":"183","possible_hits":"3",}, {"lineNum":" 180","line":" zpadded_bytes = @bin","class":"lineCov","hits":"1","order":"184","possible_hits":"1",}, -{"lineNum":" 181","line":" byte_zero = Bytes[0]","class":"lineCov","hits":"1","order":"185","possible_hits":"1",}, -{"lineNum":" 182","line":" while zpadded_bytes.size < length","class":"lineCov","hits":"1","order":"186","possible_hits":"1",}, -{"lineNum":" 183","line":" slice_size = zpadded_bytes.size + 1","class":"lineNoCov","hits":"0","possible_hits":"1",}, -{"lineNum":" 184","line":" zpadded_slice = Slice(UInt8).new slice_size","class":"lineCov","hits":"1","order":"193","possible_hits":"1",}, -{"lineNum":" 185","line":" slice_pointer = zpadded_slice.to_unsafe","class":"lineCov","hits":"1","order":"194","possible_hits":"1",}, -{"lineNum":" 186","line":" byte_zero.copy_to(slice_pointer, 0)","class":"lineCov","hits":"1","order":"195","possible_hits":"1",}, -{"lineNum":" 187","line":" slice_pointer += 1","class":"lineCov","hits":"1","order":"196","possible_hits":"1",}, -{"lineNum":" 188","line":" zpadded_bytes.copy_to(slice_pointer, zpadded_bytes.size)","class":"lineCov","hits":"1","order":"197","possible_hits":"1",}, -{"lineNum":" 189","line":" zpadded_bytes = zpadded_slice","class":"lineCov","hits":"2","order":"187","possible_hits":"2",}, -{"lineNum":" 190","line":" end"}, -{"lineNum":" 191","line":" zpadded_bytes"}, -{"lineNum":" 192","line":" end"}, -{"lineNum":" 193","line":""}, -{"lineNum":" 194","line":" # Assists to determine wether a hex-string is prefixed."}, -{"lineNum":" 195","line":" private def is_prefixed?(hex : String) : Bool","class":"lineCov","hits":"2","order":"6","possible_hits":"2",}, -{"lineNum":" 196","line":" prefix_match = /\\A0x/.match hex","class":"lineCov","hits":"2","order":"7","possible_hits":"2",}, -{"lineNum":" 197","line":" unless prefix_match.nil?","class":"lineCov","hits":"1","order":"8","possible_hits":"1",}, -{"lineNum":" 198","line":" return true"}, -{"lineNum":" 199","line":" else"}, -{"lineNum":" 200","line":" return false"}, -{"lineNum":" 201","line":" end"}, -{"lineNum":" 202","line":" end"}, -{"lineNum":" 203","line":""}, -{"lineNum":" 204","line":" # Assists to remove a `0x`-hex prefix."}, -{"lineNum":" 205","line":" private def remove_prefix(hex : String) : String","class":"lineCov","hits":"1","order":"201","possible_hits":"1",}, -{"lineNum":" 206","line":" if is_prefixed? hex","class":"lineCov","hits":"1","order":"202","possible_hits":"1",}, -{"lineNum":" 207","line":" return hex[2..-1]","class":"lineCov","hits":"1","order":"203","possible_hits":"1",}, -{"lineNum":" 208","line":" else"}, -{"lineNum":" 209","line":" return hex"}, +{"lineNum":" 181","line":" while zpadded_bytes.size < length","class":"lineCov","hits":"1","order":"185","possible_hits":"1",}, +{"lineNum":" 182","line":" zpadded_bytes = Util.concat_bytes Bytes[0x00], zpadded_bytes","class":"lineCov","hits":"1","order":"190","possible_hits":"1",}, +{"lineNum":" 183","line":" end"}, +{"lineNum":" 184","line":" zpadded_bytes"}, +{"lineNum":" 185","line":" end"}, +{"lineNum":" 186","line":""}, +{"lineNum":" 187","line":" # Assists to determine wether a hex-string is prefixed."}, +{"lineNum":" 188","line":" private def is_prefixed?(hex : String) : Bool","class":"lineCov","hits":"2","order":"6","possible_hits":"2",}, +{"lineNum":" 189","line":" prefix_match = /\\A0x/.match hex","class":"lineCov","hits":"2","order":"7","possible_hits":"2",}, +{"lineNum":" 190","line":" unless prefix_match.nil?","class":"lineCov","hits":"1","order":"8","possible_hits":"1",}, +{"lineNum":" 191","line":" return true"}, +{"lineNum":" 192","line":" else"}, +{"lineNum":" 193","line":" return false"}, +{"lineNum":" 194","line":" end"}, +{"lineNum":" 195","line":" end"}, +{"lineNum":" 196","line":""}, +{"lineNum":" 197","line":" # Assists to remove a `0x`-hex prefix."}, +{"lineNum":" 198","line":" private def remove_prefix(hex : String) : String","class":"lineCov","hits":"1","order":"195","possible_hits":"1",}, +{"lineNum":" 199","line":" if is_prefixed? hex","class":"lineCov","hits":"1","order":"196","possible_hits":"1",}, +{"lineNum":" 200","line":" return hex[2..-1]","class":"lineCov","hits":"1","order":"197","possible_hits":"1",}, +{"lineNum":" 201","line":" else"}, +{"lineNum":" 202","line":" return hex"}, +{"lineNum":" 203","line":" end"}, +{"lineNum":" 204","line":" end"}, +{"lineNum":" 205","line":""}, +{"lineNum":" 206","line":" # Assists to assert wether a `String` is hexadecimal or not."}, +{"lineNum":" 207","line":" private def assert_hexadecimal(hex : String) : String","class":"lineCov","hits":"2","order":"4","possible_hits":"2",}, +{"lineNum":" 208","line":" if is_prefixed? hex","class":"lineCov","hits":"1","order":"5","possible_hits":"1",}, +{"lineNum":" 209","line":" hex = remove_prefix hex","class":"lineCov","hits":"1","order":"194","possible_hits":"1",}, {"lineNum":" 210","line":" end"}, -{"lineNum":" 211","line":" end"}, -{"lineNum":" 212","line":""}, -{"lineNum":" 213","line":" # Assists to assert wether a `String` is hexadecimal or not."}, -{"lineNum":" 214","line":" private def assert_hexadecimal(hex : String) : String","class":"lineCov","hits":"2","order":"4","possible_hits":"2",}, -{"lineNum":" 215","line":" if is_prefixed? hex","class":"lineCov","hits":"1","order":"5","possible_hits":"1",}, -{"lineNum":" 216","line":" hex = remove_prefix hex","class":"lineCov","hits":"1","order":"200","possible_hits":"1",}, -{"lineNum":" 217","line":" end"}, -{"lineNum":" 218","line":" hex_match = /\\A[0-9a-fA-F]*\\z/.match hex","class":"lineCov","hits":"2","order":"9","possible_hits":"2",}, -{"lineNum":" 219","line":" unless hex_match.nil?","class":"lineCov","hits":"1","order":"10","possible_hits":"1",}, -{"lineNum":" 220","line":" return hex_match.string"}, -{"lineNum":" 221","line":" else"}, -{"lineNum":" 222","line":" raise \"Invalid hex data provided: \'#{hex}\'\"","class":"lineCov","hits":"1","order":"204","possible_hits":"1",}, -{"lineNum":" 223","line":" end"}, -{"lineNum":" 224","line":" end"}, -{"lineNum":" 225","line":"end"}, +{"lineNum":" 211","line":" hex_match = /\\A[0-9a-fA-F]*\\z/.match hex","class":"lineCov","hits":"2","order":"9","possible_hits":"2",}, +{"lineNum":" 212","line":" unless hex_match.nil?","class":"lineCov","hits":"1","order":"10","possible_hits":"1",}, +{"lineNum":" 213","line":" return hex_match.string"}, +{"lineNum":" 214","line":" else"}, +{"lineNum":" 215","line":" raise \"Invalid hex data provided: \'#{hex}\'\"","class":"lineCov","hits":"1","order":"198","possible_hits":"1",}, +{"lineNum":" 216","line":" end"}, +{"lineNum":" 217","line":" end"}, +{"lineNum":" 218","line":"end"}, ]}; var percent_low = 25;var percent_high = 75; -var header = { "command" : "run_coverage", "date" : "2022-04-06 11:52:18", "instrumented" : 54, "covered" : 53,}; +var header = { "command" : "run_coverage", "date" : "2022-04-06 12:16:54", "instrumented" : 47, "covered" : 47,}; var merged_data = []; diff --git a/.github/coverage/run_coverage.e4d6ba08/point.cr.10ecf873.html b/.github/coverage/run_coverage.78460cc2/point.cr.10ecf873.html similarity index 100% rename from .github/coverage/run_coverage.e4d6ba08/point.cr.10ecf873.html rename to .github/coverage/run_coverage.78460cc2/point.cr.10ecf873.html diff --git a/.github/coverage/run_coverage.e4d6ba08/point.cr.10ecf873.js b/.github/coverage/run_coverage.78460cc2/point.cr.10ecf873.js similarity index 91% rename from .github/coverage/run_coverage.e4d6ba08/point.cr.10ecf873.js rename to .github/coverage/run_coverage.78460cc2/point.cr.10ecf873.js index 274192c..aa156ae 100644 --- a/.github/coverage/run_coverage.e4d6ba08/point.cr.10ecf873.js +++ b/.github/coverage/run_coverage.78460cc2/point.cr.10ecf873.js @@ -107,34 +107,34 @@ var data = {lines:[ {"lineNum":" 106","line":" # # @dec=15358791661898278541670676806913272995387450360720708081975214114817468371819,"}, {"lineNum":" 107","line":" # # @bin=Bytes[33, 244, 196, 156, 254, 144, 218, 57, 194, 84, 165, 27, 142, 232, 175, 205, 216, 192, 45, 213, 102, 241, 53, 130, 194, 62, 16, 76, 126, 213, 147, 107]>>"}, {"lineNum":" 108","line":" # ```"}, -{"lineNum":" 109","line":" def initialize(pub : String)","class":"lineCov","hits":"4","order":"206","possible_hits":"4",}, -{"lineNum":" 110","line":" case pub.size","class":"lineCov","hits":"1","order":"207","possible_hits":"1",}, -{"lineNum":" 111","line":" when 130, 128","class":"lineCov","hits":"2","order":"208","possible_hits":"2",}, -{"lineNum":" 112","line":" pub = pub[2, 128] if pub.size === 130","class":"lineCov","hits":"2","order":"209","possible_hits":"2",}, -{"lineNum":" 113","line":" @x = Num.new pub[0, 64]","class":"lineCov","hits":"1","order":"210","possible_hits":"1",}, -{"lineNum":" 114","line":" @y = Num.new pub[64, 64]","class":"lineCov","hits":"1","order":"211","possible_hits":"1",}, -{"lineNum":" 115","line":" when 66","class":"lineCov","hits":"2","order":"213","possible_hits":"2",}, -{"lineNum":" 116","line":" prefix = pub[0, 2]","class":"lineCov","hits":"1","order":"214","possible_hits":"1",}, -{"lineNum":" 117","line":" if prefix === \"02\" || prefix === \"03\"","class":"lineCov","hits":"2","order":"215","possible_hits":"2",}, -{"lineNum":" 118","line":" prime = P.to_big","class":"lineCov","hits":"1","order":"216","possible_hits":"1",}, -{"lineNum":" 119","line":" x = Num.new(pub[2, 64]).to_big","class":"lineCov","hits":"1","order":"217","possible_hits":"1",}, +{"lineNum":" 109","line":" def initialize(pub : String)","class":"lineCov","hits":"4","order":"200","possible_hits":"4",}, +{"lineNum":" 110","line":" case pub.size","class":"lineCov","hits":"1","order":"201","possible_hits":"1",}, +{"lineNum":" 111","line":" when 130, 128","class":"lineCov","hits":"2","order":"202","possible_hits":"2",}, +{"lineNum":" 112","line":" pub = pub[2, 128] if pub.size === 130","class":"lineCov","hits":"2","order":"203","possible_hits":"2",}, +{"lineNum":" 113","line":" @x = Num.new pub[0, 64]","class":"lineCov","hits":"1","order":"204","possible_hits":"1",}, +{"lineNum":" 114","line":" @y = Num.new pub[64, 64]","class":"lineCov","hits":"1","order":"205","possible_hits":"1",}, +{"lineNum":" 115","line":" when 66","class":"lineCov","hits":"2","order":"207","possible_hits":"2",}, +{"lineNum":" 116","line":" prefix = pub[0, 2]","class":"lineCov","hits":"1","order":"208","possible_hits":"1",}, +{"lineNum":" 117","line":" if prefix === \"02\" || prefix === \"03\"","class":"lineCov","hits":"2","order":"209","possible_hits":"2",}, +{"lineNum":" 118","line":" prime = P.to_big","class":"lineCov","hits":"1","order":"210","possible_hits":"1",}, +{"lineNum":" 119","line":" x = Num.new(pub[2, 64]).to_big","class":"lineCov","hits":"1","order":"211","possible_hits":"1",}, {"lineNum":" 120","line":""}, -{"lineNum":" 121","line":" a = x ** 3 % prime","class":"lineCov","hits":"1","order":"218","possible_hits":"1",}, -{"lineNum":" 122","line":" a = (a + 7) % prime","class":"lineCov","hits":"1","order":"219","possible_hits":"1",}, -{"lineNum":" 123","line":" e = ((prime + 1) // 4) % prime","class":"lineCov","hits":"1","order":"220","possible_hits":"1",}, -{"lineNum":" 124","line":" y = BigInt.new","class":"lineCov","hits":"1","order":"221","possible_hits":"1",}, -{"lineNum":" 125","line":" LibGMP.mpz_powm_sec(y, a, e, prime)","class":"lineCov","hits":"1","order":"222","possible_hits":"1",}, +{"lineNum":" 121","line":" a = x ** 3 % prime","class":"lineCov","hits":"1","order":"212","possible_hits":"1",}, +{"lineNum":" 122","line":" a = (a + 7) % prime","class":"lineCov","hits":"1","order":"213","possible_hits":"1",}, +{"lineNum":" 123","line":" e = ((prime + 1) // 4) % prime","class":"lineCov","hits":"1","order":"214","possible_hits":"1",}, +{"lineNum":" 124","line":" y = BigInt.new","class":"lineCov","hits":"1","order":"215","possible_hits":"1",}, +{"lineNum":" 125","line":" LibGMP.mpz_powm_sec(y, a, e, prime)","class":"lineCov","hits":"1","order":"216","possible_hits":"1",}, {"lineNum":" 126","line":""}, -{"lineNum":" 127","line":" y_parity = prefix.to_i - 2","class":"linePartCov","hits":"1","order":"223","possible_hits":"2",}, -{"lineNum":" 128","line":" y = -y % prime if y % 2 != y_parity","class":"lineCov","hits":"1","order":"224","possible_hits":"1",}, +{"lineNum":" 127","line":" y_parity = prefix.to_i - 2","class":"linePartCov","hits":"1","order":"217","possible_hits":"2",}, +{"lineNum":" 128","line":" y = -y % prime if y % 2 != y_parity","class":"lineCov","hits":"1","order":"218","possible_hits":"1",}, {"lineNum":" 129","line":""}, -{"lineNum":" 130","line":" @x = Num.new x","class":"lineCov","hits":"1","order":"225","possible_hits":"1",}, -{"lineNum":" 131","line":" @y = Num.new y","class":"lineCov","hits":"2","order":"226","possible_hits":"2",}, +{"lineNum":" 130","line":" @x = Num.new x","class":"lineCov","hits":"1","order":"219","possible_hits":"1",}, +{"lineNum":" 131","line":" @y = Num.new y","class":"lineCov","hits":"2","order":"220","possible_hits":"2",}, {"lineNum":" 132","line":" else"}, -{"lineNum":" 133","line":" raise \"Invalid prefix for compressed public point: #{prefix}\"","class":"lineCov","hits":"2","order":"227","possible_hits":"2",}, +{"lineNum":" 133","line":" raise \"Invalid prefix for compressed public point: #{prefix}\"","class":"lineCov","hits":"2","order":"221","possible_hits":"2",}, {"lineNum":" 134","line":" end"}, {"lineNum":" 135","line":" else"}, -{"lineNum":" 136","line":" raise \"Unknown public point format (Invalid size: #{pub.size})\"","class":"lineCov","hits":"3","order":"212","possible_hits":"3",}, +{"lineNum":" 136","line":" raise \"Unknown public point format (Invalid size: #{pub.size})\"","class":"lineCov","hits":"3","order":"206","possible_hits":"3",}, {"lineNum":" 137","line":" end"}, {"lineNum":" 138","line":" end"}, {"lineNum":" 139","line":""}, @@ -167,5 +167,5 @@ var data = {lines:[ {"lineNum":" 166","line":"end"}, ]}; var percent_low = 25;var percent_high = 75; -var header = { "command" : "run_coverage", "date" : "2022-04-06 11:52:18", "instrumented" : 36, "covered" : 36,}; +var header = { "command" : "run_coverage", "date" : "2022-04-06 12:16:54", "instrumented" : 36, "covered" : 36,}; var merged_data = []; diff --git a/.github/coverage/run_coverage.e4d6ba08/secp256k1.cr.30592eb4.html b/.github/coverage/run_coverage.78460cc2/secp256k1.cr.30592eb4.html similarity index 100% rename from .github/coverage/run_coverage.e4d6ba08/secp256k1.cr.30592eb4.html rename to .github/coverage/run_coverage.78460cc2/secp256k1.cr.30592eb4.html diff --git a/.github/coverage/run_coverage.e4d6ba08/secp256k1.cr.30592eb4.js b/.github/coverage/run_coverage.78460cc2/secp256k1.cr.30592eb4.js similarity index 98% rename from .github/coverage/run_coverage.e4d6ba08/secp256k1.cr.30592eb4.js rename to .github/coverage/run_coverage.78460cc2/secp256k1.cr.30592eb4.js index 3542573..55cb109 100644 --- a/.github/coverage/run_coverage.e4d6ba08/secp256k1.cr.30592eb4.js +++ b/.github/coverage/run_coverage.78460cc2/secp256k1.cr.30592eb4.js @@ -52,5 +52,5 @@ var data = {lines:[ {"lineNum":" 51","line":"end"}, ]}; var percent_low = 25;var percent_high = 75; -var header = { "command" : "run_coverage", "date" : "2022-04-06 11:52:18", "instrumented" : 5, "covered" : 5,}; +var header = { "command" : "run_coverage", "date" : "2022-04-06 12:16:54", "instrumented" : 5, "covered" : 5,}; var merged_data = []; diff --git a/.github/coverage/run_coverage.e4d6ba08/signature.cr.25065a1d.html b/.github/coverage/run_coverage.78460cc2/signature.cr.25065a1d.html similarity index 100% rename from .github/coverage/run_coverage.e4d6ba08/signature.cr.25065a1d.html rename to .github/coverage/run_coverage.78460cc2/signature.cr.25065a1d.html diff --git a/.github/coverage/run_coverage.e4d6ba08/signature.cr.25065a1d.js b/.github/coverage/run_coverage.78460cc2/signature.cr.25065a1d.js similarity index 99% rename from .github/coverage/run_coverage.e4d6ba08/signature.cr.25065a1d.js rename to .github/coverage/run_coverage.78460cc2/signature.cr.25065a1d.js index 5c2d3f1..3efb683 100644 --- a/.github/coverage/run_coverage.e4d6ba08/signature.cr.25065a1d.js +++ b/.github/coverage/run_coverage.78460cc2/signature.cr.25065a1d.js @@ -79,5 +79,5 @@ var data = {lines:[ {"lineNum":" 78","line":"end"}, ]}; var percent_low = 25;var percent_high = 75; -var header = { "command" : "run_coverage", "date" : "2022-04-06 11:52:18", "instrumented" : 6, "covered" : 6,}; +var header = { "command" : "run_coverage", "date" : "2022-04-06 12:16:54", "instrumented" : 6, "covered" : 6,}; var merged_data = []; diff --git a/.github/coverage/run_coverage.e4d6ba08/sonarqube.xml b/.github/coverage/run_coverage.78460cc2/sonarqube.xml similarity index 94% rename from .github/coverage/run_coverage.e4d6ba08/sonarqube.xml rename to .github/coverage/run_coverage.78460cc2/sonarqube.xml index 3bf6313..fdff24d 100644 --- a/.github/coverage/run_coverage.e4d6ba08/sonarqube.xml +++ b/.github/coverage/run_coverage.78460cc2/sonarqube.xml @@ -224,25 +224,18 @@ - - - - - - - - - - + + + + - + + + + - - - - diff --git a/.github/coverage/run_coverage.e4d6ba08/summary.db b/.github/coverage/run_coverage.78460cc2/summary.db similarity index 76% rename from .github/coverage/run_coverage.e4d6ba08/summary.db rename to .github/coverage/run_coverage.78460cc2/summary.db index eda5eed95fb50b5455c316c49f3bd7d346d3d463..2eb2ee6ce66104a93bfc80e050d8048f71d0bd4b 100644 GIT binary patch literal 276 mcmZ?G&CFq7U|<4bMj(Cz#LtUL^Wu~9%TkLH(^G-`5eEQeIS5_= literal 276 mcmZ?G&CFq7U|<4bMj-wS#BYmA^Wu~9%TkLH(^G-`5eEQrVhC#h diff --git a/.github/coverage/run_coverage.e4d6ba08/util.cr.e684f666.html b/.github/coverage/run_coverage.78460cc2/util.cr.e684f666.html similarity index 100% rename from .github/coverage/run_coverage.e4d6ba08/util.cr.e684f666.html rename to .github/coverage/run_coverage.78460cc2/util.cr.e684f666.html diff --git a/.github/coverage/run_coverage.e4d6ba08/util.cr.e684f666.js b/.github/coverage/run_coverage.78460cc2/util.cr.e684f666.js similarity index 96% rename from .github/coverage/run_coverage.e4d6ba08/util.cr.e684f666.js rename to .github/coverage/run_coverage.78460cc2/util.cr.e684f666.js index f717803..96317b3 100644 --- a/.github/coverage/run_coverage.e4d6ba08/util.cr.e684f666.js +++ b/.github/coverage/run_coverage.78460cc2/util.cr.e684f666.js @@ -38,7 +38,7 @@ var data = {lines:[ {"lineNum":" 37","line":" if data.is_a? String"}, {"lineNum":" 38","line":" return Num.new keccak.update(data).hexdigest","class":"lineCov","hits":"1","order":"164","possible_hits":"1",}, {"lineNum":" 39","line":" else"}, -{"lineNum":" 40","line":" return Num.new keccak.update(data.to_bytes).hexdigest","class":"lineCov","hits":"1","order":"228","possible_hits":"1",}, +{"lineNum":" 40","line":" return Num.new keccak.update(data.to_bytes).hexdigest","class":"lineCov","hits":"1","order":"222","possible_hits":"1",}, {"lineNum":" 41","line":" end"}, {"lineNum":" 42","line":" end"}, {"lineNum":" 43","line":""}, @@ -57,12 +57,12 @@ var data = {lines:[ {"lineNum":" 56","line":" # Util.sha3(\"0xdeadbeef\").hex"}, {"lineNum":" 57","line":" # # => \"c12811e13ed75afe3e0945ef34e8a25b9d321a46e131c6463731de25a21b39eb\""}, {"lineNum":" 58","line":" # ```"}, -{"lineNum":" 59","line":" def sha3(data : Num | String, entropy = 256) : Num","class":"lineCov","hits":"6","order":"229","possible_hits":"6",}, -{"lineNum":" 60","line":" sha3 = Digest::SHA3.new entropy","class":"lineCov","hits":"2","order":"230","possible_hits":"2",}, +{"lineNum":" 59","line":" def sha3(data : Num | String, entropy = 256) : Num","class":"lineCov","hits":"6","order":"223","possible_hits":"6",}, +{"lineNum":" 60","line":" sha3 = Digest::SHA3.new entropy","class":"lineCov","hits":"2","order":"224","possible_hits":"2",}, {"lineNum":" 61","line":" if data.is_a? String"}, -{"lineNum":" 62","line":" return Num.new sha3.update(data).hexdigest","class":"lineCov","hits":"1","order":"231","possible_hits":"1",}, +{"lineNum":" 62","line":" return Num.new sha3.update(data).hexdigest","class":"lineCov","hits":"1","order":"225","possible_hits":"1",}, {"lineNum":" 63","line":" else"}, -{"lineNum":" 64","line":" return Num.new sha3.update(data.to_bytes).hexdigest","class":"lineCov","hits":"1","order":"232","possible_hits":"1",}, +{"lineNum":" 64","line":" return Num.new sha3.update(data.to_bytes).hexdigest","class":"lineCov","hits":"1","order":"226","possible_hits":"1",}, {"lineNum":" 65","line":" end"}, {"lineNum":" 66","line":" end"}, {"lineNum":" 67","line":""}, @@ -85,7 +85,7 @@ var data = {lines:[ {"lineNum":" 84","line":" if data.is_a? String"}, {"lineNum":" 85","line":" return Num.new sha2.update(data).final.hexstring","class":"lineCov","hits":"1","order":"101","possible_hits":"1",}, {"lineNum":" 86","line":" else"}, -{"lineNum":" 87","line":" return Num.new sha2.update(data.to_bytes).final.hexstring","class":"lineCov","hits":"1","order":"233","possible_hits":"1",}, +{"lineNum":" 87","line":" return Num.new sha2.update(data.to_bytes).final.hexstring","class":"lineCov","hits":"1","order":"227","possible_hits":"1",}, {"lineNum":" 88","line":" end"}, {"lineNum":" 89","line":" end"}, {"lineNum":" 90","line":""}, @@ -103,12 +103,12 @@ var data = {lines:[ {"lineNum":" 102","line":" # Util.ripemd160(\"0xdeadbeef\").hex"}, {"lineNum":" 103","line":" # # => \"4caf817f14e84b564e47afd19966e5d123ee0183\""}, {"lineNum":" 104","line":" # ```"}, -{"lineNum":" 105","line":" def ripemd160(data : Num | String) : Num","class":"lineCov","hits":"2","order":"234","possible_hits":"2",}, -{"lineNum":" 106","line":" ripemd = OpenSSL::Digest.new \"RIPEMD160\"","class":"lineCov","hits":"2","order":"235","possible_hits":"2",}, +{"lineNum":" 105","line":" def ripemd160(data : Num | String) : Num","class":"lineCov","hits":"2","order":"228","possible_hits":"2",}, +{"lineNum":" 106","line":" ripemd = OpenSSL::Digest.new \"RIPEMD160\"","class":"lineCov","hits":"2","order":"229","possible_hits":"2",}, {"lineNum":" 107","line":" if data.is_a? String"}, -{"lineNum":" 108","line":" return Num.new ripemd.update(data).final.hexstring","class":"lineCov","hits":"1","order":"237","possible_hits":"1",}, +{"lineNum":" 108","line":" return Num.new ripemd.update(data).final.hexstring","class":"lineCov","hits":"1","order":"231","possible_hits":"1",}, {"lineNum":" 109","line":" else"}, -{"lineNum":" 110","line":" return Num.new ripemd.update(data.to_bytes).final.hexstring","class":"lineCov","hits":"1","order":"236","possible_hits":"1",}, +{"lineNum":" 110","line":" return Num.new ripemd.update(data.to_bytes).final.hexstring","class":"lineCov","hits":"1","order":"230","possible_hits":"1",}, {"lineNum":" 111","line":" end"}, {"lineNum":" 112","line":" end"}, {"lineNum":" 113","line":""}, @@ -188,5 +188,5 @@ var data = {lines:[ {"lineNum":" 187","line":"end"}, ]}; var percent_low = 25;var percent_high = 75; -var header = { "command" : "run_coverage", "date" : "2022-04-06 11:52:18", "instrumented" : 44, "covered" : 41,}; +var header = { "command" : "run_coverage", "date" : "2022-04-06 12:16:54", "instrumented" : 44, "covered" : 41,}; var merged_data = []; diff --git a/.github/coverage/run_coverage.e4d6ba08/metadata/6faa13b0 b/.github/coverage/run_coverage.e4d6ba08/metadata/6faa13b0 deleted file mode 100644 index a6d2746c5d45b259acc2c273db34161dfacebf8e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1182 zcmYMyOD|k;7{~ELX;rDBH>#zjSInO=BeAW^%*Musxhyc5rpY)nI#c`d0$kpJ7toc2 zF~((uC3Xmj7tmMX_wY@6GEY9=bMnv0B+nVo&E!4LtI}`X|6cs3_GZTu6JpTwDmV0e zTD_yOt3p#k>upUX_eJ@D-jaIf-T6&fO^4(|+Q~`gwD!3Iw&<|Hgr{;s< Y!AyT3m3M`F>i+|mUGVi#%e}vD0UiF;(f|Me diff --git a/docs/index.json b/docs/index.json index 75b4d34..79e8828 100644 --- a/docs/index.json +++ b/docs/index.json @@ -1 +1 @@ -{"repository_name":"secp256k1","body":"# secp256k1.cr\n\n[![Build Status](https://img.shields.io/github/workflow/status/q9f/secp256k1.cr/Nightly)](https://github.com/q9f/secp256k1.cr/actions)\n[![Code Coverage](https://codecov.io/gh/q9f/secp256k1.cr/branch/main/graph/badge.svg?token=ngxRs9HdJA)](https://codecov.io/gh/q9f/secp256k1.cr)\n[![Documentation](https://img.shields.io/badge/docs-html-black)](https://q9f.github.io/secp256k1.cr/)\n[![Release](https://img.shields.io/github/v/release/q9f/secp256k1.cr?include_prereleases&color=black)](https://github.com/q9f/secp256k1.cr/releases/latest)\n[![Language](https://img.shields.io/github/languages/top/q9f/secp256k1.cr?color=black)](https://github.com/q9f/secp256k1.cr/search?l=crystal)\n[![License](https://img.shields.io/github/license/q9f/secp256k1.cr.svg?color=black)](LICENSE)\n\nA library implementing the `Secp256k1` elliptic curve natively in pure Crystal.\n`Secp256k1` is the elliptic curve used in the public-private-key cryptography required by `Bitcoin`, `Ethereum`, and `Polkadot`.\n\nThis library allows for:\n* providing a `Secp256k1` cryptographic context, see `Secp256k1::Context`\n* managing `Secp256k1` signatures and verification, see `Secp256k1::Signature`\n* managing private-public keypairs, see `Secp256k1::Key`\n* generating public keys, see `Secp256k1::Point`\n* generating private keys, see `Secp256k1::Num`\n\n# Installation\n\nAdd the `Secp256k1` library to your `shard.yml`\n\n```yaml\ndependencies:\n secp256k1:\n github: q9f/secp256k1.cr\n version: \"~> 0.5\"\n```\n\n# Usage\n\nImport and expose the `Secp256k1` module.\n\n```crystal\nrequire \"secp256k1\"\n```\n\nThis library exposes the following modules and classes (in logical order):\n\n* `Secp256k1`: necessary constants and data structures, including:\n - `Secp256k1::Num`: for managing big numerics (private keys)\n - `Secp256k1::Point`: for handling of elliptic curve points (public keys)\n - `Secp256k1::Key`: for managing private-public keypairs (accounts)\n - `Secp256k1::Signature`: for handling ECDSA signatures (r, s, v)\n* `Secp256k1::Context`: providing a cryptographic context for signing and verification\n* `Secp256k1::Curve`: the entire core mathematics behind the elliptic curve cryptography\n* `Secp256k1::Util`: binding of various hashing algorithms for convenience\n\nBasic usage:\n\n```crystal\n# generates a new, random keypair\nkey = Secp256k1::Key.new\n# => #,\n# @public_key=#,\n# @y=#>>\n\n# gets the private key\nkey.private_hex\n# => \"3ccf84820c20d5e8c536ba84c52ba410375b29b1812b5f7e722445c969a0fb30\"\n\n# gets the compressed public key with prefix\nkey.public_hex_compressed\n# => \"02cd4a8712ee6efc15b5abe37c0dbfa979d89c427d3fe24b076008decefe94dba2\"\n```\n\nSignature generation and verification:\n\n```crystal\n# sign a message with a private key\nctx = Secp256k1::Context.new\npriv = Secp256k1::Num.new \"1f0c122d41ff536b19bfd83537c0dfc290e45cd3c375a43237c8b8fff7ac8af7\"\nkey = Secp256k1::Key.new priv\nhash = Secp256k1::Util.sha256 \"Henlo, Wordl\"\nsig = ctx.sign key, hash\n# => #,\n# @s=#,\n# @v=#>\n\n# verify a signature with a public key\nr = Secp256k1::Num.new \"c4079db44240b7afe94985c69fc89602e33629fd9b8623d711c30ce6378b33df\"\ns = Secp256k1::Num.new \"6842c1b63c94bdb8e4f5ae88fb65f7a98b77b197c8323004fb47ef57fab29053\"\nv = Secp256k1::Num.new \"00\"\nsig = Secp256k1::Signature.new r, s, v\nhash = Secp256k1::Util.sha256 \"Henlo, Wordl\"\npubl = Secp256k1::Point.new \"0416008a369439f1a8a75cf974860bed5b10180518d6b1dd3ac847f423fd375d6aa29474394f0cd79d2ea543507d069e97339284f01bdbfd27392daec0ec553816\"\nctx.verify sig, hash, publ\n# => true\n```\n\n# Documentation\n\nThe full library documentation can be found here: [q9f.github.io/secp256k1.cr](https://q9f.github.io/secp256k1.cr/)\n\nGenerate a local copy with:\n\n```shell\ncrystal docs\n```\n\n# Testing\n\nThe library is entirely specified through tests in `./spec`; run:\n\n```shell\ncrystal spec --verbose\n```\n\n# Understand\n\nPrivate keys are just scalars (`Secp256k1::Num`) and public keys are points (`Secp256k1::Point`) with `x` and `y` coordinates.\n\nBitcoin public keys can be uncompressed `p|x|y` or compressed `p|x`. both come with a prefix `p` which is useless for uncompressed keys but necessary for compressed keys to recover the `y` coordinate on the `Secp256k1` elliptic curve field.\n\nEthereum public keys are uncompressed `x|y` without any prefix. The last 20 bytes slice of the `y` coordinate is actually used as address without any checksum. A checksum was later added in EIP-55 using a `keccak256` hash and indicating character capitalization.\n\nNeither Bitcoin nor Ethereum allow for recovering public keys from an address unless there exists a transaction with a valid signature on the blockchain.\n\n# Known issues\n\n_Note: this library should not be used in production without proper auditing. It should be considered slow and insecure._\n\n* This library is not constant time and might be subject to side-channel attacks. ([#4](https://github.com/q9f/secp256k1.cr/issues/4))\n* This library does unnecessary big-integer math and should someday rather correctly implement the `Secp256k1` prime field ([#5](https://github.com/q9f/secp256k1.cr/issues/5))\n* This library is slow in recovering signatures. Future versions should respect the recovery ID to quickly identify the correct public key from a signature.\n\nFound any other issue? Report it: [github.com/q9f/secp256k1.cr/issues](https://github.com/q9f/secp256k1.cr/issues)\n\n# Contribute\n\nCreate a pull request, and make sure tests and linter pass.\n\nThis pure crystal implementation is based on the python implementation [wobine/blackboard101](https://github.com/wobine/blackboard101) which is also used as reference to write tests against. It's a complete rewrite of the abandoned [packetzero/bitcoinutils](https://github.com/packetzero/bitcoinutils) for educational purposes.\n\nHonerable mention for the [bitcoin wiki](https://en.bitcoin.it/wiki/Main_Page) and the [ethereum stackexchange](https://ethereum.stackexchange.com/) for providing so many in-depth resources that supported this project in reimplementing everything.\n\nLicense: Apache License v2.0\n\nContributors: [**@q9f**](https://github.com/q9f/), [@cserb](https://github.com/cserb), [MrSorcus](https://github.com/MrSorcus)\n","program":{"html_id":"secp256k1/toplevel","path":"toplevel.html","kind":"module","full_name":"Top Level Namespace","name":"Top Level Namespace","abstract":false,"locations":[],"repository_name":"secp256k1","program":true,"enum":false,"alias":false,"const":false,"types":[{"html_id":"secp256k1/Secp256k1","path":"Secp256k1.html","kind":"module","full_name":"Secp256k1","name":"Secp256k1","abstract":false,"locations":[{"filename":"src/secp256k1.cr","line_number":35,"url":null},{"filename":"src/secp256k1/context.cr","line_number":22,"url":null},{"filename":"src/secp256k1/version.cr","line_number":21,"url":null}],"repository_name":"secp256k1","program":false,"enum":false,"alias":false,"const":false,"constants":[{"id":"G","name":"G","value":"Point.new(Num.new(\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\"), Num.new(\"483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8\"))","doc":"A commonly used base point `G` with coordinates `x` and `y`\nsatisfying `y^2 = x^3 + 7`.","summary":"

A commonly used base point G with coordinates x and y satisfying y^2 = x^3 + 7.

"},{"id":"N","name":"N","value":"Num.new(\"fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141\")","doc":"The order `n` of `G` defines the finite size of the Secp256k1 field `E`.","summary":"

The order n of G defines the finite size of the Secp256k1 field E.

"},{"id":"P","name":"P","value":"Num.new(\"fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f\")","doc":"The elliptic curve domain parameters over `F_p` associated with a\nKoblitz curve `Secp256k1` are specified by the sextuple\n`T = (p, a, b, G, n, h)` where the finite field `F_p` is defined by\nthe prime `p = 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1`.","summary":"

The elliptic curve domain parameters over F_p associated with a Koblitz curve Secp256k1 are specified by the sextuple T = (p, a, b, G, n, h) where the finite field F_p is defined by the prime p = 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1.

"},{"id":"VERSION","name":"VERSION","value":"\"0.5.0\"","doc":"The `VERSION` of the `Secp256k1` module.","summary":"

The VERSION of the Secp256k1 module.

"}],"doc":"Provides the `Secp256k1` module with the elliptic curve parameters\nused by the `Bitcoin`, `Ethereum`, and `Polkadot` blockchains. It's\nprimarily used to generate key-pairs as well as signing messages and\nrecoverying signatures.\n\nRef: [secg.org/sec2-v2.pdf](https://www.secg.org/sec2-v2.pdf)","summary":"

Provides the Secp256k1 module with the elliptic curve parameters used by the Bitcoin, Ethereum, and Polkadot blockchains.

","types":[{"html_id":"secp256k1/Secp256k1/Context","path":"Secp256k1/Context.html","kind":"class","full_name":"Secp256k1::Context","name":"Context","abstract":false,"superclass":{"html_id":"secp256k1/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"secp256k1/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"secp256k1/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/secp256k1/context.cr","line_number":22,"url":null}],"repository_name":"secp256k1","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"secp256k1/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"Provides a `Secp256k1` context to allow signing arbitrary data,\nrecovering public keys, and verifying signatures.\n\n```\nctx = Context.new\n# => #\n```","summary":"

Provides a Secp256k1 context to allow signing arbitrary data, recovering public keys, and verifying signatures.

","instance_methods":[{"html_id":"sign(key:Key,hash:Num):Signature-instance-method","name":"sign","doc":"Signs a message hash or any other arbitrary data with a given keypair.\n\nParameters:\n* `key` (`Key`): the keypair containing a secret to sign the data.\n* `hash` (`Num`): the message or arbirtrary data hash.\n\nReturns a `Signature` proving the given key signed the message hash.\n\n```\nctx = Context.new\nkey = Key.new Num.new \"1f0c122d41ff536b19bfd83537c0dfc290e45cd3c375a43237c8b8fff7ac8af7\"\nhash = Util.sha256 \"Henlo, Wordl\"\nsig = ctx.sign key, hash\n# => #,\n# @s=#,\n# @v=#>\n```","summary":"

Signs a message hash or any other arbitrary data with a given keypair.

","abstract":false,"args":[{"name":"key","external_name":"key","restriction":"Key"},{"name":"hash","external_name":"hash","restriction":"Num"}],"args_string":"(key : Key, hash : Num) : Signature","args_html":"(key : Key, hash : Num) : Signature","location":{"filename":"src/secp256k1/context.cr","line_number":50,"url":null},"def":{"name":"sign","args":[{"name":"key","external_name":"key","restriction":"Key"},{"name":"hash","external_name":"hash","restriction":"Num"}],"return_type":"Signature","visibility":"Public","body":"k = Util.deterministic_k(key.private_key, hash)\nhash = hash.to_big\npriv = key.private_key.to_big\npoint = Curve.mul(G, k)\nr = point.x.to_big % N.to_big\nk_inv = Curve.mod_inv(k, N)\ns = ((hash + (r * priv)) * k_inv.to_big) % N.to_big\nx_mag = point.x.to_big > N.to_big\ny_parity = (point.y.to_big % 2) == 0\nrec_id : Int8 = -1\nif (!y_parity) && x_mag\n rec_id = 3\nelse\n if y_parity && x_mag\n rec_id = 2\n else\n if (!y_parity) && (!x_mag)\n rec_id = 1\n else\n rec_id = 0\n end\n end\nend\nr = Num.new(r)\ns = Num.new(s)\nv = Num.new(BigInt.new(rec_id))\nSignature.new(r, s, v)\n"}},{"html_id":"verify(sig:Signature,hash:Num,publ:Point):Bool-instance-method","name":"verify","doc":"Verifies that a given signature for a given message hash matches\nthe provided public key.\n\nParameters:\n* `sig` (`Signature`): the signature to be verified.\n* `hash` (`Num`): the message or arbirtrary data hash.\n* `publ` (`Point`): the public key to match.\n\nReturns _true_ if the signature verifies.\n\n```\nctx = Context.new\nr = Num.new \"c4079db44240b7afe94985c69fc89602e33629fd9b8623d711c30ce6378b33df\"\ns = Num.new \"6842c1b63c94bdb8e4f5ae88fb65f7a98b77b197c8323004fb47ef57fab29053\"\nv = Num.new \"00\"\nsig = Signature.new r, s, v\nhash = Util.sha256 \"Henlo, Wordl\"\npubl = Point.new \"0416008a369439f1a8a75cf974860bed5b10180518d6b1dd3ac847f423fd375d6aa29474394f0cd79d2ea543507d069e97339284f01bdbfd27392daec0ec553816\"\nctx.verify sig, hash, publ\n# => true\n```","summary":"

Verifies that a given signature for a given message hash matches the provided public key.

","abstract":false,"args":[{"name":"sig","external_name":"sig","restriction":"Signature"},{"name":"hash","external_name":"hash","restriction":"Num"},{"name":"publ","external_name":"publ","restriction":"Point"}],"args_string":"(sig : Signature, hash : Num, publ : Point) : Bool","args_html":"(sig : Signature, hash : Num, publ : Point) : Bool","location":{"filename":"src/secp256k1/context.cr","line_number":97,"url":null},"def":{"name":"verify","args":[{"name":"sig","external_name":"sig","restriction":"Signature"},{"name":"hash","external_name":"hash","restriction":"Num"},{"name":"publ","external_name":"publ","restriction":"Point"}],"return_type":"Bool","visibility":"Public","body":"s_inv = Curve.mod_inv(sig.s, N)\np0 = Curve.mul(G, (hash.to_big * s_inv.to_big) % N.to_big)\np1 = Curve.mul(publ, (sig.r.to_big * s_inv.to_big) % N.to_big)\np = Curve.add(p0, p1)\nsig.r.to_big === p.x.to_big\n"}}]},{"html_id":"secp256k1/Secp256k1/Curve","path":"Secp256k1/Curve.html","kind":"module","full_name":"Secp256k1::Curve","name":"Curve","abstract":false,"locations":[{"filename":"src/secp256k1/curve.cr","line_number":18,"url":null}],"repository_name":"secp256k1","program":false,"enum":false,"alias":false,"const":false,"extended_modules":[{"html_id":"secp256k1/Secp256k1/Curve","kind":"module","full_name":"Secp256k1::Curve","name":"Curve"}],"namespace":{"html_id":"secp256k1/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"Implements 256-bit `Secp256k1` Koblitz elliptic curve operations.\n\nRef: [secg.org/sec2-v2.pdf](https://www.secg.org/sec2-v2.pdf)","summary":"

Implements 256-bit Secp256k1 Koblitz elliptic curve operations.

","instance_methods":[{"html_id":"add(p:Point,q:Point,prime=P):Point-instance-method","name":"add","doc":"Computes the elliptic curve jive addition of point `p(x, y)` and `q(x, y)`.\nIt _draws_ a line between `p` and `q` which will intersect the\ncurve in the point `r` which will be mirrored over the `x`-axis.\n\nParamters:\n* `p` (`Num`): the point `p(x, y)` to be used in the jive addition.\n* `q` (`Num`): the point `q(x, y)` to be used in the jive addition.\n* `prime` (`Num`): the prime number that shapes the field (default `P`).\n\nReturns a `Point` containing the result of the intersection.\n```\np = Point.new Num.new \"5cb1eec17e38b004a8fd90fa8e423432430f60d76c30bb33f4091243c029e86d\"\nq = Point.new Num.new \"7e17f60baa7b8dc8581a55f7be1ea263c6a88452cf3f0a3f710651767654946c\"\nCurve.add p, q\n# => #,\n# @y=#>\n```","summary":"

Computes the elliptic curve jive addition of point p(x, y) and q(x, y).

","abstract":false,"args":[{"name":"p","external_name":"p","restriction":"Point"},{"name":"q","external_name":"q","restriction":"Point"},{"name":"prime","default_value":"P","external_name":"prime","restriction":""}],"args_string":"(p : Point, q : Point, prime = P) : Point","args_html":"(p : Point, q : Point, prime = P) : Point","location":{"filename":"src/secp256k1/curve.cr","line_number":82,"url":null},"def":{"name":"add","args":[{"name":"p","external_name":"p","restriction":"Point"},{"name":"q","external_name":"q","restriction":"Point"},{"name":"prime","default_value":"P","external_name":"prime","restriction":""}],"return_type":"Point","visibility":"Public","body":"if prime.is_a?(Num)\n prime = prime.to_big\nend\np_x = p.x.to_big\np_y = p.y.to_big\nq_x = q.x.to_big\nq_y = q.y.to_big\nx_delta = q_x - p_x\nx_inv = mod_inv(x_delta)\ny_delta = q_y - p_y\nm = (y_delta * x_inv.to_big) % prime\nx = (((m * m) - p_x) - q_x) % prime\ny = ((m * (p_x - x)) - p_y) % prime\nx = Num.new(x)\ny = Num.new(y)\nPoint.new(x, y)\n"}},{"html_id":"double(p:Point,prime=P):Point-instance-method","name":"double","doc":"Computes the elliptic curve juke point doubling of `p(x, y)`.\nThis is a special case of addition where both points are the same.\nIt _draws_ a tangent line at `p` which will intersect the curve\nat point `r` which will be mirrored over the `x`-axis.\n\nParamters:\n* `p` (`Point`): the point `p(x, y)` to be used in the juke doubling.\n* `prime` (`Num`): the prime number that shapes the field (default `P`).\n\nReturns a `Point` as a result of the intersection.\n\n```\np = Point.new Num.new \"5cb1eec17e38b004a8fd90fa8e423432430f60d76c30bb33f4091243c029e86d\"\nCurve.double p\n# => #,\n# @y=#>\n```","summary":"

Computes the elliptic curve juke point doubling of p(x, y).

","abstract":false,"args":[{"name":"p","external_name":"p","restriction":"Point"},{"name":"prime","default_value":"P","external_name":"prime","restriction":""}],"args_string":"(p : Point, prime = P) : Point","args_html":"(p : Point, prime = P) : Point","location":{"filename":"src/secp256k1/curve.cr","line_number":123,"url":null},"def":{"name":"double","args":[{"name":"p","external_name":"p","restriction":"Point"},{"name":"prime","default_value":"P","external_name":"prime","restriction":""}],"return_type":"Point","visibility":"Public","body":"if prime.is_a?(Num)\n prime = prime.to_big\nend\np_x = p.x.to_big\np_y = p.y.to_big\nlam_numer = (3 * p_x) * p_x\nlam_denom = 2 * p_y\nlam_inv = mod_inv(Num.new(lam_denom))\nlam = (lam_numer * lam_inv.to_big) % prime\nx = ((lam * lam) - (2 * p_x)) % prime\ny = ((lam * (p_x - x)) - p_y) % prime\nx = Num.new(x)\ny = Num.new(y)\nPoint.new(x, y)\n"}},{"html_id":"mod_inv(a:Num|BigInt,prime=P):Num-instance-method","name":"mod_inv","doc":"Computes the elliptic curve modular multiplicative inverse of `a`.\n\nParemeters:\n* `a` (`Num | BigInt`): the integer that we want the modular inverse of.\n* `prime` (`Num`): the prime number that shapes the field (default `P`).\n\nReturns a `Num` containing the mod inverse.\n\n```\na = Num.new \"ea678c668356d16d8bf5c69f95c1055e39bd24174605f64846e27c3ae6a88d81\"\nCurve.mod_inv a\n# => #\n```","summary":"

Computes the elliptic curve modular multiplicative inverse of a.

","abstract":false,"args":[{"name":"a","external_name":"a","restriction":"Num | BigInt"},{"name":"prime","default_value":"P","external_name":"prime","restriction":""}],"args_string":"(a : Num | BigInt, prime = P) : Num","args_html":"(a : Num | BigInt, prime = P) : Num","location":{"filename":"src/secp256k1/curve.cr","line_number":37,"url":null},"def":{"name":"mod_inv","args":[{"name":"a","external_name":"a","restriction":"Num | BigInt"},{"name":"prime","default_value":"P","external_name":"prime","restriction":""}],"return_type":"Num","visibility":"Public","body":"if a.is_a?(Num)\n a = a.to_big\nend\nif prime.is_a?(Num)\n prime = prime.to_big\nend\nm_low = 1\nm_high = 0\nv_low = a % prime\nv_high = prime\nwhile v_low > 1\n v_ratio = v_high // v_low\n m_low_r = m_low * v_ratio\n v_low_r = v_low * v_ratio\n m = m_high - m_low_r\n v = v_high - v_low_r\n m_high = m_low\n v_high = v_low\n m_low = m\n v_low = v\nend\nNum.new(m_low % prime)\n"}},{"html_id":"mul(p:Point,s:Num|BigInt):Point-instance-method","name":"mul","doc":"Computes the elliptic curve sequence multiplication of point `p(x, y)`\nand a skalar `s`; with `s` being a private key within the elliptic\ncurve field size of `N`.\n\nParamters:\n* `p` (`Point`): the point `p(x, y)` to be used in the sequencing.\n* `s` (`Num | BigInt`): a skalar, in most cases a private key.\n\nReturns a `Point` as a result of the multiplication.\n\n```\np = Point.new Num.new \"5cb1eec17e38b004a8fd90fa8e423432430f60d76c30bb33f4091243c029e86d\"\ns = Num.new \"f51ad125548b7a283ebf15ab830a25c850d4d863078c48cc9993b79ee18ee11e\"\nCurve.mul p, s\n# => #,\n# @y=#>\n```","summary":"

Computes the elliptic curve sequence multiplication of point p(x, y) and a skalar s; with s being a private key within the elliptic curve field size of N.

","abstract":false,"args":[{"name":"p","external_name":"p","restriction":"Point"},{"name":"s","external_name":"s","restriction":"Num | BigInt"}],"args_string":"(p : Point, s : Num | BigInt) : Point","args_html":"(p : Point, s : Num | BigInt) : Point","location":{"filename":"src/secp256k1/curve.cr","line_number":162,"url":null},"def":{"name":"mul","args":[{"name":"p","external_name":"p","restriction":"Point"},{"name":"s","external_name":"s","restriction":"Num | BigInt"}],"return_type":"Point","visibility":"Public","body":"if s.is_a?(Num)\n s = s.to_big\nend\nif (s === 0) || s >= N.to_big\n raise(\"Invalid scalar: outside of Secp256k1 field dimension.\")\nend\ns_bin = s.to_s(2)\nq = p\ns_bin.each_char_with_index do |char, index|\n if index === 0\n next\n end\n q = double(q)\n if char === '1'\n q = add(q, p)\n end\nend\nq\n"}}]},{"html_id":"secp256k1/Secp256k1/Key","path":"Secp256k1/Key.html","kind":"class","full_name":"Secp256k1::Key","name":"Key","abstract":false,"superclass":{"html_id":"secp256k1/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"secp256k1/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"secp256k1/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/secp256k1/key.cr","line_number":21,"url":null}],"repository_name":"secp256k1","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"secp256k1/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"Provides a `Secp256k1` keypair containing a secret number (private key)\nand a public point on the elliptic curve (public key).\n\nProperties:\n* `private_key` (`Num`): the secret number representing the private key.\n* `public_key` (`Point`): the point on the elliptic curve representing the public key.","summary":"

Provides a Secp256k1 keypair containing a secret number (private key) and a public point on the elliptic curve (public key).

","constructors":[{"html_id":"new(priv:Num)-class-method","name":"new","doc":"Creates a public-private keypair from an existing private key.\n\nParameters:\n* `priv` (`Num`): the private key for the keypair.\n\n```\npriv = Num.new \"3ccf84820c20d5e8c536ba84c52ba410375b29b1812b5f7e722445c969a0fb30\"\nKey.new priv\n# => #,\n# @public_key=#,\n# @y=#>>\n```","summary":"

Creates a public-private keypair from an existing private key.

","abstract":false,"args":[{"name":"priv","external_name":"priv","restriction":"Num"}],"args_string":"(priv : Num)","args_html":"(priv : Num)","location":{"filename":"src/secp256k1/key.cr","line_number":74,"url":null},"def":{"name":"new","args":[{"name":"priv","external_name":"priv","restriction":"Num"}],"visibility":"Public","body":"_ = allocate\n_.initialize(priv)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}},{"html_id":"new-class-method","name":"new","doc":"Creates a new, random `Secp256k1` keypair.\n\n```\nKey.new\n# => #,\n# @public_key=#,\n# @y=#>>\n```","summary":"

Creates a new, random Secp256k1 keypair.

","abstract":false,"location":{"filename":"src/secp256k1/key.cr","line_number":46,"url":null},"def":{"name":"new","visibility":"Public","body":"_ = allocate\n_.initialize\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"html_id":"private_bytes:Bytes-instance-method","name":"private_bytes","doc":"Returns the private key as binary byte slice.\n\n```\nKey.new(Num.new \"3ccf84820c20d5e8c536ba84c52ba410375b29b1812b5f7e722445c969a0fb30\").private_bytes\n# => Bytes[60, 207, 132, 130, 12, 32, 213, 232, 197, 54, 186, 132, 197, 43, 164, 16, 55, 91, 41, 177, 129, 43, 95, 126, 114, 36, 69, 201, 105, 160, 251, 48]\n```","summary":"

Returns the private key as binary byte slice.

","abstract":false,"location":{"filename":"src/secp256k1/key.cr","line_number":95,"url":null},"def":{"name":"private_bytes","return_type":"Bytes","visibility":"Public","body":"@private_key.to_zpadded_bytes"}},{"html_id":"private_hex:String-instance-method","name":"private_hex","doc":"Returns the private key as hexadecimal string literal.\n\n```\nKey.new(Num.new \"3ccf84820c20d5e8c536ba84c52ba410375b29b1812b5f7e722445c969a0fb30\").private_hex\n# => \"3ccf84820c20d5e8c536ba84c52ba410375b29b1812b5f7e722445c969a0fb30\"\n```","summary":"

Returns the private key as hexadecimal string literal.

","abstract":false,"location":{"filename":"src/secp256k1/key.cr","line_number":85,"url":null},"def":{"name":"private_hex","return_type":"String","visibility":"Public","body":"@private_key.to_zpadded_hex"}},{"html_id":"private_key:Num-instance-method","name":"private_key","doc":"The secret number representing the private key.","summary":"

The secret number representing the private key.

","abstract":false,"location":{"filename":"src/secp256k1/key.cr","line_number":23,"url":null},"def":{"name":"private_key","return_type":"Num","visibility":"Public","body":"@private_key"}},{"html_id":"private_key=(private_key:Num)-instance-method","name":"private_key=","doc":"The secret number representing the private key.","summary":"

The secret number representing the private key.

","abstract":false,"args":[{"name":"private_key","external_name":"private_key","restriction":"Num"}],"args_string":"(private_key : Num)","args_html":"(private_key : Num)","location":{"filename":"src/secp256k1/key.cr","line_number":23,"url":null},"def":{"name":"private_key=","args":[{"name":"private_key","external_name":"private_key","restriction":"Num"}],"visibility":"Public","body":"@private_key = private_key"}},{"html_id":"public_bytes:Bytes-instance-method","name":"public_bytes","doc":"Returns the public key as uncompressed, binary byte slice.\n\n```\nKey.new(Num.new \"3ccf84820c20d5e8c536ba84c52ba410375b29b1812b5f7e722445c969a0fb30\").public_bytes\n# => Bytes[4, 205, 74, 135, 18, 238, 110, 252, 21, 181, 171, 227, 124, 13, 191, 169, 121, 216, 156, 66, 125, 63, 226, 75, 7, 96, 8, 222, 206, 254, 148, 219, 162, 129, 54, 61, 41, 142, 74, 64, 235, 203, 19, 241, 175, 168, 90, 11, 148, 185, 103, 242, 67, 238, 89, 165, 144, 16, 203, 93, 234, 240, 215, 182, 108]\n```","summary":"

Returns the public key as uncompressed, binary byte slice.

","abstract":false,"location":{"filename":"src/secp256k1/key.cr","line_number":125,"url":null},"def":{"name":"public_bytes","return_type":"Bytes","visibility":"Public","body":"(Num.new(@public_key.uncompressed)).to_bytes"}},{"html_id":"public_bytes_compressed:Bytes-instance-method","name":"public_bytes_compressed","doc":"Returns the public key as compressed, binary byte slice.\n\n```\nKey.new(Num.new \"3ccf84820c20d5e8c536ba84c52ba410375b29b1812b5f7e722445c969a0fb30\").public_bytes_compressed\n# => Bytes[2, 205, 74, 135, 18, 238, 110, 252, 21, 181, 171, 227, 124, 13, 191, 169, 121, 216, 156, 66, 125, 63, 226, 75, 7, 96, 8, 222, 206, 254, 148, 219, 162]\n```","summary":"

Returns the public key as compressed, binary byte slice.

","abstract":false,"location":{"filename":"src/secp256k1/key.cr","line_number":135,"url":null},"def":{"name":"public_bytes_compressed","return_type":"Bytes","visibility":"Public","body":"(Num.new(@public_key.compressed)).to_bytes"}},{"html_id":"public_hex:String-instance-method","name":"public_hex","doc":"Returns the public key as uncompressed, hexadecimal string literal.\n\n```\nKey.new(Num.new \"3ccf84820c20d5e8c536ba84c52ba410375b29b1812b5f7e722445c969a0fb30\").public_hex\n# => \"04cd4a8712ee6efc15b5abe37c0dbfa979d89c427d3fe24b076008decefe94dba281363d298e4a40ebcb13f1afa85a0b94b967f243ee59a59010cb5deaf0d7b66c\"\n```","summary":"

Returns the public key as uncompressed, hexadecimal string literal.

","abstract":false,"location":{"filename":"src/secp256k1/key.cr","line_number":105,"url":null},"def":{"name":"public_hex","return_type":"String","visibility":"Public","body":"@public_key.uncompressed"}},{"html_id":"public_hex_compressed:String-instance-method","name":"public_hex_compressed","doc":"Returns the public key as compressed, hexadecimal string literal.\n\n```\nKey.new(Num.new \"3ccf84820c20d5e8c536ba84c52ba410375b29b1812b5f7e722445c969a0fb30\").public_hex_compressed\n# => \"02cd4a8712ee6efc15b5abe37c0dbfa979d89c427d3fe24b076008decefe94dba2\"\n```","summary":"

Returns the public key as compressed, hexadecimal string literal.

","abstract":false,"location":{"filename":"src/secp256k1/key.cr","line_number":115,"url":null},"def":{"name":"public_hex_compressed","return_type":"String","visibility":"Public","body":"@public_key.compressed"}},{"html_id":"public_key:Point-instance-method","name":"public_key","doc":"The point on the elliptic curve representing the public key.","summary":"

The point on the elliptic curve representing the public key.

","abstract":false,"location":{"filename":"src/secp256k1/key.cr","line_number":25,"url":null},"def":{"name":"public_key","return_type":"Point","visibility":"Public","body":"@public_key"}},{"html_id":"public_key=(public_key:Point)-instance-method","name":"public_key=","doc":"The point on the elliptic curve representing the public key.","summary":"

The point on the elliptic curve representing the public key.

","abstract":false,"args":[{"name":"public_key","external_name":"public_key","restriction":"Point"}],"args_string":"(public_key : Point)","args_html":"(public_key : Point)","location":{"filename":"src/secp256k1/key.cr","line_number":25,"url":null},"def":{"name":"public_key=","args":[{"name":"public_key","external_name":"public_key","restriction":"Point"}],"visibility":"Public","body":"@public_key = public_key"}}]},{"html_id":"secp256k1/Secp256k1/Num","path":"Secp256k1/Num.html","kind":"class","full_name":"Secp256k1::Num","name":"Num","abstract":false,"superclass":{"html_id":"secp256k1/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"secp256k1/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"secp256k1/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/secp256k1/num.cr","line_number":25,"url":null}],"repository_name":"secp256k1","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"secp256k1/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"Provides a class to conveniently handle big numbers on the elliptic\ncurve. It allows to easily access decimal, hexadecimal, and binary\nrepresentations of the numeric. In addition, it implements some\nutilities such as zpadding or asserting hexadecimal strings. It's suited\nto temporarily handle unencrypted private keys.\n\nProperties:\n* `hex` (`String`): the hexadecimal string representation of the number.\n* `dec` (`BigInt`): the decimal big-integer representation of the number.\n* `bin` (`Bytes`): the binary bytes-slice represenation of the number.","summary":"

Provides a class to conveniently handle big numbers on the elliptic curve.

","constructors":[{"html_id":"new(hex:String)-class-method","name":"new","doc":"Creates a number from a hexadecimal string literal.\n\nParameters:\n* `hex` (`String`): a hexadecimal string representating the number.\n\n```\nNum.new \"568a0f505bde902db4a6afd207c794c7845fe7715da5999bb276d453c702a46d\"\n# => #\n```","summary":"

Creates a number from a hexadecimal string literal.

","abstract":false,"args":[{"name":"hex","external_name":"hex","restriction":"String"}],"args_string":"(hex : String)","args_html":"(hex : String)","location":{"filename":"src/secp256k1/num.cr","line_number":67,"url":null},"def":{"name":"new","args":[{"name":"hex","external_name":"hex","restriction":"String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(hex)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}},{"html_id":"new(num:BigInt)-class-method","name":"new","doc":"Creates a number from a big integer numeric.\n\nParameters:\n* `dec` (`BigInt`): the decimal big-integer representating the number.\n\n```\nNum.new BigInt.new \"39142835565766237398843902819171565157710677457569850027793715608438337348717\"\n# => #\n```","summary":"

Creates a number from a big integer numeric.

","abstract":false,"args":[{"name":"num","external_name":"num","restriction":"BigInt"}],"args_string":"(num : BigInt)","args_html":"(num : BigInt)","location":{"filename":"src/secp256k1/num.cr","line_number":87,"url":null},"def":{"name":"new","args":[{"name":"num","external_name":"num","restriction":"BigInt"}],"visibility":"Public","body":"_ = allocate\n_.initialize(num)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}},{"html_id":"new(bin:Slice(UInt8))-class-method","name":"new","doc":"Creates a number from a binary bytes slice.\n\nParameters:\n* `bin` (`Bytes`): the binary bytes-slice represenating the number.\n\n```\nNum.new Bytes[86, 138, 15, 80, 91, 222, 144, 45, 180, 166, 175, 210, 7, 199, 148, 199, 132, 95, 231, 113, 93, 165, 153, 155, 178, 118, 212, 83, 199, 2, 164, 109]\n# => #\n```","summary":"

Creates a number from a binary bytes slice.

","abstract":false,"args":[{"name":"bin","external_name":"bin","restriction":"Slice(UInt8)"}],"args_string":"(bin : Slice(UInt8))","args_html":"(bin : Slice(UInt8))","location":{"filename":"src/secp256k1/num.cr","line_number":107,"url":null},"def":{"name":"new","args":[{"name":"bin","external_name":"bin","restriction":"Slice(UInt8)"}],"visibility":"Public","body":"_ = allocate\n_.initialize(bin)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}},{"html_id":"new-class-method","name":"new","doc":"Creates a random number using `Random::Secure` that can be used as\na secret (private key).\n\n```\nNum.new\n# => #\n```","summary":"

Creates a random number using Random::Secure that can be used as a secret (private key).

","abstract":false,"location":{"filename":"src/secp256k1/num.cr","line_number":43,"url":null},"def":{"name":"new","visibility":"Public","body":"_ = allocate\n_.initialize\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"html_id":"bin:Slice(UInt8)-instance-method","name":"bin","doc":"The binary bytes-slice represenation of the number.","summary":"

The binary bytes-slice represenation of the number.

","abstract":false,"location":{"filename":"src/secp256k1/num.cr","line_number":31,"url":null},"def":{"name":"bin","return_type":"Slice(UInt8)","visibility":"Public","body":"@bin"}},{"html_id":"bin=(bin:Slice(UInt8))-instance-method","name":"bin=","doc":"The binary bytes-slice represenation of the number.","summary":"

The binary bytes-slice represenation of the number.

","abstract":false,"args":[{"name":"bin","external_name":"bin","restriction":"Slice(UInt8)"}],"args_string":"(bin : Slice(UInt8))","args_html":"(bin : Slice(UInt8))","location":{"filename":"src/secp256k1/num.cr","line_number":31,"url":null},"def":{"name":"bin=","args":[{"name":"bin","external_name":"bin","restriction":"Slice(UInt8)"}],"visibility":"Public","body":"@bin = bin"}},{"html_id":"dec:BigInt-instance-method","name":"dec","doc":"The decimal big-integer representation of the number.","summary":"

The decimal big-integer representation of the number.

","abstract":false,"location":{"filename":"src/secp256k1/num.cr","line_number":29,"url":null},"def":{"name":"dec","return_type":"BigInt","visibility":"Public","body":"@dec"}},{"html_id":"dec=(dec:BigInt)-instance-method","name":"dec=","doc":"The decimal big-integer representation of the number.","summary":"

The decimal big-integer representation of the number.

","abstract":false,"args":[{"name":"dec","external_name":"dec","restriction":"BigInt"}],"args_string":"(dec : BigInt)","args_html":"(dec : BigInt)","location":{"filename":"src/secp256k1/num.cr","line_number":29,"url":null},"def":{"name":"dec=","args":[{"name":"dec","external_name":"dec","restriction":"BigInt"}],"visibility":"Public","body":"@dec = dec"}},{"html_id":"hex:String-instance-method","name":"hex","doc":"The hexadecimal string representation of the number.","summary":"

The hexadecimal string representation of the number.

","abstract":false,"location":{"filename":"src/secp256k1/num.cr","line_number":27,"url":null},"def":{"name":"hex","return_type":"String","visibility":"Public","body":"@hex"}},{"html_id":"hex=(hex:String)-instance-method","name":"hex=","doc":"The hexadecimal string representation of the number.","summary":"

The hexadecimal string representation of the number.

","abstract":false,"args":[{"name":"hex","external_name":"hex","restriction":"String"}],"args_string":"(hex : String)","args_html":"(hex : String)","location":{"filename":"src/secp256k1/num.cr","line_number":27,"url":null},"def":{"name":"hex=","args":[{"name":"hex","external_name":"hex","restriction":"String"}],"visibility":"Public","body":"@hex = hex"}},{"html_id":"to_big:BigInt-instance-method","name":"to_big","doc":"Returns a big-integer representation of the number.\n\n```\nNum.new(Bytes[137]).to_big\n# => 137\n```","summary":"

Returns a big-integer representation of the number.

","abstract":false,"location":{"filename":"src/secp256k1/num.cr","line_number":156,"url":null},"def":{"name":"to_big","return_type":"BigInt","visibility":"Public","body":"@dec"}},{"html_id":"to_bytes:Bytes-instance-method","name":"to_bytes","doc":"Returns a binary byte-slice representation of the number.\n\n```\nNum.new(\"0x89\").to_bytes\n# => Bytes[137]\n```","summary":"

Returns a binary byte-slice representation of the number.

","abstract":false,"location":{"filename":"src/secp256k1/num.cr","line_number":166,"url":null},"def":{"name":"to_bytes","return_type":"Bytes","visibility":"Public","body":"@bin"}},{"html_id":"to_hex:String-instance-method","name":"to_hex","doc":"Returns an unprefixed hexadecimal string representation.\n\n```\nNum.new(Bytes[137]).to_hex\n# => \"89\"\n```","summary":"

Returns an unprefixed hexadecimal string representation.

","abstract":false,"location":{"filename":"src/secp256k1/num.cr","line_number":119,"url":null},"def":{"name":"to_hex","return_type":"String","visibility":"Public","body":"@hex"}},{"html_id":"to_prefixed_hex:String-instance-method","name":"to_prefixed_hex","doc":"Returns an `0x`-prefixed hexadecimal string representation.\n\n```\nNum.new(Bytes[137]).to_prefixed_hex\n# => \"0x89\"\n```","summary":"

Returns an 0x-prefixed hexadecimal string representation.

","abstract":false,"location":{"filename":"src/secp256k1/num.cr","line_number":129,"url":null},"def":{"name":"to_prefixed_hex","return_type":"String","visibility":"Public","body":"\"0x#{@hex}\""}},{"html_id":"to_zpadded_bytes(length=32):Bytes-instance-method","name":"to_zpadded_bytes","doc":"Returns a z-padded byte-slice binary representation.\n\nParameters:\n* `length` (`Int`): the byte-size of the final z-padded slice (default `32`).\n\n```\nNum.new(Bytes[137]).to_zpadded_bytes\n# => Bytes[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 137]\n```","summary":"

Returns a z-padded byte-slice binary representation.

","abstract":false,"args":[{"name":"length","default_value":"32","external_name":"length","restriction":""}],"args_string":"(length = 32) : Bytes","args_html":"(length = 32) : Bytes","location":{"filename":"src/secp256k1/num.cr","line_number":179,"url":null},"def":{"name":"to_zpadded_bytes","args":[{"name":"length","default_value":"32","external_name":"length","restriction":""}],"return_type":"Bytes","visibility":"Public","body":"zpadded_bytes = @bin\nbyte_zero = Bytes[0]\nwhile zpadded_bytes.size < length\n slice_size = zpadded_bytes.size + 1\n zpadded_slice = Slice(UInt8).new(slice_size)\n slice_pointer = zpadded_slice.to_unsafe\n byte_zero.copy_to(slice_pointer, 0)\n slice_pointer = slice_pointer + 1\n zpadded_bytes.copy_to(slice_pointer, zpadded_bytes.size)\n zpadded_bytes = zpadded_slice\nend\nzpadded_bytes\n"}},{"html_id":"to_zpadded_hex(length=32):String-instance-method","name":"to_zpadded_hex","doc":"Returns a z-padded hexadecimal string representation.\n\nParameters:\n* `length` (`Int`): the byte-size of the final z-padded hex-string (default `32`).\n\n```\nNum.new(Bytes[137]).to_zpadded_hex\n# => \"0000000000000000000000000000000000000000000000000000000000000089\"\n```","summary":"

Returns a z-padded hexadecimal string representation.

","abstract":false,"args":[{"name":"length","default_value":"32","external_name":"length","restriction":""}],"args_string":"(length = 32) : String","args_html":"(length = 32) : String","location":{"filename":"src/secp256k1/num.cr","line_number":142,"url":null},"def":{"name":"to_zpadded_hex","args":[{"name":"length","default_value":"32","external_name":"length","restriction":""}],"return_type":"String","visibility":"Public","body":"zpadded_hex = @hex\nwhile zpadded_hex.size < (length * 2)\n zpadded_hex = \"0#{zpadded_hex}\"\nend\nzpadded_hex\n"}}]},{"html_id":"secp256k1/Secp256k1/Point","path":"Secp256k1/Point.html","kind":"class","full_name":"Secp256k1::Point","name":"Point","abstract":false,"superclass":{"html_id":"secp256k1/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"secp256k1/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"secp256k1/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/secp256k1/point.cr","line_number":30,"url":null}],"repository_name":"secp256k1","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"secp256k1/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"Provides a point in the two-dimensional space of any elliptic curve.\nIn most cases, such a point on a given curve represents a public key.\nHowever, for keypairs, a `Key` type shall be used!\n\nProperties:\n* `x` (`Num`): the position on the x-axis.\n* `y` (`Num`): the position on the y-axis.","summary":"

Provides a point in the two-dimensional space of any elliptic curve.

","constructors":[{"html_id":"new(x:Num,y:Num)-class-method","name":"new","doc":"Provides a public point in the two-dimensional space on the given `Secp256k1`\nelliptic curve by passing the x- and y-coordinates (public key).\n\nParameters:\n* `x` (`Num`): the position on the x-axis.\n* `y` (`Num`): the position on the y-axis.\n\n```\nx = Num.new \"efc4f8d8bfc778463e4d4916d88bf3f057e6dc96cb2adc26dfb91959c4bef4a5\"\ny = Num.new \"cecd9a83fefafcb3cf99fde0c340bbe2fed9cdd0d25b53f4e08254acefb69ae0\"\nPoint.new x, y\n# => #,\n# @y=#>\n```","summary":"

Provides a public point in the two-dimensional space on the given Secp256k1 elliptic curve by passing the x- and y-coordinates (public key).

","abstract":false,"args":[{"name":"x","external_name":"x","restriction":"Num"},{"name":"y","external_name":"y","restriction":"Num"}],"args_string":"(x : Num, y : Num)","args_html":"(x : Num, y : Num)","location":{"filename":"src/secp256k1/point.cr","line_number":58,"url":null},"def":{"name":"new","args":[{"name":"x","external_name":"x","restriction":"Num"},{"name":"y","external_name":"y","restriction":"Num"}],"visibility":"Public","body":"_ = allocate\n_.initialize(x, y)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}},{"html_id":"new(priv:Num)-class-method","name":"new","doc":"Provides a public point in the two-dimensional space on the given `Secp256k1`\nelliptic curve by passing a random number (private key). Note, that the\nprivate key will be consumed by this constructor and should only be used\nto retrieve a public key. To manage keypairs, use the `Key` type instead.\n\nParameters:\n* `priv` (`Num`): the random number giving access to the point.\n\n```\npriv = Num.new \"e50932676c9901f259659d62f0c56fd899feca3f57ecab147a5ef8a0b59defc3\"\nPoint.new priv\n# => #,\n# @y=#>\n```","summary":"

Provides a public point in the two-dimensional space on the given Secp256k1 elliptic curve by passing a random number (private key).

","abstract":false,"args":[{"name":"priv","external_name":"priv","restriction":"Num"}],"args_string":"(priv : Num)","args_html":"(priv : Num)","location":{"filename":"src/secp256k1/point.cr","line_number":84,"url":null},"def":{"name":"new","args":[{"name":"priv","external_name":"priv","restriction":"Num"}],"visibility":"Public","body":"_ = allocate\n_.initialize(priv)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}},{"html_id":"new(pub:String)-class-method","name":"new","doc":"Provides a public point in the two-dimensional space on the given `Secp256k1`\nelliptic curve by passing a compressed or uncompressed public key.\n\nParameters:\n* `pub` (`String`): the public key string (compressed or uncompressed).\n\n```\npub = \"03aff8674d6b96a6c58dbab08b903565363271308888340a2caddf88e56165930f\"\nPoint.new pub\n# => #,\n# @y=#>\n```","summary":"

Provides a public point in the two-dimensional space on the given Secp256k1 elliptic curve by passing a compressed or uncompressed public key.

","abstract":false,"args":[{"name":"pub","external_name":"pub","restriction":"String"}],"args_string":"(pub : String)","args_html":"(pub : String)","location":{"filename":"src/secp256k1/point.cr","line_number":109,"url":null},"def":{"name":"new","args":[{"name":"pub","external_name":"pub","restriction":"String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(pub)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"html_id":"compressed:String-instance-method","name":"compressed","doc":"Returns a prefixed, compressed public key string for the given point\nin the format `prefix|x|y`.\n\n```\npriv = Num.new \"e50932676c9901f259659d62f0c56fd899feca3f57ecab147a5ef8a0b59defc3\"\nPoint.new(priv).compressed\n# => \"03aff8674d6b96a6c58dbab08b903565363271308888340a2caddf88e56165930f\"\n```","summary":"

Returns a prefixed, compressed public key string for the given point in the format prefix|x|y.

","abstract":false,"location":{"filename":"src/secp256k1/point.cr","line_number":161,"url":null},"def":{"name":"compressed","return_type":"String","visibility":"Public","body":"prefix = 2 + (@y.to_big % 2)\nprefix = \"0#{prefix}\"\n\"#{prefix}#{@x.to_zpadded_hex}\"\n"}},{"html_id":"uncompressed:String-instance-method","name":"uncompressed","doc":"Returns a prefixed, uncompressed public key string for the given point\nin the format `04|x|y`.\n\n```\npriv = Num.new \"e50932676c9901f259659d62f0c56fd899feca3f57ecab147a5ef8a0b59defc3\"\nPoint.new(priv).uncompressed\n# => \"04aff8674d6b96a6c58dbab08b903565363271308888340a2caddf88e56165930f21f4c49cfe90da39c254a51b8ee8afcdd8c02dd566f13582c23e104c7ed5936b\"\n```","summary":"

Returns a prefixed, uncompressed public key string for the given point in the format 04|x|y.

","abstract":false,"location":{"filename":"src/secp256k1/point.cr","line_number":148,"url":null},"def":{"name":"uncompressed","return_type":"String","visibility":"Public","body":"prefix = \"04\"\n\"#{prefix}#{@x.to_zpadded_hex}#{@y.to_zpadded_hex}\"\n"}},{"html_id":"x:Num-instance-method","name":"x","doc":"The position on the x-axis.","summary":"

The position on the x-axis.

","abstract":false,"location":{"filename":"src/secp256k1/point.cr","line_number":32,"url":null},"def":{"name":"x","return_type":"Num","visibility":"Public","body":"@x"}},{"html_id":"x=(x:Num)-instance-method","name":"x=","doc":"The position on the x-axis.","summary":"

The position on the x-axis.

","abstract":false,"args":[{"name":"x","external_name":"x","restriction":"Num"}],"args_string":"(x : Num)","args_html":"(x : Num)","location":{"filename":"src/secp256k1/point.cr","line_number":32,"url":null},"def":{"name":"x=","args":[{"name":"x","external_name":"x","restriction":"Num"}],"visibility":"Public","body":"@x = x"}},{"html_id":"y:Num-instance-method","name":"y","doc":"The position on the y-axis.","summary":"

The position on the y-axis.

","abstract":false,"location":{"filename":"src/secp256k1/point.cr","line_number":35,"url":null},"def":{"name":"y","return_type":"Num","visibility":"Public","body":"@y"}},{"html_id":"y=(y:Num)-instance-method","name":"y=","doc":"The position on the y-axis.","summary":"

The position on the y-axis.

","abstract":false,"args":[{"name":"y","external_name":"y","restriction":"Num"}],"args_string":"(y : Num)","args_html":"(y : Num)","location":{"filename":"src/secp256k1/point.cr","line_number":35,"url":null},"def":{"name":"y=","args":[{"name":"y","external_name":"y","restriction":"Num"}],"visibility":"Public","body":"@y = y"}}]},{"html_id":"secp256k1/Secp256k1/Signature","path":"Secp256k1/Signature.html","kind":"class","full_name":"Secp256k1::Signature","name":"Signature","abstract":false,"superclass":{"html_id":"secp256k1/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"secp256k1/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"secp256k1/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/secp256k1/signature.cr","line_number":22,"url":null}],"repository_name":"secp256k1","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"secp256k1/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"Provides an ECDSA Signature containing the random point `r`, the\nsignature proof `s`, and the recovery id or `v` value.\n\nProperties:\n* `r` (`Num`): the `x` coordinate of a random point `R` on the curve.\n* `s` (`Num`): the signature proof of a message.\n* `v` (`Num`): the recovery id or `v` value.","summary":"

Provides an ECDSA Signature containing the random point #r, the signature proof #s, and the recovery id or #v value.

","constructors":[{"html_id":"new(r:Num,s:Num,v:Num)-class-method","name":"new","doc":"Provides an ECDSA Signature containing the random point `r`, the\nsignature proof `s`, and the recovery id or `v` value.\n\nParameters:\n* `r` (`Num`): the `x` coordinate of a random point `R` on the curve.\n* `s` (`Num`): the signature proof of a message.\n* `v` (`Num`): the recovery id or `v` value.\n\n```\nr = Num.new \"efc4f8d8bfc778463e4d4916d88bf3f057e6dc96cb2adc26dfb91959c4bef4a5\"\ns = Num.new \"cecd9a83fefafcb3cf99fde0c340bbe2fed9cdd0d25b53f4e08254acefb69ae0\"\nv = Num.new \"00\"\nSignature.new r, s, v\n# => #,\n# @s=#,\n# @v=#>\n```","summary":"

Provides an ECDSA Signature containing the random point #r, the signature proof #s, and the recovery id or #v value.

","abstract":false,"args":[{"name":"r","external_name":"r","restriction":"Num"},{"name":"s","external_name":"s","restriction":"Num"},{"name":"v","external_name":"v","restriction":"Num"}],"args_string":"(r : Num, s : Num, v : Num)","args_html":"(r : Num, s : Num, v : Num)","location":{"filename":"src/secp256k1/signature.cr","line_number":59,"url":null},"def":{"name":"new","args":[{"name":"r","external_name":"r","restriction":"Num"},{"name":"s","external_name":"s","restriction":"Num"},{"name":"v","external_name":"v","restriction":"Num"}],"visibility":"Public","body":"_ = allocate\n_.initialize(r, s, v)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"html_id":"compact:String-instance-method","name":"compact","doc":"Returns a compact `String` containing the concatenated signature\nin the form `r|s|v`.\n\n```\nr = Num.new \"efc4f8d8bfc778463e4d4916d88bf3f057e6dc96cb2adc26dfb91959c4bef4a5\"\ns = Num.new \"cecd9a83fefafcb3cf99fde0c340bbe2fed9cdd0d25b53f4e08254acefb69ae0\"\nv = Num.new \"00\"\nSignature.new(r, s, v).compact\n# => \"efc4f8d8bfc778463e4d4916d88bf3f057e6dc96cb2adc26dfb91959c4bef4a5cecd9a83fefafcb3cf99fde0c340bbe2fed9cdd0d25b53f4e08254acefb69ae000\"\n```","summary":"

Returns a compact String containing the concatenated signature in the form r|s|v.

","abstract":false,"location":{"filename":"src/secp256k1/signature.cr","line_number":75,"url":null},"def":{"name":"compact","return_type":"String","visibility":"Public","body":"\"#{r.to_zpadded_hex}#{s.to_zpadded_hex}#{v.to_hex}\""}},{"html_id":"r:Num-instance-method","name":"r","doc":"The `x` coordinate of a random point `R` on the curve.","summary":"

The x coordinate of a random point R on the curve.

","abstract":false,"location":{"filename":"src/secp256k1/signature.cr","line_number":24,"url":null},"def":{"name":"r","return_type":"Num","visibility":"Public","body":"@r"}},{"html_id":"r=(r:Num)-instance-method","name":"r=","doc":"The `x` coordinate of a random point `R` on the curve.","summary":"

The x coordinate of a random point R on the curve.

","abstract":false,"args":[{"name":"r","external_name":"r","restriction":"Num"}],"args_string":"(r : Num)","args_html":"(r : Num)","location":{"filename":"src/secp256k1/signature.cr","line_number":24,"url":null},"def":{"name":"r=","args":[{"name":"r","external_name":"r","restriction":"Num"}],"visibility":"Public","body":"@r = r"}},{"html_id":"s:Num-instance-method","name":"s","doc":"The signature proof of a message.","summary":"

The signature proof of a message.

","abstract":false,"location":{"filename":"src/secp256k1/signature.cr","line_number":27,"url":null},"def":{"name":"s","return_type":"Num","visibility":"Public","body":"@s"}},{"html_id":"s=(s:Num)-instance-method","name":"s=","doc":"The signature proof of a message.","summary":"

The signature proof of a message.

","abstract":false,"args":[{"name":"s","external_name":"s","restriction":"Num"}],"args_string":"(s : Num)","args_html":"(s : Num)","location":{"filename":"src/secp256k1/signature.cr","line_number":27,"url":null},"def":{"name":"s=","args":[{"name":"s","external_name":"s","restriction":"Num"}],"visibility":"Public","body":"@s = s"}},{"html_id":"v:Num-instance-method","name":"v","doc":"The recovery id or `v` value.","summary":"

The recovery id or #v value.

","abstract":false,"location":{"filename":"src/secp256k1/signature.cr","line_number":30,"url":null},"def":{"name":"v","return_type":"Num","visibility":"Public","body":"@v"}},{"html_id":"v=(v:Num)-instance-method","name":"v=","doc":"The recovery id or `v` value.","summary":"

The recovery id or #v value.

","abstract":false,"args":[{"name":"v","external_name":"v","restriction":"Num"}],"args_string":"(v : Num)","args_html":"(v : Num)","location":{"filename":"src/secp256k1/signature.cr","line_number":30,"url":null},"def":{"name":"v=","args":[{"name":"v","external_name":"v","restriction":"Num"}],"visibility":"Public","body":"@v = v"}}]},{"html_id":"secp256k1/Secp256k1/Util","path":"Secp256k1/Util.html","kind":"module","full_name":"Secp256k1::Util","name":"Util","abstract":false,"locations":[{"filename":"src/secp256k1/util.cr","line_number":17,"url":null}],"repository_name":"secp256k1","program":false,"enum":false,"alias":false,"const":false,"extended_modules":[{"html_id":"secp256k1/Secp256k1/Util","kind":"module","full_name":"Secp256k1::Util","name":"Util"}],"namespace":{"html_id":"secp256k1/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"Provides a collection of utilities for convenience, e.g., to bind\nrelevant hashing algorithms, or to concatenate byte slices.","summary":"

Provides a collection of utilities for convenience, e.g., to bind relevant hashing algorithms, or to concatenate byte slices.

","instance_methods":[{"html_id":"concat_bytes(x:Bytes,y:Bytes):Bytes-instance-method","name":"concat_bytes","doc":"Concatenates two byte slices in the order provided, i.e., `x|y`.\n\nParameters:\n* `x` (`Bytes`): a byte slice.\n* `y` (`Bytes`): another byte slice.\n\nReturns a concatenated `Bytes` slice.\n\n```\nUtil.concat_bytes Bytes[1, 2, 3], Bytes[9, 8, 7]\n# => Bytes[1, 2, 3, 9, 8, 7]\n```","summary":"

Concatenates two byte slices in the order provided, i.e., x|y.

","abstract":false,"args":[{"name":"x","external_name":"x","restriction":"Bytes"},{"name":"y","external_name":"y","restriction":"Bytes"}],"args_string":"(x : Bytes, y : Bytes) : Bytes","args_html":"(x : Bytes, y : Bytes) : Bytes","location":{"filename":"src/secp256k1/util.cr","line_number":177,"url":null},"def":{"name":"concat_bytes","args":[{"name":"x","external_name":"x","restriction":"Bytes"},{"name":"y","external_name":"y","restriction":"Bytes"}],"return_type":"Bytes","visibility":"Public","body":"z = IO::Memory.new(x.bytesize + y.bytesize)\nx.each do |b|\n z.write_bytes(UInt8.new(b))\nend\ny.each do |b|\n z.write_bytes(UInt8.new(b))\nend\nreturn z.to_slice\n"}},{"html_id":"deterministic_k(priv:Num,hash:Num,order=N):Num-instance-method","name":"deterministic_k","doc":"Provides a deterministic secret based on private key and message hash\nas defined in RFC-6979.\n\nRef: [datatracker.ietf.org/doc/html/rfc6979](https://datatracker.ietf.org/doc/html/rfc6979)\n\nParameters:\n* `priv` (`Num`): the private key or secret number.\n* `hash` (`Num`): the message hash or arbirtrary data hash.\n* `order` (`Num`): the order of the curve over `G` (default `N`).\n\nReturns a deterministically random number of type `Num`.\n\n```\npriv = Num.new \"3b74fcc0b0c419a00d2d9e88b15fbd99e03920138da22e2a00c327b88d24cf45\"\nhash = Util.sha256 \"Henlo, Wordl\"\nUtil.deterministic_k(priv, hash)\n# => #\n```","summary":"

Provides a deterministic secret based on private key and message hash as defined in RFC-6979.

","abstract":false,"args":[{"name":"priv","external_name":"priv","restriction":"Num"},{"name":"hash","external_name":"hash","restriction":"Num"},{"name":"order","default_value":"N","external_name":"order","restriction":""}],"args_string":"(priv : Num, hash : Num, order = N) : Num","args_html":"(priv : Num, hash : Num, order = N) : Num","location":{"filename":"src/secp256k1/util.cr","line_number":135,"url":null},"def":{"name":"deterministic_k","args":[{"name":"priv","external_name":"priv","restriction":"Num"},{"name":"hash","external_name":"hash","restriction":"Num"},{"name":"order","default_value":"N","external_name":"order","restriction":""}],"return_type":"Num","visibility":"Public","body":"order_size = order.hex.size // 2\nv = Num.new(Bytes.new(order_size, 1))\nk = Num.new(Bytes.new(order_size, 0))\nconcat = Util.concat_bytes(v.bin, Bytes[0])\nconcat = Util.concat_bytes(concat, priv.bin)\nconcat = Util.concat_bytes(concat, hash.bin)\nk = OpenSSL::HMAC.digest(:sha256, k.bin, concat)\nv = OpenSSL::HMAC.digest(:sha256, k, v.bin)\nconcat = Util.concat_bytes(v, Bytes[0])\nconcat = Util.concat_bytes(concat, priv.bin)\nconcat = Util.concat_bytes(concat, hash.bin)\nk = OpenSSL::HMAC.digest(:sha256, k, concat)\nv = OpenSSL::HMAC.digest(:sha256, k, v)\nwhile true\n t = IO::Memory.new.to_slice\n while t.size < order_size\n v = OpenSSL::HMAC.digest(:sha256, k, v)\n t = Util.concat_bytes(t, v)\n end\n secret = Num.new(t)\n if secret.dec < order.dec && secret.dec > 0\n return secret\n end\n increment = Util.concat_bytes(v, Bytes[0])\n k = OpenSSL::HMAC.digest(:sha256, k, increment)\n v = OpenSSL::HMAC.digest(:sha256, k, v)\nend\n"}},{"html_id":"keccak(data:Num|String,entropy=256):Num-instance-method","name":"keccak","doc":"Operating a Keccak hash on a binary/number or string literal.\n\nParameters:\n* `data` (`Num | String`): the binary numeric or string literal to be hashed.\n* `entropy` (`Int32`): the required entropy (default `256`).\n\nReturns a `Num` representing the Keccak hash.\n\n```\nUtil.keccak(Num.new \"0xdeadbeef\").hex\n# => \"d4fd4e189132273036449fc9e11198c739161b4c0116a9a2dccdfa1c492006f1\"\n\nUtil.keccak(\"0xdeadbeef\").hex\n# => \"4f440a001006a49f24a7de53c04eca3f79aef851ac58e460c9630d044277c8b0\"\n```","summary":"

Operating a Keccak hash on a binary/number or string literal.

","abstract":false,"args":[{"name":"data","external_name":"data","restriction":"Num | String"},{"name":"entropy","default_value":"256","external_name":"entropy","restriction":""}],"args_string":"(data : Num | String, entropy = 256) : Num","args_html":"(data : Num | String, entropy = 256) : Num","location":{"filename":"src/secp256k1/util.cr","line_number":35,"url":null},"def":{"name":"keccak","args":[{"name":"data","external_name":"data","restriction":"Num | String"},{"name":"entropy","default_value":"256","external_name":"entropy","restriction":""}],"return_type":"Num","visibility":"Public","body":"keccak = Digest::Keccak3.new(entropy)\nif data.is_a?(String)\n return Num.new((keccak.update(data)).hexdigest)\nelse\n return Num.new((keccak.update(data.to_bytes)).hexdigest)\nend\n"}},{"html_id":"ripemd160(data:Num|String):Num-instance-method","name":"ripemd160","doc":"Operating a RIPEMD-160 hash on a binary/number or string literal.\n\nParameters:\n* `data` (`Num | String`): the binary numeric or string literal to be hashed.\n\nReturns a `Num` representing the RIPEMD hash.\n\n```\nUtil.ripemd160(Num.new \"0xdeadbeef\").hex\n# => \"226821c2f5423e11fe9af68bd285c249db2e4b5a\"\n\nUtil.ripemd160(\"0xdeadbeef\").hex\n# => \"4caf817f14e84b564e47afd19966e5d123ee0183\"\n```","summary":"

Operating a RIPEMD-160 hash on a binary/number or string literal.

","abstract":false,"args":[{"name":"data","external_name":"data","restriction":"Num | String"}],"args_string":"(data : Num | String) : Num","args_html":"(data : Num | String) : Num","location":{"filename":"src/secp256k1/util.cr","line_number":105,"url":null},"def":{"name":"ripemd160","args":[{"name":"data","external_name":"data","restriction":"Num | String"}],"return_type":"Num","visibility":"Public","body":"ripemd = OpenSSL::Digest.new(\"RIPEMD160\")\nif data.is_a?(String)\n return Num.new((ripemd.update(data)).final.hexstring)\nelse\n return Num.new((ripemd.update(data.to_bytes)).final.hexstring)\nend\n"}},{"html_id":"sha256(data:Num|String):Num-instance-method","name":"sha256","doc":"Operating a SHA2-256 hash on a binary/number or string literal.\n\nParameters:\n* `data` (`Num | String`): the binary numeric or string literal to be hashed.\n\nReturns a `Num` representing the SHA2 hash.\n\n```\nUtil.sha256(Num.new \"0xdeadbeef\").hex\n# => \"5f78c33274e43fa9de5659265c1d917e25c03722dcb0b8d27db8d5feaa813953\"\n\nUtil.sha256(\"0xdeadbeef\").hex\n# => \"4142710b9b4caaeb000b8e5de271bbebac7f509aab2f5e61d1ed1958bfe6d583\"\n```","summary":"

Operating a SHA2-256 hash on a binary/number or string literal.

","abstract":false,"args":[{"name":"data","external_name":"data","restriction":"Num | String"}],"args_string":"(data : Num | String) : Num","args_html":"(data : Num | String) : Num","location":{"filename":"src/secp256k1/util.cr","line_number":82,"url":null},"def":{"name":"sha256","args":[{"name":"data","external_name":"data","restriction":"Num | String"}],"return_type":"Num","visibility":"Public","body":"sha2 = OpenSSL::Digest.new(\"SHA256\")\nif data.is_a?(String)\n return Num.new((sha2.update(data)).final.hexstring)\nelse\n return Num.new((sha2.update(data.to_bytes)).final.hexstring)\nend\n"}},{"html_id":"sha3(data:Num|String,entropy=256):Num-instance-method","name":"sha3","doc":"Operating a SHA3 hash on a binary/number or string literal.\n\nParameters:\n* `data` (`Num | String`): the binary numeric or string literal to be hashed.\n* `entropy` (`Int32`): the required entropy (default `256`).\n\nReturns a `Num` representing the SHA3 hash.\n\n```\nUtil.sha3(Num.new \"0xdeadbeef\").hex\n# => \"352b82608dad6c7ac3dd665bc2666e5d97803cb13f23a1109e2105e93f42c448\"\n\nUtil.sha3(\"0xdeadbeef\").hex\n# => \"c12811e13ed75afe3e0945ef34e8a25b9d321a46e131c6463731de25a21b39eb\"\n```","summary":"

Operating a SHA3 hash on a binary/number or string literal.

","abstract":false,"args":[{"name":"data","external_name":"data","restriction":"Num | String"},{"name":"entropy","default_value":"256","external_name":"entropy","restriction":""}],"args_string":"(data : Num | String, entropy = 256) : Num","args_html":"(data : Num | String, entropy = 256) : Num","location":{"filename":"src/secp256k1/util.cr","line_number":59,"url":null},"def":{"name":"sha3","args":[{"name":"data","external_name":"data","restriction":"Num | String"},{"name":"entropy","default_value":"256","external_name":"entropy","restriction":""}],"return_type":"Num","visibility":"Public","body":"sha3 = Digest::SHA3.new(entropy)\nif data.is_a?(String)\n return Num.new((sha3.update(data)).hexdigest)\nelse\n return Num.new((sha3.update(data.to_bytes)).hexdigest)\nend\n"}}]}]}]}} \ No newline at end of file +{"repository_name":"secp256k1","body":"# secp256k1.cr\n\n[![Build Status](https://img.shields.io/github/workflow/status/q9f/secp256k1.cr/Nightly)](https://github.com/q9f/secp256k1.cr/actions)\n[![Code Coverage](https://codecov.io/gh/q9f/secp256k1.cr/branch/main/graph/badge.svg?token=ngxRs9HdJA)](https://codecov.io/gh/q9f/secp256k1.cr)\n[![Documentation](https://img.shields.io/badge/docs-html-black)](https://q9f.github.io/secp256k1.cr/)\n[![Release](https://img.shields.io/github/v/release/q9f/secp256k1.cr?include_prereleases&color=black)](https://github.com/q9f/secp256k1.cr/releases/latest)\n[![Language](https://img.shields.io/github/languages/top/q9f/secp256k1.cr?color=black)](https://github.com/q9f/secp256k1.cr/search?l=crystal)\n[![License](https://img.shields.io/github/license/q9f/secp256k1.cr.svg?color=black)](LICENSE)\n\nA library implementing the `Secp256k1` elliptic curve natively in pure Crystal.\n`Secp256k1` is the elliptic curve used in the public-private-key cryptography required by `Bitcoin`, `Ethereum`, and `Polkadot`.\n\nThis library allows for:\n* providing a `Secp256k1` cryptographic context, see `Secp256k1::Context`\n* managing `Secp256k1` signatures and verification, see `Secp256k1::Signature`\n* managing private-public keypairs, see `Secp256k1::Key`\n* generating public keys, see `Secp256k1::Point`\n* generating private keys, see `Secp256k1::Num`\n\n# Installation\n\nAdd the `Secp256k1` library to your `shard.yml`\n\n```yaml\ndependencies:\n secp256k1:\n github: q9f/secp256k1.cr\n version: \"~> 0.5\"\n```\n\n# Usage\n\nImport and expose the `Secp256k1` module.\n\n```crystal\nrequire \"secp256k1\"\n```\n\nThis library exposes the following modules and classes (in logical order):\n\n* `Secp256k1`: necessary constants and data structures, including:\n - `Secp256k1::Num`: for managing big numerics (private keys)\n - `Secp256k1::Point`: for handling of elliptic curve points (public keys)\n - `Secp256k1::Key`: for managing private-public keypairs (accounts)\n - `Secp256k1::Signature`: for handling ECDSA signatures (r, s, v)\n* `Secp256k1::Context`: providing a cryptographic context for signing and verification\n* `Secp256k1::Curve`: the entire core mathematics behind the elliptic curve cryptography\n* `Secp256k1::Util`: binding of various hashing algorithms for convenience\n\nBasic usage:\n\n```crystal\n# generates a new, random keypair\nkey = Secp256k1::Key.new\n# => #,\n# @public_key=#,\n# @y=#>>\n\n# gets the private key\nkey.private_hex\n# => \"3ccf84820c20d5e8c536ba84c52ba410375b29b1812b5f7e722445c969a0fb30\"\n\n# gets the compressed public key with prefix\nkey.public_hex_compressed\n# => \"02cd4a8712ee6efc15b5abe37c0dbfa979d89c427d3fe24b076008decefe94dba2\"\n```\n\nSignature generation and verification:\n\n```crystal\n# sign a message with a private key\nctx = Secp256k1::Context.new\npriv = Secp256k1::Num.new \"1f0c122d41ff536b19bfd83537c0dfc290e45cd3c375a43237c8b8fff7ac8af7\"\nkey = Secp256k1::Key.new priv\nhash = Secp256k1::Util.sha256 \"Henlo, Wordl\"\nsig = ctx.sign key, hash\n# => #,\n# @s=#,\n# @v=#>\n\n# verify a signature with a public key\nr = Secp256k1::Num.new \"c4079db44240b7afe94985c69fc89602e33629fd9b8623d711c30ce6378b33df\"\ns = Secp256k1::Num.new \"6842c1b63c94bdb8e4f5ae88fb65f7a98b77b197c8323004fb47ef57fab29053\"\nv = Secp256k1::Num.new \"00\"\nsig = Secp256k1::Signature.new r, s, v\nhash = Secp256k1::Util.sha256 \"Henlo, Wordl\"\npubl = Secp256k1::Point.new \"0416008a369439f1a8a75cf974860bed5b10180518d6b1dd3ac847f423fd375d6aa29474394f0cd79d2ea543507d069e97339284f01bdbfd27392daec0ec553816\"\nctx.verify sig, hash, publ\n# => true\n```\n\n# Documentation\n\nThe full library documentation can be found here: [q9f.github.io/secp256k1.cr](https://q9f.github.io/secp256k1.cr/)\n\nGenerate a local copy with:\n\n```shell\ncrystal docs\n```\n\n# Testing\n\nThe library is entirely specified through tests in `./spec`; run:\n\n```shell\ncrystal spec --verbose\n```\n\n# Understand\n\nPrivate keys are just scalars (`Secp256k1::Num`) and public keys are points (`Secp256k1::Point`) with `x` and `y` coordinates.\n\nBitcoin public keys can be uncompressed `p|x|y` or compressed `p|x`. both come with a prefix `p` which is useless for uncompressed keys but necessary for compressed keys to recover the `y` coordinate on the `Secp256k1` elliptic curve field.\n\nEthereum public keys are uncompressed `x|y` without any prefix. The last 20 bytes slice of the `y` coordinate is actually used as address without any checksum. A checksum was later added in EIP-55 using a `keccak256` hash and indicating character capitalization.\n\nNeither Bitcoin nor Ethereum allow for recovering public keys from an address unless there exists a transaction with a valid signature on the blockchain.\n\n# Known issues\n\n_Note: this library should not be used in production without proper auditing. It should be considered slow and insecure._\n\n* This library is not constant time and might be subject to side-channel attacks. ([#4](https://github.com/q9f/secp256k1.cr/issues/4))\n* This library does unnecessary big-integer math and should someday rather correctly implement the `Secp256k1` prime field ([#5](https://github.com/q9f/secp256k1.cr/issues/5))\n* This library is slow in recovering signatures. Future versions should respect the recovery ID to quickly identify the correct public key from a signature.\n\nFound any other issue? Report it: [github.com/q9f/secp256k1.cr/issues](https://github.com/q9f/secp256k1.cr/issues)\n\n# Contribute\n\nCreate a pull request, and make sure tests and linter pass.\n\nThis pure crystal implementation is based on the python implementation [wobine/blackboard101](https://github.com/wobine/blackboard101) which is also used as reference to write tests against. It's a complete rewrite of the abandoned [packetzero/bitcoinutils](https://github.com/packetzero/bitcoinutils) for educational purposes.\n\nHonerable mention for the [bitcoin wiki](https://en.bitcoin.it/wiki/Main_Page) and the [ethereum stackexchange](https://ethereum.stackexchange.com/) for providing so many in-depth resources that supported this project in reimplementing everything.\n\nLicense: Apache License v2.0\n\nContributors: [**@q9f**](https://github.com/q9f/), [@cserb](https://github.com/cserb), [MrSorcus](https://github.com/MrSorcus)\n","program":{"html_id":"secp256k1/toplevel","path":"toplevel.html","kind":"module","full_name":"Top Level Namespace","name":"Top Level Namespace","abstract":false,"locations":[],"repository_name":"secp256k1","program":true,"enum":false,"alias":false,"const":false,"types":[{"html_id":"secp256k1/Secp256k1","path":"Secp256k1.html","kind":"module","full_name":"Secp256k1","name":"Secp256k1","abstract":false,"locations":[{"filename":"src/secp256k1.cr","line_number":35,"url":null},{"filename":"src/secp256k1/context.cr","line_number":22,"url":null},{"filename":"src/secp256k1/version.cr","line_number":21,"url":null}],"repository_name":"secp256k1","program":false,"enum":false,"alias":false,"const":false,"constants":[{"id":"G","name":"G","value":"Point.new(Num.new(\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\"), Num.new(\"483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8\"))","doc":"A commonly used base point `G` with coordinates `x` and `y`\nsatisfying `y^2 = x^3 + 7`.","summary":"

A commonly used base point G with coordinates x and y satisfying y^2 = x^3 + 7.

"},{"id":"N","name":"N","value":"Num.new(\"fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141\")","doc":"The order `n` of `G` defines the finite size of the Secp256k1 field `E`.","summary":"

The order n of G defines the finite size of the Secp256k1 field E.

"},{"id":"P","name":"P","value":"Num.new(\"fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f\")","doc":"The elliptic curve domain parameters over `F_p` associated with a\nKoblitz curve `Secp256k1` are specified by the sextuple\n`T = (p, a, b, G, n, h)` where the finite field `F_p` is defined by\nthe prime `p = 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1`.","summary":"

The elliptic curve domain parameters over F_p associated with a Koblitz curve Secp256k1 are specified by the sextuple T = (p, a, b, G, n, h) where the finite field F_p is defined by the prime p = 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1.

"},{"id":"VERSION","name":"VERSION","value":"\"0.5.0\"","doc":"The `VERSION` of the `Secp256k1` module.","summary":"

The VERSION of the Secp256k1 module.

"}],"doc":"Provides the `Secp256k1` module with the elliptic curve parameters\nused by the `Bitcoin`, `Ethereum`, and `Polkadot` blockchains. It's\nprimarily used to generate key-pairs as well as signing messages and\nrecoverying signatures.\n\nRef: [secg.org/sec2-v2.pdf](https://www.secg.org/sec2-v2.pdf)","summary":"

Provides the Secp256k1 module with the elliptic curve parameters used by the Bitcoin, Ethereum, and Polkadot blockchains.

","types":[{"html_id":"secp256k1/Secp256k1/Context","path":"Secp256k1/Context.html","kind":"class","full_name":"Secp256k1::Context","name":"Context","abstract":false,"superclass":{"html_id":"secp256k1/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"secp256k1/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"secp256k1/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/secp256k1/context.cr","line_number":22,"url":null}],"repository_name":"secp256k1","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"secp256k1/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"Provides a `Secp256k1` context to allow signing arbitrary data,\nrecovering public keys, and verifying signatures.\n\n```\nctx = Context.new\n# => #\n```","summary":"

Provides a Secp256k1 context to allow signing arbitrary data, recovering public keys, and verifying signatures.

","instance_methods":[{"html_id":"sign(key:Key,hash:Num):Signature-instance-method","name":"sign","doc":"Signs a message hash or any other arbitrary data with a given keypair.\n\nParameters:\n* `key` (`Key`): the keypair containing a secret to sign the data.\n* `hash` (`Num`): the message or arbirtrary data hash.\n\nReturns a `Signature` proving the given key signed the message hash.\n\n```\nctx = Context.new\nkey = Key.new Num.new \"1f0c122d41ff536b19bfd83537c0dfc290e45cd3c375a43237c8b8fff7ac8af7\"\nhash = Util.sha256 \"Henlo, Wordl\"\nsig = ctx.sign key, hash\n# => #,\n# @s=#,\n# @v=#>\n```","summary":"

Signs a message hash or any other arbitrary data with a given keypair.

","abstract":false,"args":[{"name":"key","external_name":"key","restriction":"Key"},{"name":"hash","external_name":"hash","restriction":"Num"}],"args_string":"(key : Key, hash : Num) : Signature","args_html":"(key : Key, hash : Num) : Signature","location":{"filename":"src/secp256k1/context.cr","line_number":50,"url":null},"def":{"name":"sign","args":[{"name":"key","external_name":"key","restriction":"Key"},{"name":"hash","external_name":"hash","restriction":"Num"}],"return_type":"Signature","visibility":"Public","body":"k = Util.deterministic_k(key.private_key, hash)\nhash = hash.to_big\npriv = key.private_key.to_big\npoint = Curve.mul(G, k)\nr = point.x.to_big % N.to_big\nk_inv = Curve.mod_inv(k, N)\ns = ((hash + (r * priv)) * k_inv.to_big) % N.to_big\nx_mag = point.x.to_big > N.to_big\ny_parity = (point.y.to_big % 2) == 0\nrec_id : Int8 = -1\nif (!y_parity) && x_mag\n rec_id = 3\nelse\n if y_parity && x_mag\n rec_id = 2\n else\n if (!y_parity) && (!x_mag)\n rec_id = 1\n else\n rec_id = 0\n end\n end\nend\nr = Num.new(r)\ns = Num.new(s)\nv = Num.new(BigInt.new(rec_id))\nSignature.new(r, s, v)\n"}},{"html_id":"verify(sig:Signature,hash:Num,publ:Point):Bool-instance-method","name":"verify","doc":"Verifies that a given signature for a given message hash matches\nthe provided public key.\n\nParameters:\n* `sig` (`Signature`): the signature to be verified.\n* `hash` (`Num`): the message or arbirtrary data hash.\n* `publ` (`Point`): the public key to match.\n\nReturns _true_ if the signature verifies.\n\n```\nctx = Context.new\nr = Num.new \"c4079db44240b7afe94985c69fc89602e33629fd9b8623d711c30ce6378b33df\"\ns = Num.new \"6842c1b63c94bdb8e4f5ae88fb65f7a98b77b197c8323004fb47ef57fab29053\"\nv = Num.new \"00\"\nsig = Signature.new r, s, v\nhash = Util.sha256 \"Henlo, Wordl\"\npubl = Point.new \"0416008a369439f1a8a75cf974860bed5b10180518d6b1dd3ac847f423fd375d6aa29474394f0cd79d2ea543507d069e97339284f01bdbfd27392daec0ec553816\"\nctx.verify sig, hash, publ\n# => true\n```","summary":"

Verifies that a given signature for a given message hash matches the provided public key.

","abstract":false,"args":[{"name":"sig","external_name":"sig","restriction":"Signature"},{"name":"hash","external_name":"hash","restriction":"Num"},{"name":"publ","external_name":"publ","restriction":"Point"}],"args_string":"(sig : Signature, hash : Num, publ : Point) : Bool","args_html":"(sig : Signature, hash : Num, publ : Point) : Bool","location":{"filename":"src/secp256k1/context.cr","line_number":97,"url":null},"def":{"name":"verify","args":[{"name":"sig","external_name":"sig","restriction":"Signature"},{"name":"hash","external_name":"hash","restriction":"Num"},{"name":"publ","external_name":"publ","restriction":"Point"}],"return_type":"Bool","visibility":"Public","body":"s_inv = Curve.mod_inv(sig.s, N)\np0 = Curve.mul(G, (hash.to_big * s_inv.to_big) % N.to_big)\np1 = Curve.mul(publ, (sig.r.to_big * s_inv.to_big) % N.to_big)\np = Curve.add(p0, p1)\nsig.r.to_big === p.x.to_big\n"}}]},{"html_id":"secp256k1/Secp256k1/Curve","path":"Secp256k1/Curve.html","kind":"module","full_name":"Secp256k1::Curve","name":"Curve","abstract":false,"locations":[{"filename":"src/secp256k1/curve.cr","line_number":18,"url":null}],"repository_name":"secp256k1","program":false,"enum":false,"alias":false,"const":false,"extended_modules":[{"html_id":"secp256k1/Secp256k1/Curve","kind":"module","full_name":"Secp256k1::Curve","name":"Curve"}],"namespace":{"html_id":"secp256k1/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"Implements 256-bit `Secp256k1` Koblitz elliptic curve operations.\n\nRef: [secg.org/sec2-v2.pdf](https://www.secg.org/sec2-v2.pdf)","summary":"

Implements 256-bit Secp256k1 Koblitz elliptic curve operations.

","instance_methods":[{"html_id":"add(p:Point,q:Point,prime=P):Point-instance-method","name":"add","doc":"Computes the elliptic curve jive addition of point `p(x, y)` and `q(x, y)`.\nIt _draws_ a line between `p` and `q` which will intersect the\ncurve in the point `r` which will be mirrored over the `x`-axis.\n\nParamters:\n* `p` (`Num`): the point `p(x, y)` to be used in the jive addition.\n* `q` (`Num`): the point `q(x, y)` to be used in the jive addition.\n* `prime` (`Num`): the prime number that shapes the field (default `P`).\n\nReturns a `Point` containing the result of the intersection.\n```\np = Point.new Num.new \"5cb1eec17e38b004a8fd90fa8e423432430f60d76c30bb33f4091243c029e86d\"\nq = Point.new Num.new \"7e17f60baa7b8dc8581a55f7be1ea263c6a88452cf3f0a3f710651767654946c\"\nCurve.add p, q\n# => #,\n# @y=#>\n```","summary":"

Computes the elliptic curve jive addition of point p(x, y) and q(x, y).

","abstract":false,"args":[{"name":"p","external_name":"p","restriction":"Point"},{"name":"q","external_name":"q","restriction":"Point"},{"name":"prime","default_value":"P","external_name":"prime","restriction":""}],"args_string":"(p : Point, q : Point, prime = P) : Point","args_html":"(p : Point, q : Point, prime = P) : Point","location":{"filename":"src/secp256k1/curve.cr","line_number":82,"url":null},"def":{"name":"add","args":[{"name":"p","external_name":"p","restriction":"Point"},{"name":"q","external_name":"q","restriction":"Point"},{"name":"prime","default_value":"P","external_name":"prime","restriction":""}],"return_type":"Point","visibility":"Public","body":"if prime.is_a?(Num)\n prime = prime.to_big\nend\np_x = p.x.to_big\np_y = p.y.to_big\nq_x = q.x.to_big\nq_y = q.y.to_big\nx_delta = q_x - p_x\nx_inv = mod_inv(x_delta)\ny_delta = q_y - p_y\nm = (y_delta * x_inv.to_big) % prime\nx = (((m * m) - p_x) - q_x) % prime\ny = ((m * (p_x - x)) - p_y) % prime\nx = Num.new(x)\ny = Num.new(y)\nPoint.new(x, y)\n"}},{"html_id":"double(p:Point,prime=P):Point-instance-method","name":"double","doc":"Computes the elliptic curve juke point doubling of `p(x, y)`.\nThis is a special case of addition where both points are the same.\nIt _draws_ a tangent line at `p` which will intersect the curve\nat point `r` which will be mirrored over the `x`-axis.\n\nParamters:\n* `p` (`Point`): the point `p(x, y)` to be used in the juke doubling.\n* `prime` (`Num`): the prime number that shapes the field (default `P`).\n\nReturns a `Point` as a result of the intersection.\n\n```\np = Point.new Num.new \"5cb1eec17e38b004a8fd90fa8e423432430f60d76c30bb33f4091243c029e86d\"\nCurve.double p\n# => #,\n# @y=#>\n```","summary":"

Computes the elliptic curve juke point doubling of p(x, y).

","abstract":false,"args":[{"name":"p","external_name":"p","restriction":"Point"},{"name":"prime","default_value":"P","external_name":"prime","restriction":""}],"args_string":"(p : Point, prime = P) : Point","args_html":"(p : Point, prime = P) : Point","location":{"filename":"src/secp256k1/curve.cr","line_number":123,"url":null},"def":{"name":"double","args":[{"name":"p","external_name":"p","restriction":"Point"},{"name":"prime","default_value":"P","external_name":"prime","restriction":""}],"return_type":"Point","visibility":"Public","body":"if prime.is_a?(Num)\n prime = prime.to_big\nend\np_x = p.x.to_big\np_y = p.y.to_big\nlam_numer = (3 * p_x) * p_x\nlam_denom = 2 * p_y\nlam_inv = mod_inv(Num.new(lam_denom))\nlam = (lam_numer * lam_inv.to_big) % prime\nx = ((lam * lam) - (2 * p_x)) % prime\ny = ((lam * (p_x - x)) - p_y) % prime\nx = Num.new(x)\ny = Num.new(y)\nPoint.new(x, y)\n"}},{"html_id":"mod_inv(a:Num|BigInt,prime=P):Num-instance-method","name":"mod_inv","doc":"Computes the elliptic curve modular multiplicative inverse of `a`.\n\nParemeters:\n* `a` (`Num | BigInt`): the integer that we want the modular inverse of.\n* `prime` (`Num`): the prime number that shapes the field (default `P`).\n\nReturns a `Num` containing the mod inverse.\n\n```\na = Num.new \"ea678c668356d16d8bf5c69f95c1055e39bd24174605f64846e27c3ae6a88d81\"\nCurve.mod_inv a\n# => #\n```","summary":"

Computes the elliptic curve modular multiplicative inverse of a.

","abstract":false,"args":[{"name":"a","external_name":"a","restriction":"Num | BigInt"},{"name":"prime","default_value":"P","external_name":"prime","restriction":""}],"args_string":"(a : Num | BigInt, prime = P) : Num","args_html":"(a : Num | BigInt, prime = P) : Num","location":{"filename":"src/secp256k1/curve.cr","line_number":37,"url":null},"def":{"name":"mod_inv","args":[{"name":"a","external_name":"a","restriction":"Num | BigInt"},{"name":"prime","default_value":"P","external_name":"prime","restriction":""}],"return_type":"Num","visibility":"Public","body":"if a.is_a?(Num)\n a = a.to_big\nend\nif prime.is_a?(Num)\n prime = prime.to_big\nend\nm_low = 1\nm_high = 0\nv_low = a % prime\nv_high = prime\nwhile v_low > 1\n v_ratio = v_high // v_low\n m_low_r = m_low * v_ratio\n v_low_r = v_low * v_ratio\n m = m_high - m_low_r\n v = v_high - v_low_r\n m_high = m_low\n v_high = v_low\n m_low = m\n v_low = v\nend\nNum.new(m_low % prime)\n"}},{"html_id":"mul(p:Point,s:Num|BigInt):Point-instance-method","name":"mul","doc":"Computes the elliptic curve sequence multiplication of point `p(x, y)`\nand a skalar `s`; with `s` being a private key within the elliptic\ncurve field size of `N`.\n\nParamters:\n* `p` (`Point`): the point `p(x, y)` to be used in the sequencing.\n* `s` (`Num | BigInt`): a skalar, in most cases a private key.\n\nReturns a `Point` as a result of the multiplication.\n\n```\np = Point.new Num.new \"5cb1eec17e38b004a8fd90fa8e423432430f60d76c30bb33f4091243c029e86d\"\ns = Num.new \"f51ad125548b7a283ebf15ab830a25c850d4d863078c48cc9993b79ee18ee11e\"\nCurve.mul p, s\n# => #,\n# @y=#>\n```","summary":"

Computes the elliptic curve sequence multiplication of point p(x, y) and a skalar s; with s being a private key within the elliptic curve field size of N.

","abstract":false,"args":[{"name":"p","external_name":"p","restriction":"Point"},{"name":"s","external_name":"s","restriction":"Num | BigInt"}],"args_string":"(p : Point, s : Num | BigInt) : Point","args_html":"(p : Point, s : Num | BigInt) : Point","location":{"filename":"src/secp256k1/curve.cr","line_number":162,"url":null},"def":{"name":"mul","args":[{"name":"p","external_name":"p","restriction":"Point"},{"name":"s","external_name":"s","restriction":"Num | BigInt"}],"return_type":"Point","visibility":"Public","body":"if s.is_a?(Num)\n s = s.to_big\nend\nif (s === 0) || s >= N.to_big\n raise(\"Invalid scalar: outside of Secp256k1 field dimension.\")\nend\ns_bin = s.to_s(2)\nq = p\ns_bin.each_char_with_index do |char, index|\n if index === 0\n next\n end\n q = double(q)\n if char === '1'\n q = add(q, p)\n end\nend\nq\n"}}]},{"html_id":"secp256k1/Secp256k1/Key","path":"Secp256k1/Key.html","kind":"class","full_name":"Secp256k1::Key","name":"Key","abstract":false,"superclass":{"html_id":"secp256k1/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"secp256k1/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"secp256k1/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/secp256k1/key.cr","line_number":21,"url":null}],"repository_name":"secp256k1","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"secp256k1/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"Provides a `Secp256k1` keypair containing a secret number (private key)\nand a public point on the elliptic curve (public key).\n\nProperties:\n* `private_key` (`Num`): the secret number representing the private key.\n* `public_key` (`Point`): the point on the elliptic curve representing the public key.","summary":"

Provides a Secp256k1 keypair containing a secret number (private key) and a public point on the elliptic curve (public key).

","constructors":[{"html_id":"new(priv:Num)-class-method","name":"new","doc":"Creates a public-private keypair from an existing private key.\n\nParameters:\n* `priv` (`Num`): the private key for the keypair.\n\n```\npriv = Num.new \"3ccf84820c20d5e8c536ba84c52ba410375b29b1812b5f7e722445c969a0fb30\"\nKey.new priv\n# => #,\n# @public_key=#,\n# @y=#>>\n```","summary":"

Creates a public-private keypair from an existing private key.

","abstract":false,"args":[{"name":"priv","external_name":"priv","restriction":"Num"}],"args_string":"(priv : Num)","args_html":"(priv : Num)","location":{"filename":"src/secp256k1/key.cr","line_number":74,"url":null},"def":{"name":"new","args":[{"name":"priv","external_name":"priv","restriction":"Num"}],"visibility":"Public","body":"_ = allocate\n_.initialize(priv)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}},{"html_id":"new-class-method","name":"new","doc":"Creates a new, random `Secp256k1` keypair.\n\n```\nKey.new\n# => #,\n# @public_key=#,\n# @y=#>>\n```","summary":"

Creates a new, random Secp256k1 keypair.

","abstract":false,"location":{"filename":"src/secp256k1/key.cr","line_number":46,"url":null},"def":{"name":"new","visibility":"Public","body":"_ = allocate\n_.initialize\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"html_id":"private_bytes:Bytes-instance-method","name":"private_bytes","doc":"Returns the private key as binary byte slice.\n\n```\nKey.new(Num.new \"3ccf84820c20d5e8c536ba84c52ba410375b29b1812b5f7e722445c969a0fb30\").private_bytes\n# => Bytes[60, 207, 132, 130, 12, 32, 213, 232, 197, 54, 186, 132, 197, 43, 164, 16, 55, 91, 41, 177, 129, 43, 95, 126, 114, 36, 69, 201, 105, 160, 251, 48]\n```","summary":"

Returns the private key as binary byte slice.

","abstract":false,"location":{"filename":"src/secp256k1/key.cr","line_number":95,"url":null},"def":{"name":"private_bytes","return_type":"Bytes","visibility":"Public","body":"@private_key.to_zpadded_bytes"}},{"html_id":"private_hex:String-instance-method","name":"private_hex","doc":"Returns the private key as hexadecimal string literal.\n\n```\nKey.new(Num.new \"3ccf84820c20d5e8c536ba84c52ba410375b29b1812b5f7e722445c969a0fb30\").private_hex\n# => \"3ccf84820c20d5e8c536ba84c52ba410375b29b1812b5f7e722445c969a0fb30\"\n```","summary":"

Returns the private key as hexadecimal string literal.

","abstract":false,"location":{"filename":"src/secp256k1/key.cr","line_number":85,"url":null},"def":{"name":"private_hex","return_type":"String","visibility":"Public","body":"@private_key.to_zpadded_hex"}},{"html_id":"private_key:Num-instance-method","name":"private_key","doc":"The secret number representing the private key.","summary":"

The secret number representing the private key.

","abstract":false,"location":{"filename":"src/secp256k1/key.cr","line_number":23,"url":null},"def":{"name":"private_key","return_type":"Num","visibility":"Public","body":"@private_key"}},{"html_id":"private_key=(private_key:Num)-instance-method","name":"private_key=","doc":"The secret number representing the private key.","summary":"

The secret number representing the private key.

","abstract":false,"args":[{"name":"private_key","external_name":"private_key","restriction":"Num"}],"args_string":"(private_key : Num)","args_html":"(private_key : Num)","location":{"filename":"src/secp256k1/key.cr","line_number":23,"url":null},"def":{"name":"private_key=","args":[{"name":"private_key","external_name":"private_key","restriction":"Num"}],"visibility":"Public","body":"@private_key = private_key"}},{"html_id":"public_bytes:Bytes-instance-method","name":"public_bytes","doc":"Returns the public key as uncompressed, binary byte slice.\n\n```\nKey.new(Num.new \"3ccf84820c20d5e8c536ba84c52ba410375b29b1812b5f7e722445c969a0fb30\").public_bytes\n# => Bytes[4, 205, 74, 135, 18, 238, 110, 252, 21, 181, 171, 227, 124, 13, 191, 169, 121, 216, 156, 66, 125, 63, 226, 75, 7, 96, 8, 222, 206, 254, 148, 219, 162, 129, 54, 61, 41, 142, 74, 64, 235, 203, 19, 241, 175, 168, 90, 11, 148, 185, 103, 242, 67, 238, 89, 165, 144, 16, 203, 93, 234, 240, 215, 182, 108]\n```","summary":"

Returns the public key as uncompressed, binary byte slice.

","abstract":false,"location":{"filename":"src/secp256k1/key.cr","line_number":125,"url":null},"def":{"name":"public_bytes","return_type":"Bytes","visibility":"Public","body":"(Num.new(@public_key.uncompressed)).to_bytes"}},{"html_id":"public_bytes_compressed:Bytes-instance-method","name":"public_bytes_compressed","doc":"Returns the public key as compressed, binary byte slice.\n\n```\nKey.new(Num.new \"3ccf84820c20d5e8c536ba84c52ba410375b29b1812b5f7e722445c969a0fb30\").public_bytes_compressed\n# => Bytes[2, 205, 74, 135, 18, 238, 110, 252, 21, 181, 171, 227, 124, 13, 191, 169, 121, 216, 156, 66, 125, 63, 226, 75, 7, 96, 8, 222, 206, 254, 148, 219, 162]\n```","summary":"

Returns the public key as compressed, binary byte slice.

","abstract":false,"location":{"filename":"src/secp256k1/key.cr","line_number":135,"url":null},"def":{"name":"public_bytes_compressed","return_type":"Bytes","visibility":"Public","body":"(Num.new(@public_key.compressed)).to_bytes"}},{"html_id":"public_hex:String-instance-method","name":"public_hex","doc":"Returns the public key as uncompressed, hexadecimal string literal.\n\n```\nKey.new(Num.new \"3ccf84820c20d5e8c536ba84c52ba410375b29b1812b5f7e722445c969a0fb30\").public_hex\n# => \"04cd4a8712ee6efc15b5abe37c0dbfa979d89c427d3fe24b076008decefe94dba281363d298e4a40ebcb13f1afa85a0b94b967f243ee59a59010cb5deaf0d7b66c\"\n```","summary":"

Returns the public key as uncompressed, hexadecimal string literal.

","abstract":false,"location":{"filename":"src/secp256k1/key.cr","line_number":105,"url":null},"def":{"name":"public_hex","return_type":"String","visibility":"Public","body":"@public_key.uncompressed"}},{"html_id":"public_hex_compressed:String-instance-method","name":"public_hex_compressed","doc":"Returns the public key as compressed, hexadecimal string literal.\n\n```\nKey.new(Num.new \"3ccf84820c20d5e8c536ba84c52ba410375b29b1812b5f7e722445c969a0fb30\").public_hex_compressed\n# => \"02cd4a8712ee6efc15b5abe37c0dbfa979d89c427d3fe24b076008decefe94dba2\"\n```","summary":"

Returns the public key as compressed, hexadecimal string literal.

","abstract":false,"location":{"filename":"src/secp256k1/key.cr","line_number":115,"url":null},"def":{"name":"public_hex_compressed","return_type":"String","visibility":"Public","body":"@public_key.compressed"}},{"html_id":"public_key:Point-instance-method","name":"public_key","doc":"The point on the elliptic curve representing the public key.","summary":"

The point on the elliptic curve representing the public key.

","abstract":false,"location":{"filename":"src/secp256k1/key.cr","line_number":25,"url":null},"def":{"name":"public_key","return_type":"Point","visibility":"Public","body":"@public_key"}},{"html_id":"public_key=(public_key:Point)-instance-method","name":"public_key=","doc":"The point on the elliptic curve representing the public key.","summary":"

The point on the elliptic curve representing the public key.

","abstract":false,"args":[{"name":"public_key","external_name":"public_key","restriction":"Point"}],"args_string":"(public_key : Point)","args_html":"(public_key : Point)","location":{"filename":"src/secp256k1/key.cr","line_number":25,"url":null},"def":{"name":"public_key=","args":[{"name":"public_key","external_name":"public_key","restriction":"Point"}],"visibility":"Public","body":"@public_key = public_key"}}]},{"html_id":"secp256k1/Secp256k1/Num","path":"Secp256k1/Num.html","kind":"class","full_name":"Secp256k1::Num","name":"Num","abstract":false,"superclass":{"html_id":"secp256k1/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"secp256k1/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"secp256k1/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/secp256k1/num.cr","line_number":25,"url":null}],"repository_name":"secp256k1","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"secp256k1/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"Provides a class to conveniently handle big numbers on the elliptic\ncurve. It allows to easily access decimal, hexadecimal, and binary\nrepresentations of the numeric. In addition, it implements some\nutilities such as zpadding or asserting hexadecimal strings. It's suited\nto temporarily handle unencrypted private keys.\n\nProperties:\n* `hex` (`String`): the hexadecimal string representation of the number.\n* `dec` (`BigInt`): the decimal big-integer representation of the number.\n* `bin` (`Bytes`): the binary bytes-slice represenation of the number.","summary":"

Provides a class to conveniently handle big numbers on the elliptic curve.

","constructors":[{"html_id":"new(hex:String)-class-method","name":"new","doc":"Creates a number from a hexadecimal string literal.\n\nParameters:\n* `hex` (`String`): a hexadecimal string representating the number.\n\n```\nNum.new \"568a0f505bde902db4a6afd207c794c7845fe7715da5999bb276d453c702a46d\"\n# => #\n```","summary":"

Creates a number from a hexadecimal string literal.

","abstract":false,"args":[{"name":"hex","external_name":"hex","restriction":"String"}],"args_string":"(hex : String)","args_html":"(hex : String)","location":{"filename":"src/secp256k1/num.cr","line_number":67,"url":null},"def":{"name":"new","args":[{"name":"hex","external_name":"hex","restriction":"String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(hex)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}},{"html_id":"new(num:BigInt)-class-method","name":"new","doc":"Creates a number from a big integer numeric.\n\nParameters:\n* `dec` (`BigInt`): the decimal big-integer representating the number.\n\n```\nNum.new BigInt.new \"39142835565766237398843902819171565157710677457569850027793715608438337348717\"\n# => #\n```","summary":"

Creates a number from a big integer numeric.

","abstract":false,"args":[{"name":"num","external_name":"num","restriction":"BigInt"}],"args_string":"(num : BigInt)","args_html":"(num : BigInt)","location":{"filename":"src/secp256k1/num.cr","line_number":87,"url":null},"def":{"name":"new","args":[{"name":"num","external_name":"num","restriction":"BigInt"}],"visibility":"Public","body":"_ = allocate\n_.initialize(num)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}},{"html_id":"new(bin:Slice(UInt8))-class-method","name":"new","doc":"Creates a number from a binary bytes slice.\n\nParameters:\n* `bin` (`Bytes`): the binary bytes-slice represenating the number.\n\n```\nNum.new Bytes[86, 138, 15, 80, 91, 222, 144, 45, 180, 166, 175, 210, 7, 199, 148, 199, 132, 95, 231, 113, 93, 165, 153, 155, 178, 118, 212, 83, 199, 2, 164, 109]\n# => #\n```","summary":"

Creates a number from a binary bytes slice.

","abstract":false,"args":[{"name":"bin","external_name":"bin","restriction":"Slice(UInt8)"}],"args_string":"(bin : Slice(UInt8))","args_html":"(bin : Slice(UInt8))","location":{"filename":"src/secp256k1/num.cr","line_number":107,"url":null},"def":{"name":"new","args":[{"name":"bin","external_name":"bin","restriction":"Slice(UInt8)"}],"visibility":"Public","body":"_ = allocate\n_.initialize(bin)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}},{"html_id":"new-class-method","name":"new","doc":"Creates a random number using `Random::Secure` that can be used as\na secret (private key).\n\n```\nNum.new\n# => #\n```","summary":"

Creates a random number using Random::Secure that can be used as a secret (private key).

","abstract":false,"location":{"filename":"src/secp256k1/num.cr","line_number":43,"url":null},"def":{"name":"new","visibility":"Public","body":"_ = allocate\n_.initialize\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"html_id":"bin:Slice(UInt8)-instance-method","name":"bin","doc":"The binary bytes-slice represenation of the number.","summary":"

The binary bytes-slice represenation of the number.

","abstract":false,"location":{"filename":"src/secp256k1/num.cr","line_number":31,"url":null},"def":{"name":"bin","return_type":"Slice(UInt8)","visibility":"Public","body":"@bin"}},{"html_id":"bin=(bin:Slice(UInt8))-instance-method","name":"bin=","doc":"The binary bytes-slice represenation of the number.","summary":"

The binary bytes-slice represenation of the number.

","abstract":false,"args":[{"name":"bin","external_name":"bin","restriction":"Slice(UInt8)"}],"args_string":"(bin : Slice(UInt8))","args_html":"(bin : Slice(UInt8))","location":{"filename":"src/secp256k1/num.cr","line_number":31,"url":null},"def":{"name":"bin=","args":[{"name":"bin","external_name":"bin","restriction":"Slice(UInt8)"}],"visibility":"Public","body":"@bin = bin"}},{"html_id":"dec:BigInt-instance-method","name":"dec","doc":"The decimal big-integer representation of the number.","summary":"

The decimal big-integer representation of the number.

","abstract":false,"location":{"filename":"src/secp256k1/num.cr","line_number":29,"url":null},"def":{"name":"dec","return_type":"BigInt","visibility":"Public","body":"@dec"}},{"html_id":"dec=(dec:BigInt)-instance-method","name":"dec=","doc":"The decimal big-integer representation of the number.","summary":"

The decimal big-integer representation of the number.

","abstract":false,"args":[{"name":"dec","external_name":"dec","restriction":"BigInt"}],"args_string":"(dec : BigInt)","args_html":"(dec : BigInt)","location":{"filename":"src/secp256k1/num.cr","line_number":29,"url":null},"def":{"name":"dec=","args":[{"name":"dec","external_name":"dec","restriction":"BigInt"}],"visibility":"Public","body":"@dec = dec"}},{"html_id":"hex:String-instance-method","name":"hex","doc":"The hexadecimal string representation of the number.","summary":"

The hexadecimal string representation of the number.

","abstract":false,"location":{"filename":"src/secp256k1/num.cr","line_number":27,"url":null},"def":{"name":"hex","return_type":"String","visibility":"Public","body":"@hex"}},{"html_id":"hex=(hex:String)-instance-method","name":"hex=","doc":"The hexadecimal string representation of the number.","summary":"

The hexadecimal string representation of the number.

","abstract":false,"args":[{"name":"hex","external_name":"hex","restriction":"String"}],"args_string":"(hex : String)","args_html":"(hex : String)","location":{"filename":"src/secp256k1/num.cr","line_number":27,"url":null},"def":{"name":"hex=","args":[{"name":"hex","external_name":"hex","restriction":"String"}],"visibility":"Public","body":"@hex = hex"}},{"html_id":"to_big:BigInt-instance-method","name":"to_big","doc":"Returns a big-integer representation of the number.\n\n```\nNum.new(Bytes[137]).to_big\n# => 137\n```","summary":"

Returns a big-integer representation of the number.

","abstract":false,"location":{"filename":"src/secp256k1/num.cr","line_number":156,"url":null},"def":{"name":"to_big","return_type":"BigInt","visibility":"Public","body":"@dec"}},{"html_id":"to_bytes:Bytes-instance-method","name":"to_bytes","doc":"Returns a binary byte-slice representation of the number.\n\n```\nNum.new(\"0x89\").to_bytes\n# => Bytes[137]\n```","summary":"

Returns a binary byte-slice representation of the number.

","abstract":false,"location":{"filename":"src/secp256k1/num.cr","line_number":166,"url":null},"def":{"name":"to_bytes","return_type":"Bytes","visibility":"Public","body":"@bin"}},{"html_id":"to_hex:String-instance-method","name":"to_hex","doc":"Returns an unprefixed hexadecimal string representation.\n\n```\nNum.new(Bytes[137]).to_hex\n# => \"89\"\n```","summary":"

Returns an unprefixed hexadecimal string representation.

","abstract":false,"location":{"filename":"src/secp256k1/num.cr","line_number":119,"url":null},"def":{"name":"to_hex","return_type":"String","visibility":"Public","body":"@hex"}},{"html_id":"to_prefixed_hex:String-instance-method","name":"to_prefixed_hex","doc":"Returns an `0x`-prefixed hexadecimal string representation.\n\n```\nNum.new(Bytes[137]).to_prefixed_hex\n# => \"0x89\"\n```","summary":"

Returns an 0x-prefixed hexadecimal string representation.

","abstract":false,"location":{"filename":"src/secp256k1/num.cr","line_number":129,"url":null},"def":{"name":"to_prefixed_hex","return_type":"String","visibility":"Public","body":"\"0x#{@hex}\""}},{"html_id":"to_zpadded_bytes(length=32):Bytes-instance-method","name":"to_zpadded_bytes","doc":"Returns a z-padded byte-slice binary representation.\n\nParameters:\n* `length` (`Int`): the byte-size of the final z-padded slice (default `32`).\n\n```\nNum.new(Bytes[137]).to_zpadded_bytes\n# => Bytes[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 137]\n```","summary":"

Returns a z-padded byte-slice binary representation.

","abstract":false,"args":[{"name":"length","default_value":"32","external_name":"length","restriction":""}],"args_string":"(length = 32) : Bytes","args_html":"(length = 32) : Bytes","location":{"filename":"src/secp256k1/num.cr","line_number":179,"url":null},"def":{"name":"to_zpadded_bytes","args":[{"name":"length","default_value":"32","external_name":"length","restriction":""}],"return_type":"Bytes","visibility":"Public","body":"zpadded_bytes = @bin\nwhile zpadded_bytes.size < length\n zpadded_bytes = Util.concat_bytes(Bytes[0], zpadded_bytes)\nend\nzpadded_bytes\n"}},{"html_id":"to_zpadded_hex(length=32):String-instance-method","name":"to_zpadded_hex","doc":"Returns a z-padded hexadecimal string representation.\n\nParameters:\n* `length` (`Int`): the byte-size of the final z-padded hex-string (default `32`).\n\n```\nNum.new(Bytes[137]).to_zpadded_hex\n# => \"0000000000000000000000000000000000000000000000000000000000000089\"\n```","summary":"

Returns a z-padded hexadecimal string representation.

","abstract":false,"args":[{"name":"length","default_value":"32","external_name":"length","restriction":""}],"args_string":"(length = 32) : String","args_html":"(length = 32) : String","location":{"filename":"src/secp256k1/num.cr","line_number":142,"url":null},"def":{"name":"to_zpadded_hex","args":[{"name":"length","default_value":"32","external_name":"length","restriction":""}],"return_type":"String","visibility":"Public","body":"zpadded_hex = @hex\nwhile zpadded_hex.size < (length * 2)\n zpadded_hex = \"0#{zpadded_hex}\"\nend\nzpadded_hex\n"}}]},{"html_id":"secp256k1/Secp256k1/Point","path":"Secp256k1/Point.html","kind":"class","full_name":"Secp256k1::Point","name":"Point","abstract":false,"superclass":{"html_id":"secp256k1/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"secp256k1/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"secp256k1/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/secp256k1/point.cr","line_number":30,"url":null}],"repository_name":"secp256k1","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"secp256k1/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"Provides a point in the two-dimensional space of any elliptic curve.\nIn most cases, such a point on a given curve represents a public key.\nHowever, for keypairs, a `Key` type shall be used!\n\nProperties:\n* `x` (`Num`): the position on the x-axis.\n* `y` (`Num`): the position on the y-axis.","summary":"

Provides a point in the two-dimensional space of any elliptic curve.

","constructors":[{"html_id":"new(x:Num,y:Num)-class-method","name":"new","doc":"Provides a public point in the two-dimensional space on the given `Secp256k1`\nelliptic curve by passing the x- and y-coordinates (public key).\n\nParameters:\n* `x` (`Num`): the position on the x-axis.\n* `y` (`Num`): the position on the y-axis.\n\n```\nx = Num.new \"efc4f8d8bfc778463e4d4916d88bf3f057e6dc96cb2adc26dfb91959c4bef4a5\"\ny = Num.new \"cecd9a83fefafcb3cf99fde0c340bbe2fed9cdd0d25b53f4e08254acefb69ae0\"\nPoint.new x, y\n# => #,\n# @y=#>\n```","summary":"

Provides a public point in the two-dimensional space on the given Secp256k1 elliptic curve by passing the x- and y-coordinates (public key).

","abstract":false,"args":[{"name":"x","external_name":"x","restriction":"Num"},{"name":"y","external_name":"y","restriction":"Num"}],"args_string":"(x : Num, y : Num)","args_html":"(x : Num, y : Num)","location":{"filename":"src/secp256k1/point.cr","line_number":58,"url":null},"def":{"name":"new","args":[{"name":"x","external_name":"x","restriction":"Num"},{"name":"y","external_name":"y","restriction":"Num"}],"visibility":"Public","body":"_ = allocate\n_.initialize(x, y)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}},{"html_id":"new(priv:Num)-class-method","name":"new","doc":"Provides a public point in the two-dimensional space on the given `Secp256k1`\nelliptic curve by passing a random number (private key). Note, that the\nprivate key will be consumed by this constructor and should only be used\nto retrieve a public key. To manage keypairs, use the `Key` type instead.\n\nParameters:\n* `priv` (`Num`): the random number giving access to the point.\n\n```\npriv = Num.new \"e50932676c9901f259659d62f0c56fd899feca3f57ecab147a5ef8a0b59defc3\"\nPoint.new priv\n# => #,\n# @y=#>\n```","summary":"

Provides a public point in the two-dimensional space on the given Secp256k1 elliptic curve by passing a random number (private key).

","abstract":false,"args":[{"name":"priv","external_name":"priv","restriction":"Num"}],"args_string":"(priv : Num)","args_html":"(priv : Num)","location":{"filename":"src/secp256k1/point.cr","line_number":84,"url":null},"def":{"name":"new","args":[{"name":"priv","external_name":"priv","restriction":"Num"}],"visibility":"Public","body":"_ = allocate\n_.initialize(priv)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}},{"html_id":"new(pub:String)-class-method","name":"new","doc":"Provides a public point in the two-dimensional space on the given `Secp256k1`\nelliptic curve by passing a compressed or uncompressed public key.\n\nParameters:\n* `pub` (`String`): the public key string (compressed or uncompressed).\n\n```\npub = \"03aff8674d6b96a6c58dbab08b903565363271308888340a2caddf88e56165930f\"\nPoint.new pub\n# => #,\n# @y=#>\n```","summary":"

Provides a public point in the two-dimensional space on the given Secp256k1 elliptic curve by passing a compressed or uncompressed public key.

","abstract":false,"args":[{"name":"pub","external_name":"pub","restriction":"String"}],"args_string":"(pub : String)","args_html":"(pub : String)","location":{"filename":"src/secp256k1/point.cr","line_number":109,"url":null},"def":{"name":"new","args":[{"name":"pub","external_name":"pub","restriction":"String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(pub)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"html_id":"compressed:String-instance-method","name":"compressed","doc":"Returns a prefixed, compressed public key string for the given point\nin the format `prefix|x|y`.\n\n```\npriv = Num.new \"e50932676c9901f259659d62f0c56fd899feca3f57ecab147a5ef8a0b59defc3\"\nPoint.new(priv).compressed\n# => \"03aff8674d6b96a6c58dbab08b903565363271308888340a2caddf88e56165930f\"\n```","summary":"

Returns a prefixed, compressed public key string for the given point in the format prefix|x|y.

","abstract":false,"location":{"filename":"src/secp256k1/point.cr","line_number":161,"url":null},"def":{"name":"compressed","return_type":"String","visibility":"Public","body":"prefix = 2 + (@y.to_big % 2)\nprefix = \"0#{prefix}\"\n\"#{prefix}#{@x.to_zpadded_hex}\"\n"}},{"html_id":"uncompressed:String-instance-method","name":"uncompressed","doc":"Returns a prefixed, uncompressed public key string for the given point\nin the format `04|x|y`.\n\n```\npriv = Num.new \"e50932676c9901f259659d62f0c56fd899feca3f57ecab147a5ef8a0b59defc3\"\nPoint.new(priv).uncompressed\n# => \"04aff8674d6b96a6c58dbab08b903565363271308888340a2caddf88e56165930f21f4c49cfe90da39c254a51b8ee8afcdd8c02dd566f13582c23e104c7ed5936b\"\n```","summary":"

Returns a prefixed, uncompressed public key string for the given point in the format 04|x|y.

","abstract":false,"location":{"filename":"src/secp256k1/point.cr","line_number":148,"url":null},"def":{"name":"uncompressed","return_type":"String","visibility":"Public","body":"prefix = \"04\"\n\"#{prefix}#{@x.to_zpadded_hex}#{@y.to_zpadded_hex}\"\n"}},{"html_id":"x:Num-instance-method","name":"x","doc":"The position on the x-axis.","summary":"

The position on the x-axis.

","abstract":false,"location":{"filename":"src/secp256k1/point.cr","line_number":32,"url":null},"def":{"name":"x","return_type":"Num","visibility":"Public","body":"@x"}},{"html_id":"x=(x:Num)-instance-method","name":"x=","doc":"The position on the x-axis.","summary":"

The position on the x-axis.

","abstract":false,"args":[{"name":"x","external_name":"x","restriction":"Num"}],"args_string":"(x : Num)","args_html":"(x : Num)","location":{"filename":"src/secp256k1/point.cr","line_number":32,"url":null},"def":{"name":"x=","args":[{"name":"x","external_name":"x","restriction":"Num"}],"visibility":"Public","body":"@x = x"}},{"html_id":"y:Num-instance-method","name":"y","doc":"The position on the y-axis.","summary":"

The position on the y-axis.

","abstract":false,"location":{"filename":"src/secp256k1/point.cr","line_number":35,"url":null},"def":{"name":"y","return_type":"Num","visibility":"Public","body":"@y"}},{"html_id":"y=(y:Num)-instance-method","name":"y=","doc":"The position on the y-axis.","summary":"

The position on the y-axis.

","abstract":false,"args":[{"name":"y","external_name":"y","restriction":"Num"}],"args_string":"(y : Num)","args_html":"(y : Num)","location":{"filename":"src/secp256k1/point.cr","line_number":35,"url":null},"def":{"name":"y=","args":[{"name":"y","external_name":"y","restriction":"Num"}],"visibility":"Public","body":"@y = y"}}]},{"html_id":"secp256k1/Secp256k1/Signature","path":"Secp256k1/Signature.html","kind":"class","full_name":"Secp256k1::Signature","name":"Signature","abstract":false,"superclass":{"html_id":"secp256k1/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"secp256k1/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"secp256k1/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/secp256k1/signature.cr","line_number":22,"url":null}],"repository_name":"secp256k1","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"secp256k1/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"Provides an ECDSA Signature containing the random point `r`, the\nsignature proof `s`, and the recovery id or `v` value.\n\nProperties:\n* `r` (`Num`): the `x` coordinate of a random point `R` on the curve.\n* `s` (`Num`): the signature proof of a message.\n* `v` (`Num`): the recovery id or `v` value.","summary":"

Provides an ECDSA Signature containing the random point #r, the signature proof #s, and the recovery id or #v value.

","constructors":[{"html_id":"new(r:Num,s:Num,v:Num)-class-method","name":"new","doc":"Provides an ECDSA Signature containing the random point `r`, the\nsignature proof `s`, and the recovery id or `v` value.\n\nParameters:\n* `r` (`Num`): the `x` coordinate of a random point `R` on the curve.\n* `s` (`Num`): the signature proof of a message.\n* `v` (`Num`): the recovery id or `v` value.\n\n```\nr = Num.new \"efc4f8d8bfc778463e4d4916d88bf3f057e6dc96cb2adc26dfb91959c4bef4a5\"\ns = Num.new \"cecd9a83fefafcb3cf99fde0c340bbe2fed9cdd0d25b53f4e08254acefb69ae0\"\nv = Num.new \"00\"\nSignature.new r, s, v\n# => #,\n# @s=#,\n# @v=#>\n```","summary":"

Provides an ECDSA Signature containing the random point #r, the signature proof #s, and the recovery id or #v value.

","abstract":false,"args":[{"name":"r","external_name":"r","restriction":"Num"},{"name":"s","external_name":"s","restriction":"Num"},{"name":"v","external_name":"v","restriction":"Num"}],"args_string":"(r : Num, s : Num, v : Num)","args_html":"(r : Num, s : Num, v : Num)","location":{"filename":"src/secp256k1/signature.cr","line_number":59,"url":null},"def":{"name":"new","args":[{"name":"r","external_name":"r","restriction":"Num"},{"name":"s","external_name":"s","restriction":"Num"},{"name":"v","external_name":"v","restriction":"Num"}],"visibility":"Public","body":"_ = allocate\n_.initialize(r, s, v)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"html_id":"compact:String-instance-method","name":"compact","doc":"Returns a compact `String` containing the concatenated signature\nin the form `r|s|v`.\n\n```\nr = Num.new \"efc4f8d8bfc778463e4d4916d88bf3f057e6dc96cb2adc26dfb91959c4bef4a5\"\ns = Num.new \"cecd9a83fefafcb3cf99fde0c340bbe2fed9cdd0d25b53f4e08254acefb69ae0\"\nv = Num.new \"00\"\nSignature.new(r, s, v).compact\n# => \"efc4f8d8bfc778463e4d4916d88bf3f057e6dc96cb2adc26dfb91959c4bef4a5cecd9a83fefafcb3cf99fde0c340bbe2fed9cdd0d25b53f4e08254acefb69ae000\"\n```","summary":"

Returns a compact String containing the concatenated signature in the form r|s|v.

","abstract":false,"location":{"filename":"src/secp256k1/signature.cr","line_number":75,"url":null},"def":{"name":"compact","return_type":"String","visibility":"Public","body":"\"#{r.to_zpadded_hex}#{s.to_zpadded_hex}#{v.to_hex}\""}},{"html_id":"r:Num-instance-method","name":"r","doc":"The `x` coordinate of a random point `R` on the curve.","summary":"

The x coordinate of a random point R on the curve.

","abstract":false,"location":{"filename":"src/secp256k1/signature.cr","line_number":24,"url":null},"def":{"name":"r","return_type":"Num","visibility":"Public","body":"@r"}},{"html_id":"r=(r:Num)-instance-method","name":"r=","doc":"The `x` coordinate of a random point `R` on the curve.","summary":"

The x coordinate of a random point R on the curve.

","abstract":false,"args":[{"name":"r","external_name":"r","restriction":"Num"}],"args_string":"(r : Num)","args_html":"(r : Num)","location":{"filename":"src/secp256k1/signature.cr","line_number":24,"url":null},"def":{"name":"r=","args":[{"name":"r","external_name":"r","restriction":"Num"}],"visibility":"Public","body":"@r = r"}},{"html_id":"s:Num-instance-method","name":"s","doc":"The signature proof of a message.","summary":"

The signature proof of a message.

","abstract":false,"location":{"filename":"src/secp256k1/signature.cr","line_number":27,"url":null},"def":{"name":"s","return_type":"Num","visibility":"Public","body":"@s"}},{"html_id":"s=(s:Num)-instance-method","name":"s=","doc":"The signature proof of a message.","summary":"

The signature proof of a message.

","abstract":false,"args":[{"name":"s","external_name":"s","restriction":"Num"}],"args_string":"(s : Num)","args_html":"(s : Num)","location":{"filename":"src/secp256k1/signature.cr","line_number":27,"url":null},"def":{"name":"s=","args":[{"name":"s","external_name":"s","restriction":"Num"}],"visibility":"Public","body":"@s = s"}},{"html_id":"v:Num-instance-method","name":"v","doc":"The recovery id or `v` value.","summary":"

The recovery id or #v value.

","abstract":false,"location":{"filename":"src/secp256k1/signature.cr","line_number":30,"url":null},"def":{"name":"v","return_type":"Num","visibility":"Public","body":"@v"}},{"html_id":"v=(v:Num)-instance-method","name":"v=","doc":"The recovery id or `v` value.","summary":"

The recovery id or #v value.

","abstract":false,"args":[{"name":"v","external_name":"v","restriction":"Num"}],"args_string":"(v : Num)","args_html":"(v : Num)","location":{"filename":"src/secp256k1/signature.cr","line_number":30,"url":null},"def":{"name":"v=","args":[{"name":"v","external_name":"v","restriction":"Num"}],"visibility":"Public","body":"@v = v"}}]},{"html_id":"secp256k1/Secp256k1/Util","path":"Secp256k1/Util.html","kind":"module","full_name":"Secp256k1::Util","name":"Util","abstract":false,"locations":[{"filename":"src/secp256k1/util.cr","line_number":17,"url":null}],"repository_name":"secp256k1","program":false,"enum":false,"alias":false,"const":false,"extended_modules":[{"html_id":"secp256k1/Secp256k1/Util","kind":"module","full_name":"Secp256k1::Util","name":"Util"}],"namespace":{"html_id":"secp256k1/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"Provides a collection of utilities for convenience, e.g., to bind\nrelevant hashing algorithms, or to concatenate byte slices.","summary":"

Provides a collection of utilities for convenience, e.g., to bind relevant hashing algorithms, or to concatenate byte slices.

","instance_methods":[{"html_id":"concat_bytes(x:Bytes,y:Bytes):Bytes-instance-method","name":"concat_bytes","doc":"Concatenates two byte slices in the order provided, i.e., `x|y`.\n\nParameters:\n* `x` (`Bytes`): a byte slice.\n* `y` (`Bytes`): another byte slice.\n\nReturns a concatenated `Bytes` slice.\n\n```\nUtil.concat_bytes Bytes[1, 2, 3], Bytes[9, 8, 7]\n# => Bytes[1, 2, 3, 9, 8, 7]\n```","summary":"

Concatenates two byte slices in the order provided, i.e., x|y.

","abstract":false,"args":[{"name":"x","external_name":"x","restriction":"Bytes"},{"name":"y","external_name":"y","restriction":"Bytes"}],"args_string":"(x : Bytes, y : Bytes) : Bytes","args_html":"(x : Bytes, y : Bytes) : Bytes","location":{"filename":"src/secp256k1/util.cr","line_number":177,"url":null},"def":{"name":"concat_bytes","args":[{"name":"x","external_name":"x","restriction":"Bytes"},{"name":"y","external_name":"y","restriction":"Bytes"}],"return_type":"Bytes","visibility":"Public","body":"z = IO::Memory.new(x.bytesize + y.bytesize)\nx.each do |b|\n z.write_bytes(UInt8.new(b))\nend\ny.each do |b|\n z.write_bytes(UInt8.new(b))\nend\nreturn z.to_slice\n"}},{"html_id":"deterministic_k(priv:Num,hash:Num,order=N):Num-instance-method","name":"deterministic_k","doc":"Provides a deterministic secret based on private key and message hash\nas defined in RFC-6979.\n\nRef: [datatracker.ietf.org/doc/html/rfc6979](https://datatracker.ietf.org/doc/html/rfc6979)\n\nParameters:\n* `priv` (`Num`): the private key or secret number.\n* `hash` (`Num`): the message hash or arbirtrary data hash.\n* `order` (`Num`): the order of the curve over `G` (default `N`).\n\nReturns a deterministically random number of type `Num`.\n\n```\npriv = Num.new \"3b74fcc0b0c419a00d2d9e88b15fbd99e03920138da22e2a00c327b88d24cf45\"\nhash = Util.sha256 \"Henlo, Wordl\"\nUtil.deterministic_k(priv, hash)\n# => #\n```","summary":"

Provides a deterministic secret based on private key and message hash as defined in RFC-6979.

","abstract":false,"args":[{"name":"priv","external_name":"priv","restriction":"Num"},{"name":"hash","external_name":"hash","restriction":"Num"},{"name":"order","default_value":"N","external_name":"order","restriction":""}],"args_string":"(priv : Num, hash : Num, order = N) : Num","args_html":"(priv : Num, hash : Num, order = N) : Num","location":{"filename":"src/secp256k1/util.cr","line_number":135,"url":null},"def":{"name":"deterministic_k","args":[{"name":"priv","external_name":"priv","restriction":"Num"},{"name":"hash","external_name":"hash","restriction":"Num"},{"name":"order","default_value":"N","external_name":"order","restriction":""}],"return_type":"Num","visibility":"Public","body":"order_size = order.hex.size // 2\nv = Num.new(Bytes.new(order_size, 1))\nk = Num.new(Bytes.new(order_size, 0))\nconcat = Util.concat_bytes(v.bin, Bytes[0])\nconcat = Util.concat_bytes(concat, priv.bin)\nconcat = Util.concat_bytes(concat, hash.bin)\nk = OpenSSL::HMAC.digest(:sha256, k.bin, concat)\nv = OpenSSL::HMAC.digest(:sha256, k, v.bin)\nconcat = Util.concat_bytes(v, Bytes[0])\nconcat = Util.concat_bytes(concat, priv.bin)\nconcat = Util.concat_bytes(concat, hash.bin)\nk = OpenSSL::HMAC.digest(:sha256, k, concat)\nv = OpenSSL::HMAC.digest(:sha256, k, v)\nwhile true\n t = IO::Memory.new.to_slice\n while t.size < order_size\n v = OpenSSL::HMAC.digest(:sha256, k, v)\n t = Util.concat_bytes(t, v)\n end\n secret = Num.new(t)\n if secret.dec < order.dec && secret.dec > 0\n return secret\n end\n increment = Util.concat_bytes(v, Bytes[0])\n k = OpenSSL::HMAC.digest(:sha256, k, increment)\n v = OpenSSL::HMAC.digest(:sha256, k, v)\nend\n"}},{"html_id":"keccak(data:Num|String,entropy=256):Num-instance-method","name":"keccak","doc":"Operating a Keccak hash on a binary/number or string literal.\n\nParameters:\n* `data` (`Num | String`): the binary numeric or string literal to be hashed.\n* `entropy` (`Int32`): the required entropy (default `256`).\n\nReturns a `Num` representing the Keccak hash.\n\n```\nUtil.keccak(Num.new \"0xdeadbeef\").hex\n# => \"d4fd4e189132273036449fc9e11198c739161b4c0116a9a2dccdfa1c492006f1\"\n\nUtil.keccak(\"0xdeadbeef\").hex\n# => \"4f440a001006a49f24a7de53c04eca3f79aef851ac58e460c9630d044277c8b0\"\n```","summary":"

Operating a Keccak hash on a binary/number or string literal.

","abstract":false,"args":[{"name":"data","external_name":"data","restriction":"Num | String"},{"name":"entropy","default_value":"256","external_name":"entropy","restriction":""}],"args_string":"(data : Num | String, entropy = 256) : Num","args_html":"(data : Num | String, entropy = 256) : Num","location":{"filename":"src/secp256k1/util.cr","line_number":35,"url":null},"def":{"name":"keccak","args":[{"name":"data","external_name":"data","restriction":"Num | String"},{"name":"entropy","default_value":"256","external_name":"entropy","restriction":""}],"return_type":"Num","visibility":"Public","body":"keccak = Digest::Keccak3.new(entropy)\nif data.is_a?(String)\n return Num.new((keccak.update(data)).hexdigest)\nelse\n return Num.new((keccak.update(data.to_bytes)).hexdigest)\nend\n"}},{"html_id":"ripemd160(data:Num|String):Num-instance-method","name":"ripemd160","doc":"Operating a RIPEMD-160 hash on a binary/number or string literal.\n\nParameters:\n* `data` (`Num | String`): the binary numeric or string literal to be hashed.\n\nReturns a `Num` representing the RIPEMD hash.\n\n```\nUtil.ripemd160(Num.new \"0xdeadbeef\").hex\n# => \"226821c2f5423e11fe9af68bd285c249db2e4b5a\"\n\nUtil.ripemd160(\"0xdeadbeef\").hex\n# => \"4caf817f14e84b564e47afd19966e5d123ee0183\"\n```","summary":"

Operating a RIPEMD-160 hash on a binary/number or string literal.

","abstract":false,"args":[{"name":"data","external_name":"data","restriction":"Num | String"}],"args_string":"(data : Num | String) : Num","args_html":"(data : Num | String) : Num","location":{"filename":"src/secp256k1/util.cr","line_number":105,"url":null},"def":{"name":"ripemd160","args":[{"name":"data","external_name":"data","restriction":"Num | String"}],"return_type":"Num","visibility":"Public","body":"ripemd = OpenSSL::Digest.new(\"RIPEMD160\")\nif data.is_a?(String)\n return Num.new((ripemd.update(data)).final.hexstring)\nelse\n return Num.new((ripemd.update(data.to_bytes)).final.hexstring)\nend\n"}},{"html_id":"sha256(data:Num|String):Num-instance-method","name":"sha256","doc":"Operating a SHA2-256 hash on a binary/number or string literal.\n\nParameters:\n* `data` (`Num | String`): the binary numeric or string literal to be hashed.\n\nReturns a `Num` representing the SHA2 hash.\n\n```\nUtil.sha256(Num.new \"0xdeadbeef\").hex\n# => \"5f78c33274e43fa9de5659265c1d917e25c03722dcb0b8d27db8d5feaa813953\"\n\nUtil.sha256(\"0xdeadbeef\").hex\n# => \"4142710b9b4caaeb000b8e5de271bbebac7f509aab2f5e61d1ed1958bfe6d583\"\n```","summary":"

Operating a SHA2-256 hash on a binary/number or string literal.

","abstract":false,"args":[{"name":"data","external_name":"data","restriction":"Num | String"}],"args_string":"(data : Num | String) : Num","args_html":"(data : Num | String) : Num","location":{"filename":"src/secp256k1/util.cr","line_number":82,"url":null},"def":{"name":"sha256","args":[{"name":"data","external_name":"data","restriction":"Num | String"}],"return_type":"Num","visibility":"Public","body":"sha2 = OpenSSL::Digest.new(\"SHA256\")\nif data.is_a?(String)\n return Num.new((sha2.update(data)).final.hexstring)\nelse\n return Num.new((sha2.update(data.to_bytes)).final.hexstring)\nend\n"}},{"html_id":"sha3(data:Num|String,entropy=256):Num-instance-method","name":"sha3","doc":"Operating a SHA3 hash on a binary/number or string literal.\n\nParameters:\n* `data` (`Num | String`): the binary numeric or string literal to be hashed.\n* `entropy` (`Int32`): the required entropy (default `256`).\n\nReturns a `Num` representing the SHA3 hash.\n\n```\nUtil.sha3(Num.new \"0xdeadbeef\").hex\n# => \"352b82608dad6c7ac3dd665bc2666e5d97803cb13f23a1109e2105e93f42c448\"\n\nUtil.sha3(\"0xdeadbeef\").hex\n# => \"c12811e13ed75afe3e0945ef34e8a25b9d321a46e131c6463731de25a21b39eb\"\n```","summary":"

Operating a SHA3 hash on a binary/number or string literal.

","abstract":false,"args":[{"name":"data","external_name":"data","restriction":"Num | String"},{"name":"entropy","default_value":"256","external_name":"entropy","restriction":""}],"args_string":"(data : Num | String, entropy = 256) : Num","args_html":"(data : Num | String, entropy = 256) : Num","location":{"filename":"src/secp256k1/util.cr","line_number":59,"url":null},"def":{"name":"sha3","args":[{"name":"data","external_name":"data","restriction":"Num | String"},{"name":"entropy","default_value":"256","external_name":"entropy","restriction":""}],"return_type":"Num","visibility":"Public","body":"sha3 = Digest::SHA3.new(entropy)\nif data.is_a?(String)\n return Num.new((sha3.update(data)).hexdigest)\nelse\n return Num.new((sha3.update(data.to_bytes)).hexdigest)\nend\n"}}]}]}]}} \ No newline at end of file diff --git a/docs/search-index.js b/docs/search-index.js index a1b2652..9766f15 100644 --- a/docs/search-index.js +++ b/docs/search-index.js @@ -1 +1 @@ -crystal_doc_search_index_callback({"repository_name":"secp256k1","body":"# secp256k1.cr\n\n[![Build Status](https://img.shields.io/github/workflow/status/q9f/secp256k1.cr/Nightly)](https://github.com/q9f/secp256k1.cr/actions)\n[![Code Coverage](https://codecov.io/gh/q9f/secp256k1.cr/branch/main/graph/badge.svg?token=ngxRs9HdJA)](https://codecov.io/gh/q9f/secp256k1.cr)\n[![Documentation](https://img.shields.io/badge/docs-html-black)](https://q9f.github.io/secp256k1.cr/)\n[![Release](https://img.shields.io/github/v/release/q9f/secp256k1.cr?include_prereleases&color=black)](https://github.com/q9f/secp256k1.cr/releases/latest)\n[![Language](https://img.shields.io/github/languages/top/q9f/secp256k1.cr?color=black)](https://github.com/q9f/secp256k1.cr/search?l=crystal)\n[![License](https://img.shields.io/github/license/q9f/secp256k1.cr.svg?color=black)](LICENSE)\n\nA library implementing the `Secp256k1` elliptic curve natively in pure Crystal.\n`Secp256k1` is the elliptic curve used in the public-private-key cryptography required by `Bitcoin`, `Ethereum`, and `Polkadot`.\n\nThis library allows for:\n* providing a `Secp256k1` cryptographic context, see `Secp256k1::Context`\n* managing `Secp256k1` signatures and verification, see `Secp256k1::Signature`\n* managing private-public keypairs, see `Secp256k1::Key`\n* generating public keys, see `Secp256k1::Point`\n* generating private keys, see `Secp256k1::Num`\n\n# Installation\n\nAdd the `Secp256k1` library to your `shard.yml`\n\n```yaml\ndependencies:\n secp256k1:\n github: q9f/secp256k1.cr\n version: \"~> 0.5\"\n```\n\n# Usage\n\nImport and expose the `Secp256k1` module.\n\n```crystal\nrequire \"secp256k1\"\n```\n\nThis library exposes the following modules and classes (in logical order):\n\n* `Secp256k1`: necessary constants and data structures, including:\n - `Secp256k1::Num`: for managing big numerics (private keys)\n - `Secp256k1::Point`: for handling of elliptic curve points (public keys)\n - `Secp256k1::Key`: for managing private-public keypairs (accounts)\n - `Secp256k1::Signature`: for handling ECDSA signatures (r, s, v)\n* `Secp256k1::Context`: providing a cryptographic context for signing and verification\n* `Secp256k1::Curve`: the entire core mathematics behind the elliptic curve cryptography\n* `Secp256k1::Util`: binding of various hashing algorithms for convenience\n\nBasic usage:\n\n```crystal\n# generates a new, random keypair\nkey = Secp256k1::Key.new\n# => #,\n# @public_key=#,\n# @y=#>>\n\n# gets the private key\nkey.private_hex\n# => \"3ccf84820c20d5e8c536ba84c52ba410375b29b1812b5f7e722445c969a0fb30\"\n\n# gets the compressed public key with prefix\nkey.public_hex_compressed\n# => \"02cd4a8712ee6efc15b5abe37c0dbfa979d89c427d3fe24b076008decefe94dba2\"\n```\n\nSignature generation and verification:\n\n```crystal\n# sign a message with a private key\nctx = Secp256k1::Context.new\npriv = Secp256k1::Num.new \"1f0c122d41ff536b19bfd83537c0dfc290e45cd3c375a43237c8b8fff7ac8af7\"\nkey = Secp256k1::Key.new priv\nhash = Secp256k1::Util.sha256 \"Henlo, Wordl\"\nsig = ctx.sign key, hash\n# => #,\n# @s=#,\n# @v=#>\n\n# verify a signature with a public key\nr = Secp256k1::Num.new \"c4079db44240b7afe94985c69fc89602e33629fd9b8623d711c30ce6378b33df\"\ns = Secp256k1::Num.new \"6842c1b63c94bdb8e4f5ae88fb65f7a98b77b197c8323004fb47ef57fab29053\"\nv = Secp256k1::Num.new \"00\"\nsig = Secp256k1::Signature.new r, s, v\nhash = Secp256k1::Util.sha256 \"Henlo, Wordl\"\npubl = Secp256k1::Point.new \"0416008a369439f1a8a75cf974860bed5b10180518d6b1dd3ac847f423fd375d6aa29474394f0cd79d2ea543507d069e97339284f01bdbfd27392daec0ec553816\"\nctx.verify sig, hash, publ\n# => true\n```\n\n# Documentation\n\nThe full library documentation can be found here: [q9f.github.io/secp256k1.cr](https://q9f.github.io/secp256k1.cr/)\n\nGenerate a local copy with:\n\n```shell\ncrystal docs\n```\n\n# Testing\n\nThe library is entirely specified through tests in `./spec`; run:\n\n```shell\ncrystal spec --verbose\n```\n\n# Understand\n\nPrivate keys are just scalars (`Secp256k1::Num`) and public keys are points (`Secp256k1::Point`) with `x` and `y` coordinates.\n\nBitcoin public keys can be uncompressed `p|x|y` or compressed `p|x`. both come with a prefix `p` which is useless for uncompressed keys but necessary for compressed keys to recover the `y` coordinate on the `Secp256k1` elliptic curve field.\n\nEthereum public keys are uncompressed `x|y` without any prefix. The last 20 bytes slice of the `y` coordinate is actually used as address without any checksum. A checksum was later added in EIP-55 using a `keccak256` hash and indicating character capitalization.\n\nNeither Bitcoin nor Ethereum allow for recovering public keys from an address unless there exists a transaction with a valid signature on the blockchain.\n\n# Known issues\n\n_Note: this library should not be used in production without proper auditing. It should be considered slow and insecure._\n\n* This library is not constant time and might be subject to side-channel attacks. ([#4](https://github.com/q9f/secp256k1.cr/issues/4))\n* This library does unnecessary big-integer math and should someday rather correctly implement the `Secp256k1` prime field ([#5](https://github.com/q9f/secp256k1.cr/issues/5))\n* This library is slow in recovering signatures. Future versions should respect the recovery ID to quickly identify the correct public key from a signature.\n\nFound any other issue? Report it: [github.com/q9f/secp256k1.cr/issues](https://github.com/q9f/secp256k1.cr/issues)\n\n# Contribute\n\nCreate a pull request, and make sure tests and linter pass.\n\nThis pure crystal implementation is based on the python implementation [wobine/blackboard101](https://github.com/wobine/blackboard101) which is also used as reference to write tests against. It's a complete rewrite of the abandoned [packetzero/bitcoinutils](https://github.com/packetzero/bitcoinutils) for educational purposes.\n\nHonerable mention for the [bitcoin wiki](https://en.bitcoin.it/wiki/Main_Page) and the [ethereum stackexchange](https://ethereum.stackexchange.com/) for providing so many in-depth resources that supported this project in reimplementing everything.\n\nLicense: Apache License v2.0\n\nContributors: [**@q9f**](https://github.com/q9f/), [@cserb](https://github.com/cserb), [MrSorcus](https://github.com/MrSorcus)\n","program":{"html_id":"secp256k1/toplevel","path":"toplevel.html","kind":"module","full_name":"Top Level Namespace","name":"Top Level Namespace","abstract":false,"locations":[],"repository_name":"secp256k1","program":true,"enum":false,"alias":false,"const":false,"types":[{"html_id":"secp256k1/Secp256k1","path":"Secp256k1.html","kind":"module","full_name":"Secp256k1","name":"Secp256k1","abstract":false,"locations":[{"filename":"src/secp256k1.cr","line_number":35,"url":null},{"filename":"src/secp256k1/context.cr","line_number":22,"url":null},{"filename":"src/secp256k1/version.cr","line_number":21,"url":null}],"repository_name":"secp256k1","program":false,"enum":false,"alias":false,"const":false,"constants":[{"id":"G","name":"G","value":"Point.new(Num.new(\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\"), Num.new(\"483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8\"))","doc":"A commonly used base point `G` with coordinates `x` and `y`\nsatisfying `y^2 = x^3 + 7`.","summary":"

A commonly used base point G with coordinates x and y satisfying y^2 = x^3 + 7.

"},{"id":"N","name":"N","value":"Num.new(\"fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141\")","doc":"The order `n` of `G` defines the finite size of the Secp256k1 field `E`.","summary":"

The order n of G defines the finite size of the Secp256k1 field E.

"},{"id":"P","name":"P","value":"Num.new(\"fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f\")","doc":"The elliptic curve domain parameters over `F_p` associated with a\nKoblitz curve `Secp256k1` are specified by the sextuple\n`T = (p, a, b, G, n, h)` where the finite field `F_p` is defined by\nthe prime `p = 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1`.","summary":"

The elliptic curve domain parameters over F_p associated with a Koblitz curve Secp256k1 are specified by the sextuple T = (p, a, b, G, n, h) where the finite field F_p is defined by the prime p = 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1.

"},{"id":"VERSION","name":"VERSION","value":"\"0.5.0\"","doc":"The `VERSION` of the `Secp256k1` module.","summary":"

The VERSION of the Secp256k1 module.

"}],"doc":"Provides the `Secp256k1` module with the elliptic curve parameters\nused by the `Bitcoin`, `Ethereum`, and `Polkadot` blockchains. It's\nprimarily used to generate key-pairs as well as signing messages and\nrecoverying signatures.\n\nRef: [secg.org/sec2-v2.pdf](https://www.secg.org/sec2-v2.pdf)","summary":"

Provides the Secp256k1 module with the elliptic curve parameters used by the Bitcoin, Ethereum, and Polkadot blockchains.

","types":[{"html_id":"secp256k1/Secp256k1/Context","path":"Secp256k1/Context.html","kind":"class","full_name":"Secp256k1::Context","name":"Context","abstract":false,"superclass":{"html_id":"secp256k1/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"secp256k1/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"secp256k1/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/secp256k1/context.cr","line_number":22,"url":null}],"repository_name":"secp256k1","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"secp256k1/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"Provides a `Secp256k1` context to allow signing arbitrary data,\nrecovering public keys, and verifying signatures.\n\n```\nctx = Context.new\n# => #\n```","summary":"

Provides a Secp256k1 context to allow signing arbitrary data, recovering public keys, and verifying signatures.

","instance_methods":[{"html_id":"sign(key:Key,hash:Num):Signature-instance-method","name":"sign","doc":"Signs a message hash or any other arbitrary data with a given keypair.\n\nParameters:\n* `key` (`Key`): the keypair containing a secret to sign the data.\n* `hash` (`Num`): the message or arbirtrary data hash.\n\nReturns a `Signature` proving the given key signed the message hash.\n\n```\nctx = Context.new\nkey = Key.new Num.new \"1f0c122d41ff536b19bfd83537c0dfc290e45cd3c375a43237c8b8fff7ac8af7\"\nhash = Util.sha256 \"Henlo, Wordl\"\nsig = ctx.sign key, hash\n# => #,\n# @s=#,\n# @v=#>\n```","summary":"

Signs a message hash or any other arbitrary data with a given keypair.

","abstract":false,"args":[{"name":"key","external_name":"key","restriction":"Key"},{"name":"hash","external_name":"hash","restriction":"Num"}],"args_string":"(key : Key, hash : Num) : Signature","args_html":"(key : Key, hash : Num) : Signature","location":{"filename":"src/secp256k1/context.cr","line_number":50,"url":null},"def":{"name":"sign","args":[{"name":"key","external_name":"key","restriction":"Key"},{"name":"hash","external_name":"hash","restriction":"Num"}],"return_type":"Signature","visibility":"Public","body":"k = Util.deterministic_k(key.private_key, hash)\nhash = hash.to_big\npriv = key.private_key.to_big\npoint = Curve.mul(G, k)\nr = point.x.to_big % N.to_big\nk_inv = Curve.mod_inv(k, N)\ns = ((hash + (r * priv)) * k_inv.to_big) % N.to_big\nx_mag = point.x.to_big > N.to_big\ny_parity = (point.y.to_big % 2) == 0\nrec_id : Int8 = -1\nif (!y_parity) && x_mag\n rec_id = 3\nelse\n if y_parity && x_mag\n rec_id = 2\n else\n if (!y_parity) && (!x_mag)\n rec_id = 1\n else\n rec_id = 0\n end\n end\nend\nr = Num.new(r)\ns = Num.new(s)\nv = Num.new(BigInt.new(rec_id))\nSignature.new(r, s, v)\n"}},{"html_id":"verify(sig:Signature,hash:Num,publ:Point):Bool-instance-method","name":"verify","doc":"Verifies that a given signature for a given message hash matches\nthe provided public key.\n\nParameters:\n* `sig` (`Signature`): the signature to be verified.\n* `hash` (`Num`): the message or arbirtrary data hash.\n* `publ` (`Point`): the public key to match.\n\nReturns _true_ if the signature verifies.\n\n```\nctx = Context.new\nr = Num.new \"c4079db44240b7afe94985c69fc89602e33629fd9b8623d711c30ce6378b33df\"\ns = Num.new \"6842c1b63c94bdb8e4f5ae88fb65f7a98b77b197c8323004fb47ef57fab29053\"\nv = Num.new \"00\"\nsig = Signature.new r, s, v\nhash = Util.sha256 \"Henlo, Wordl\"\npubl = Point.new \"0416008a369439f1a8a75cf974860bed5b10180518d6b1dd3ac847f423fd375d6aa29474394f0cd79d2ea543507d069e97339284f01bdbfd27392daec0ec553816\"\nctx.verify sig, hash, publ\n# => true\n```","summary":"

Verifies that a given signature for a given message hash matches the provided public key.

","abstract":false,"args":[{"name":"sig","external_name":"sig","restriction":"Signature"},{"name":"hash","external_name":"hash","restriction":"Num"},{"name":"publ","external_name":"publ","restriction":"Point"}],"args_string":"(sig : Signature, hash : Num, publ : Point) : Bool","args_html":"(sig : Signature, hash : Num, publ : Point) : Bool","location":{"filename":"src/secp256k1/context.cr","line_number":97,"url":null},"def":{"name":"verify","args":[{"name":"sig","external_name":"sig","restriction":"Signature"},{"name":"hash","external_name":"hash","restriction":"Num"},{"name":"publ","external_name":"publ","restriction":"Point"}],"return_type":"Bool","visibility":"Public","body":"s_inv = Curve.mod_inv(sig.s, N)\np0 = Curve.mul(G, (hash.to_big * s_inv.to_big) % N.to_big)\np1 = Curve.mul(publ, (sig.r.to_big * s_inv.to_big) % N.to_big)\np = Curve.add(p0, p1)\nsig.r.to_big === p.x.to_big\n"}}]},{"html_id":"secp256k1/Secp256k1/Curve","path":"Secp256k1/Curve.html","kind":"module","full_name":"Secp256k1::Curve","name":"Curve","abstract":false,"locations":[{"filename":"src/secp256k1/curve.cr","line_number":18,"url":null}],"repository_name":"secp256k1","program":false,"enum":false,"alias":false,"const":false,"extended_modules":[{"html_id":"secp256k1/Secp256k1/Curve","kind":"module","full_name":"Secp256k1::Curve","name":"Curve"}],"namespace":{"html_id":"secp256k1/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"Implements 256-bit `Secp256k1` Koblitz elliptic curve operations.\n\nRef: [secg.org/sec2-v2.pdf](https://www.secg.org/sec2-v2.pdf)","summary":"

Implements 256-bit Secp256k1 Koblitz elliptic curve operations.

","instance_methods":[{"html_id":"add(p:Point,q:Point,prime=P):Point-instance-method","name":"add","doc":"Computes the elliptic curve jive addition of point `p(x, y)` and `q(x, y)`.\nIt _draws_ a line between `p` and `q` which will intersect the\ncurve in the point `r` which will be mirrored over the `x`-axis.\n\nParamters:\n* `p` (`Num`): the point `p(x, y)` to be used in the jive addition.\n* `q` (`Num`): the point `q(x, y)` to be used in the jive addition.\n* `prime` (`Num`): the prime number that shapes the field (default `P`).\n\nReturns a `Point` containing the result of the intersection.\n```\np = Point.new Num.new \"5cb1eec17e38b004a8fd90fa8e423432430f60d76c30bb33f4091243c029e86d\"\nq = Point.new Num.new \"7e17f60baa7b8dc8581a55f7be1ea263c6a88452cf3f0a3f710651767654946c\"\nCurve.add p, q\n# => #,\n# @y=#>\n```","summary":"

Computes the elliptic curve jive addition of point p(x, y) and q(x, y).

","abstract":false,"args":[{"name":"p","external_name":"p","restriction":"Point"},{"name":"q","external_name":"q","restriction":"Point"},{"name":"prime","default_value":"P","external_name":"prime","restriction":""}],"args_string":"(p : Point, q : Point, prime = P) : Point","args_html":"(p : Point, q : Point, prime = P) : Point","location":{"filename":"src/secp256k1/curve.cr","line_number":82,"url":null},"def":{"name":"add","args":[{"name":"p","external_name":"p","restriction":"Point"},{"name":"q","external_name":"q","restriction":"Point"},{"name":"prime","default_value":"P","external_name":"prime","restriction":""}],"return_type":"Point","visibility":"Public","body":"if prime.is_a?(Num)\n prime = prime.to_big\nend\np_x = p.x.to_big\np_y = p.y.to_big\nq_x = q.x.to_big\nq_y = q.y.to_big\nx_delta = q_x - p_x\nx_inv = mod_inv(x_delta)\ny_delta = q_y - p_y\nm = (y_delta * x_inv.to_big) % prime\nx = (((m * m) - p_x) - q_x) % prime\ny = ((m * (p_x - x)) - p_y) % prime\nx = Num.new(x)\ny = Num.new(y)\nPoint.new(x, y)\n"}},{"html_id":"double(p:Point,prime=P):Point-instance-method","name":"double","doc":"Computes the elliptic curve juke point doubling of `p(x, y)`.\nThis is a special case of addition where both points are the same.\nIt _draws_ a tangent line at `p` which will intersect the curve\nat point `r` which will be mirrored over the `x`-axis.\n\nParamters:\n* `p` (`Point`): the point `p(x, y)` to be used in the juke doubling.\n* `prime` (`Num`): the prime number that shapes the field (default `P`).\n\nReturns a `Point` as a result of the intersection.\n\n```\np = Point.new Num.new \"5cb1eec17e38b004a8fd90fa8e423432430f60d76c30bb33f4091243c029e86d\"\nCurve.double p\n# => #,\n# @y=#>\n```","summary":"

Computes the elliptic curve juke point doubling of p(x, y).

","abstract":false,"args":[{"name":"p","external_name":"p","restriction":"Point"},{"name":"prime","default_value":"P","external_name":"prime","restriction":""}],"args_string":"(p : Point, prime = P) : Point","args_html":"(p : Point, prime = P) : Point","location":{"filename":"src/secp256k1/curve.cr","line_number":123,"url":null},"def":{"name":"double","args":[{"name":"p","external_name":"p","restriction":"Point"},{"name":"prime","default_value":"P","external_name":"prime","restriction":""}],"return_type":"Point","visibility":"Public","body":"if prime.is_a?(Num)\n prime = prime.to_big\nend\np_x = p.x.to_big\np_y = p.y.to_big\nlam_numer = (3 * p_x) * p_x\nlam_denom = 2 * p_y\nlam_inv = mod_inv(Num.new(lam_denom))\nlam = (lam_numer * lam_inv.to_big) % prime\nx = ((lam * lam) - (2 * p_x)) % prime\ny = ((lam * (p_x - x)) - p_y) % prime\nx = Num.new(x)\ny = Num.new(y)\nPoint.new(x, y)\n"}},{"html_id":"mod_inv(a:Num|BigInt,prime=P):Num-instance-method","name":"mod_inv","doc":"Computes the elliptic curve modular multiplicative inverse of `a`.\n\nParemeters:\n* `a` (`Num | BigInt`): the integer that we want the modular inverse of.\n* `prime` (`Num`): the prime number that shapes the field (default `P`).\n\nReturns a `Num` containing the mod inverse.\n\n```\na = Num.new \"ea678c668356d16d8bf5c69f95c1055e39bd24174605f64846e27c3ae6a88d81\"\nCurve.mod_inv a\n# => #\n```","summary":"

Computes the elliptic curve modular multiplicative inverse of a.

","abstract":false,"args":[{"name":"a","external_name":"a","restriction":"Num | BigInt"},{"name":"prime","default_value":"P","external_name":"prime","restriction":""}],"args_string":"(a : Num | BigInt, prime = P) : Num","args_html":"(a : Num | BigInt, prime = P) : Num","location":{"filename":"src/secp256k1/curve.cr","line_number":37,"url":null},"def":{"name":"mod_inv","args":[{"name":"a","external_name":"a","restriction":"Num | BigInt"},{"name":"prime","default_value":"P","external_name":"prime","restriction":""}],"return_type":"Num","visibility":"Public","body":"if a.is_a?(Num)\n a = a.to_big\nend\nif prime.is_a?(Num)\n prime = prime.to_big\nend\nm_low = 1\nm_high = 0\nv_low = a % prime\nv_high = prime\nwhile v_low > 1\n v_ratio = v_high // v_low\n m_low_r = m_low * v_ratio\n v_low_r = v_low * v_ratio\n m = m_high - m_low_r\n v = v_high - v_low_r\n m_high = m_low\n v_high = v_low\n m_low = m\n v_low = v\nend\nNum.new(m_low % prime)\n"}},{"html_id":"mul(p:Point,s:Num|BigInt):Point-instance-method","name":"mul","doc":"Computes the elliptic curve sequence multiplication of point `p(x, y)`\nand a skalar `s`; with `s` being a private key within the elliptic\ncurve field size of `N`.\n\nParamters:\n* `p` (`Point`): the point `p(x, y)` to be used in the sequencing.\n* `s` (`Num | BigInt`): a skalar, in most cases a private key.\n\nReturns a `Point` as a result of the multiplication.\n\n```\np = Point.new Num.new \"5cb1eec17e38b004a8fd90fa8e423432430f60d76c30bb33f4091243c029e86d\"\ns = Num.new \"f51ad125548b7a283ebf15ab830a25c850d4d863078c48cc9993b79ee18ee11e\"\nCurve.mul p, s\n# => #,\n# @y=#>\n```","summary":"

Computes the elliptic curve sequence multiplication of point p(x, y) and a skalar s; with s being a private key within the elliptic curve field size of N.

","abstract":false,"args":[{"name":"p","external_name":"p","restriction":"Point"},{"name":"s","external_name":"s","restriction":"Num | BigInt"}],"args_string":"(p : Point, s : Num | BigInt) : Point","args_html":"(p : Point, s : Num | BigInt) : Point","location":{"filename":"src/secp256k1/curve.cr","line_number":162,"url":null},"def":{"name":"mul","args":[{"name":"p","external_name":"p","restriction":"Point"},{"name":"s","external_name":"s","restriction":"Num | BigInt"}],"return_type":"Point","visibility":"Public","body":"if s.is_a?(Num)\n s = s.to_big\nend\nif (s === 0) || s >= N.to_big\n raise(\"Invalid scalar: outside of Secp256k1 field dimension.\")\nend\ns_bin = s.to_s(2)\nq = p\ns_bin.each_char_with_index do |char, index|\n if index === 0\n next\n end\n q = double(q)\n if char === '1'\n q = add(q, p)\n end\nend\nq\n"}}]},{"html_id":"secp256k1/Secp256k1/Key","path":"Secp256k1/Key.html","kind":"class","full_name":"Secp256k1::Key","name":"Key","abstract":false,"superclass":{"html_id":"secp256k1/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"secp256k1/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"secp256k1/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/secp256k1/key.cr","line_number":21,"url":null}],"repository_name":"secp256k1","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"secp256k1/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"Provides a `Secp256k1` keypair containing a secret number (private key)\nand a public point on the elliptic curve (public key).\n\nProperties:\n* `private_key` (`Num`): the secret number representing the private key.\n* `public_key` (`Point`): the point on the elliptic curve representing the public key.","summary":"

Provides a Secp256k1 keypair containing a secret number (private key) and a public point on the elliptic curve (public key).

","constructors":[{"html_id":"new(priv:Num)-class-method","name":"new","doc":"Creates a public-private keypair from an existing private key.\n\nParameters:\n* `priv` (`Num`): the private key for the keypair.\n\n```\npriv = Num.new \"3ccf84820c20d5e8c536ba84c52ba410375b29b1812b5f7e722445c969a0fb30\"\nKey.new priv\n# => #,\n# @public_key=#,\n# @y=#>>\n```","summary":"

Creates a public-private keypair from an existing private key.

","abstract":false,"args":[{"name":"priv","external_name":"priv","restriction":"Num"}],"args_string":"(priv : Num)","args_html":"(priv : Num)","location":{"filename":"src/secp256k1/key.cr","line_number":74,"url":null},"def":{"name":"new","args":[{"name":"priv","external_name":"priv","restriction":"Num"}],"visibility":"Public","body":"_ = allocate\n_.initialize(priv)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}},{"html_id":"new-class-method","name":"new","doc":"Creates a new, random `Secp256k1` keypair.\n\n```\nKey.new\n# => #,\n# @public_key=#,\n# @y=#>>\n```","summary":"

Creates a new, random Secp256k1 keypair.

","abstract":false,"location":{"filename":"src/secp256k1/key.cr","line_number":46,"url":null},"def":{"name":"new","visibility":"Public","body":"_ = allocate\n_.initialize\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"html_id":"private_bytes:Bytes-instance-method","name":"private_bytes","doc":"Returns the private key as binary byte slice.\n\n```\nKey.new(Num.new \"3ccf84820c20d5e8c536ba84c52ba410375b29b1812b5f7e722445c969a0fb30\").private_bytes\n# => Bytes[60, 207, 132, 130, 12, 32, 213, 232, 197, 54, 186, 132, 197, 43, 164, 16, 55, 91, 41, 177, 129, 43, 95, 126, 114, 36, 69, 201, 105, 160, 251, 48]\n```","summary":"

Returns the private key as binary byte slice.

","abstract":false,"location":{"filename":"src/secp256k1/key.cr","line_number":95,"url":null},"def":{"name":"private_bytes","return_type":"Bytes","visibility":"Public","body":"@private_key.to_zpadded_bytes"}},{"html_id":"private_hex:String-instance-method","name":"private_hex","doc":"Returns the private key as hexadecimal string literal.\n\n```\nKey.new(Num.new \"3ccf84820c20d5e8c536ba84c52ba410375b29b1812b5f7e722445c969a0fb30\").private_hex\n# => \"3ccf84820c20d5e8c536ba84c52ba410375b29b1812b5f7e722445c969a0fb30\"\n```","summary":"

Returns the private key as hexadecimal string literal.

","abstract":false,"location":{"filename":"src/secp256k1/key.cr","line_number":85,"url":null},"def":{"name":"private_hex","return_type":"String","visibility":"Public","body":"@private_key.to_zpadded_hex"}},{"html_id":"private_key:Num-instance-method","name":"private_key","doc":"The secret number representing the private key.","summary":"

The secret number representing the private key.

","abstract":false,"location":{"filename":"src/secp256k1/key.cr","line_number":23,"url":null},"def":{"name":"private_key","return_type":"Num","visibility":"Public","body":"@private_key"}},{"html_id":"private_key=(private_key:Num)-instance-method","name":"private_key=","doc":"The secret number representing the private key.","summary":"

The secret number representing the private key.

","abstract":false,"args":[{"name":"private_key","external_name":"private_key","restriction":"Num"}],"args_string":"(private_key : Num)","args_html":"(private_key : Num)","location":{"filename":"src/secp256k1/key.cr","line_number":23,"url":null},"def":{"name":"private_key=","args":[{"name":"private_key","external_name":"private_key","restriction":"Num"}],"visibility":"Public","body":"@private_key = private_key"}},{"html_id":"public_bytes:Bytes-instance-method","name":"public_bytes","doc":"Returns the public key as uncompressed, binary byte slice.\n\n```\nKey.new(Num.new \"3ccf84820c20d5e8c536ba84c52ba410375b29b1812b5f7e722445c969a0fb30\").public_bytes\n# => Bytes[4, 205, 74, 135, 18, 238, 110, 252, 21, 181, 171, 227, 124, 13, 191, 169, 121, 216, 156, 66, 125, 63, 226, 75, 7, 96, 8, 222, 206, 254, 148, 219, 162, 129, 54, 61, 41, 142, 74, 64, 235, 203, 19, 241, 175, 168, 90, 11, 148, 185, 103, 242, 67, 238, 89, 165, 144, 16, 203, 93, 234, 240, 215, 182, 108]\n```","summary":"

Returns the public key as uncompressed, binary byte slice.

","abstract":false,"location":{"filename":"src/secp256k1/key.cr","line_number":125,"url":null},"def":{"name":"public_bytes","return_type":"Bytes","visibility":"Public","body":"(Num.new(@public_key.uncompressed)).to_bytes"}},{"html_id":"public_bytes_compressed:Bytes-instance-method","name":"public_bytes_compressed","doc":"Returns the public key as compressed, binary byte slice.\n\n```\nKey.new(Num.new \"3ccf84820c20d5e8c536ba84c52ba410375b29b1812b5f7e722445c969a0fb30\").public_bytes_compressed\n# => Bytes[2, 205, 74, 135, 18, 238, 110, 252, 21, 181, 171, 227, 124, 13, 191, 169, 121, 216, 156, 66, 125, 63, 226, 75, 7, 96, 8, 222, 206, 254, 148, 219, 162]\n```","summary":"

Returns the public key as compressed, binary byte slice.

","abstract":false,"location":{"filename":"src/secp256k1/key.cr","line_number":135,"url":null},"def":{"name":"public_bytes_compressed","return_type":"Bytes","visibility":"Public","body":"(Num.new(@public_key.compressed)).to_bytes"}},{"html_id":"public_hex:String-instance-method","name":"public_hex","doc":"Returns the public key as uncompressed, hexadecimal string literal.\n\n```\nKey.new(Num.new \"3ccf84820c20d5e8c536ba84c52ba410375b29b1812b5f7e722445c969a0fb30\").public_hex\n# => \"04cd4a8712ee6efc15b5abe37c0dbfa979d89c427d3fe24b076008decefe94dba281363d298e4a40ebcb13f1afa85a0b94b967f243ee59a59010cb5deaf0d7b66c\"\n```","summary":"

Returns the public key as uncompressed, hexadecimal string literal.

","abstract":false,"location":{"filename":"src/secp256k1/key.cr","line_number":105,"url":null},"def":{"name":"public_hex","return_type":"String","visibility":"Public","body":"@public_key.uncompressed"}},{"html_id":"public_hex_compressed:String-instance-method","name":"public_hex_compressed","doc":"Returns the public key as compressed, hexadecimal string literal.\n\n```\nKey.new(Num.new \"3ccf84820c20d5e8c536ba84c52ba410375b29b1812b5f7e722445c969a0fb30\").public_hex_compressed\n# => \"02cd4a8712ee6efc15b5abe37c0dbfa979d89c427d3fe24b076008decefe94dba2\"\n```","summary":"

Returns the public key as compressed, hexadecimal string literal.

","abstract":false,"location":{"filename":"src/secp256k1/key.cr","line_number":115,"url":null},"def":{"name":"public_hex_compressed","return_type":"String","visibility":"Public","body":"@public_key.compressed"}},{"html_id":"public_key:Point-instance-method","name":"public_key","doc":"The point on the elliptic curve representing the public key.","summary":"

The point on the elliptic curve representing the public key.

","abstract":false,"location":{"filename":"src/secp256k1/key.cr","line_number":25,"url":null},"def":{"name":"public_key","return_type":"Point","visibility":"Public","body":"@public_key"}},{"html_id":"public_key=(public_key:Point)-instance-method","name":"public_key=","doc":"The point on the elliptic curve representing the public key.","summary":"

The point on the elliptic curve representing the public key.

","abstract":false,"args":[{"name":"public_key","external_name":"public_key","restriction":"Point"}],"args_string":"(public_key : Point)","args_html":"(public_key : Point)","location":{"filename":"src/secp256k1/key.cr","line_number":25,"url":null},"def":{"name":"public_key=","args":[{"name":"public_key","external_name":"public_key","restriction":"Point"}],"visibility":"Public","body":"@public_key = public_key"}}]},{"html_id":"secp256k1/Secp256k1/Num","path":"Secp256k1/Num.html","kind":"class","full_name":"Secp256k1::Num","name":"Num","abstract":false,"superclass":{"html_id":"secp256k1/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"secp256k1/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"secp256k1/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/secp256k1/num.cr","line_number":25,"url":null}],"repository_name":"secp256k1","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"secp256k1/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"Provides a class to conveniently handle big numbers on the elliptic\ncurve. It allows to easily access decimal, hexadecimal, and binary\nrepresentations of the numeric. In addition, it implements some\nutilities such as zpadding or asserting hexadecimal strings. It's suited\nto temporarily handle unencrypted private keys.\n\nProperties:\n* `hex` (`String`): the hexadecimal string representation of the number.\n* `dec` (`BigInt`): the decimal big-integer representation of the number.\n* `bin` (`Bytes`): the binary bytes-slice represenation of the number.","summary":"

Provides a class to conveniently handle big numbers on the elliptic curve.

","constructors":[{"html_id":"new(hex:String)-class-method","name":"new","doc":"Creates a number from a hexadecimal string literal.\n\nParameters:\n* `hex` (`String`): a hexadecimal string representating the number.\n\n```\nNum.new \"568a0f505bde902db4a6afd207c794c7845fe7715da5999bb276d453c702a46d\"\n# => #\n```","summary":"

Creates a number from a hexadecimal string literal.

","abstract":false,"args":[{"name":"hex","external_name":"hex","restriction":"String"}],"args_string":"(hex : String)","args_html":"(hex : String)","location":{"filename":"src/secp256k1/num.cr","line_number":67,"url":null},"def":{"name":"new","args":[{"name":"hex","external_name":"hex","restriction":"String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(hex)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}},{"html_id":"new(num:BigInt)-class-method","name":"new","doc":"Creates a number from a big integer numeric.\n\nParameters:\n* `dec` (`BigInt`): the decimal big-integer representating the number.\n\n```\nNum.new BigInt.new \"39142835565766237398843902819171565157710677457569850027793715608438337348717\"\n# => #\n```","summary":"

Creates a number from a big integer numeric.

","abstract":false,"args":[{"name":"num","external_name":"num","restriction":"BigInt"}],"args_string":"(num : BigInt)","args_html":"(num : BigInt)","location":{"filename":"src/secp256k1/num.cr","line_number":87,"url":null},"def":{"name":"new","args":[{"name":"num","external_name":"num","restriction":"BigInt"}],"visibility":"Public","body":"_ = allocate\n_.initialize(num)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}},{"html_id":"new(bin:Slice(UInt8))-class-method","name":"new","doc":"Creates a number from a binary bytes slice.\n\nParameters:\n* `bin` (`Bytes`): the binary bytes-slice represenating the number.\n\n```\nNum.new Bytes[86, 138, 15, 80, 91, 222, 144, 45, 180, 166, 175, 210, 7, 199, 148, 199, 132, 95, 231, 113, 93, 165, 153, 155, 178, 118, 212, 83, 199, 2, 164, 109]\n# => #\n```","summary":"

Creates a number from a binary bytes slice.

","abstract":false,"args":[{"name":"bin","external_name":"bin","restriction":"Slice(UInt8)"}],"args_string":"(bin : Slice(UInt8))","args_html":"(bin : Slice(UInt8))","location":{"filename":"src/secp256k1/num.cr","line_number":107,"url":null},"def":{"name":"new","args":[{"name":"bin","external_name":"bin","restriction":"Slice(UInt8)"}],"visibility":"Public","body":"_ = allocate\n_.initialize(bin)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}},{"html_id":"new-class-method","name":"new","doc":"Creates a random number using `Random::Secure` that can be used as\na secret (private key).\n\n```\nNum.new\n# => #\n```","summary":"

Creates a random number using Random::Secure that can be used as a secret (private key).

","abstract":false,"location":{"filename":"src/secp256k1/num.cr","line_number":43,"url":null},"def":{"name":"new","visibility":"Public","body":"_ = allocate\n_.initialize\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"html_id":"bin:Slice(UInt8)-instance-method","name":"bin","doc":"The binary bytes-slice represenation of the number.","summary":"

The binary bytes-slice represenation of the number.

","abstract":false,"location":{"filename":"src/secp256k1/num.cr","line_number":31,"url":null},"def":{"name":"bin","return_type":"Slice(UInt8)","visibility":"Public","body":"@bin"}},{"html_id":"bin=(bin:Slice(UInt8))-instance-method","name":"bin=","doc":"The binary bytes-slice represenation of the number.","summary":"

The binary bytes-slice represenation of the number.

","abstract":false,"args":[{"name":"bin","external_name":"bin","restriction":"Slice(UInt8)"}],"args_string":"(bin : Slice(UInt8))","args_html":"(bin : Slice(UInt8))","location":{"filename":"src/secp256k1/num.cr","line_number":31,"url":null},"def":{"name":"bin=","args":[{"name":"bin","external_name":"bin","restriction":"Slice(UInt8)"}],"visibility":"Public","body":"@bin = bin"}},{"html_id":"dec:BigInt-instance-method","name":"dec","doc":"The decimal big-integer representation of the number.","summary":"

The decimal big-integer representation of the number.

","abstract":false,"location":{"filename":"src/secp256k1/num.cr","line_number":29,"url":null},"def":{"name":"dec","return_type":"BigInt","visibility":"Public","body":"@dec"}},{"html_id":"dec=(dec:BigInt)-instance-method","name":"dec=","doc":"The decimal big-integer representation of the number.","summary":"

The decimal big-integer representation of the number.

","abstract":false,"args":[{"name":"dec","external_name":"dec","restriction":"BigInt"}],"args_string":"(dec : BigInt)","args_html":"(dec : BigInt)","location":{"filename":"src/secp256k1/num.cr","line_number":29,"url":null},"def":{"name":"dec=","args":[{"name":"dec","external_name":"dec","restriction":"BigInt"}],"visibility":"Public","body":"@dec = dec"}},{"html_id":"hex:String-instance-method","name":"hex","doc":"The hexadecimal string representation of the number.","summary":"

The hexadecimal string representation of the number.

","abstract":false,"location":{"filename":"src/secp256k1/num.cr","line_number":27,"url":null},"def":{"name":"hex","return_type":"String","visibility":"Public","body":"@hex"}},{"html_id":"hex=(hex:String)-instance-method","name":"hex=","doc":"The hexadecimal string representation of the number.","summary":"

The hexadecimal string representation of the number.

","abstract":false,"args":[{"name":"hex","external_name":"hex","restriction":"String"}],"args_string":"(hex : String)","args_html":"(hex : String)","location":{"filename":"src/secp256k1/num.cr","line_number":27,"url":null},"def":{"name":"hex=","args":[{"name":"hex","external_name":"hex","restriction":"String"}],"visibility":"Public","body":"@hex = hex"}},{"html_id":"to_big:BigInt-instance-method","name":"to_big","doc":"Returns a big-integer representation of the number.\n\n```\nNum.new(Bytes[137]).to_big\n# => 137\n```","summary":"

Returns a big-integer representation of the number.

","abstract":false,"location":{"filename":"src/secp256k1/num.cr","line_number":156,"url":null},"def":{"name":"to_big","return_type":"BigInt","visibility":"Public","body":"@dec"}},{"html_id":"to_bytes:Bytes-instance-method","name":"to_bytes","doc":"Returns a binary byte-slice representation of the number.\n\n```\nNum.new(\"0x89\").to_bytes\n# => Bytes[137]\n```","summary":"

Returns a binary byte-slice representation of the number.

","abstract":false,"location":{"filename":"src/secp256k1/num.cr","line_number":166,"url":null},"def":{"name":"to_bytes","return_type":"Bytes","visibility":"Public","body":"@bin"}},{"html_id":"to_hex:String-instance-method","name":"to_hex","doc":"Returns an unprefixed hexadecimal string representation.\n\n```\nNum.new(Bytes[137]).to_hex\n# => \"89\"\n```","summary":"

Returns an unprefixed hexadecimal string representation.

","abstract":false,"location":{"filename":"src/secp256k1/num.cr","line_number":119,"url":null},"def":{"name":"to_hex","return_type":"String","visibility":"Public","body":"@hex"}},{"html_id":"to_prefixed_hex:String-instance-method","name":"to_prefixed_hex","doc":"Returns an `0x`-prefixed hexadecimal string representation.\n\n```\nNum.new(Bytes[137]).to_prefixed_hex\n# => \"0x89\"\n```","summary":"

Returns an 0x-prefixed hexadecimal string representation.

","abstract":false,"location":{"filename":"src/secp256k1/num.cr","line_number":129,"url":null},"def":{"name":"to_prefixed_hex","return_type":"String","visibility":"Public","body":"\"0x#{@hex}\""}},{"html_id":"to_zpadded_bytes(length=32):Bytes-instance-method","name":"to_zpadded_bytes","doc":"Returns a z-padded byte-slice binary representation.\n\nParameters:\n* `length` (`Int`): the byte-size of the final z-padded slice (default `32`).\n\n```\nNum.new(Bytes[137]).to_zpadded_bytes\n# => Bytes[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 137]\n```","summary":"

Returns a z-padded byte-slice binary representation.

","abstract":false,"args":[{"name":"length","default_value":"32","external_name":"length","restriction":""}],"args_string":"(length = 32) : Bytes","args_html":"(length = 32) : Bytes","location":{"filename":"src/secp256k1/num.cr","line_number":179,"url":null},"def":{"name":"to_zpadded_bytes","args":[{"name":"length","default_value":"32","external_name":"length","restriction":""}],"return_type":"Bytes","visibility":"Public","body":"zpadded_bytes = @bin\nbyte_zero = Bytes[0]\nwhile zpadded_bytes.size < length\n slice_size = zpadded_bytes.size + 1\n zpadded_slice = Slice(UInt8).new(slice_size)\n slice_pointer = zpadded_slice.to_unsafe\n byte_zero.copy_to(slice_pointer, 0)\n slice_pointer = slice_pointer + 1\n zpadded_bytes.copy_to(slice_pointer, zpadded_bytes.size)\n zpadded_bytes = zpadded_slice\nend\nzpadded_bytes\n"}},{"html_id":"to_zpadded_hex(length=32):String-instance-method","name":"to_zpadded_hex","doc":"Returns a z-padded hexadecimal string representation.\n\nParameters:\n* `length` (`Int`): the byte-size of the final z-padded hex-string (default `32`).\n\n```\nNum.new(Bytes[137]).to_zpadded_hex\n# => \"0000000000000000000000000000000000000000000000000000000000000089\"\n```","summary":"

Returns a z-padded hexadecimal string representation.

","abstract":false,"args":[{"name":"length","default_value":"32","external_name":"length","restriction":""}],"args_string":"(length = 32) : String","args_html":"(length = 32) : String","location":{"filename":"src/secp256k1/num.cr","line_number":142,"url":null},"def":{"name":"to_zpadded_hex","args":[{"name":"length","default_value":"32","external_name":"length","restriction":""}],"return_type":"String","visibility":"Public","body":"zpadded_hex = @hex\nwhile zpadded_hex.size < (length * 2)\n zpadded_hex = \"0#{zpadded_hex}\"\nend\nzpadded_hex\n"}}]},{"html_id":"secp256k1/Secp256k1/Point","path":"Secp256k1/Point.html","kind":"class","full_name":"Secp256k1::Point","name":"Point","abstract":false,"superclass":{"html_id":"secp256k1/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"secp256k1/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"secp256k1/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/secp256k1/point.cr","line_number":30,"url":null}],"repository_name":"secp256k1","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"secp256k1/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"Provides a point in the two-dimensional space of any elliptic curve.\nIn most cases, such a point on a given curve represents a public key.\nHowever, for keypairs, a `Key` type shall be used!\n\nProperties:\n* `x` (`Num`): the position on the x-axis.\n* `y` (`Num`): the position on the y-axis.","summary":"

Provides a point in the two-dimensional space of any elliptic curve.

","constructors":[{"html_id":"new(x:Num,y:Num)-class-method","name":"new","doc":"Provides a public point in the two-dimensional space on the given `Secp256k1`\nelliptic curve by passing the x- and y-coordinates (public key).\n\nParameters:\n* `x` (`Num`): the position on the x-axis.\n* `y` (`Num`): the position on the y-axis.\n\n```\nx = Num.new \"efc4f8d8bfc778463e4d4916d88bf3f057e6dc96cb2adc26dfb91959c4bef4a5\"\ny = Num.new \"cecd9a83fefafcb3cf99fde0c340bbe2fed9cdd0d25b53f4e08254acefb69ae0\"\nPoint.new x, y\n# => #,\n# @y=#>\n```","summary":"

Provides a public point in the two-dimensional space on the given Secp256k1 elliptic curve by passing the x- and y-coordinates (public key).

","abstract":false,"args":[{"name":"x","external_name":"x","restriction":"Num"},{"name":"y","external_name":"y","restriction":"Num"}],"args_string":"(x : Num, y : Num)","args_html":"(x : Num, y : Num)","location":{"filename":"src/secp256k1/point.cr","line_number":58,"url":null},"def":{"name":"new","args":[{"name":"x","external_name":"x","restriction":"Num"},{"name":"y","external_name":"y","restriction":"Num"}],"visibility":"Public","body":"_ = allocate\n_.initialize(x, y)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}},{"html_id":"new(priv:Num)-class-method","name":"new","doc":"Provides a public point in the two-dimensional space on the given `Secp256k1`\nelliptic curve by passing a random number (private key). Note, that the\nprivate key will be consumed by this constructor and should only be used\nto retrieve a public key. To manage keypairs, use the `Key` type instead.\n\nParameters:\n* `priv` (`Num`): the random number giving access to the point.\n\n```\npriv = Num.new \"e50932676c9901f259659d62f0c56fd899feca3f57ecab147a5ef8a0b59defc3\"\nPoint.new priv\n# => #,\n# @y=#>\n```","summary":"

Provides a public point in the two-dimensional space on the given Secp256k1 elliptic curve by passing a random number (private key).

","abstract":false,"args":[{"name":"priv","external_name":"priv","restriction":"Num"}],"args_string":"(priv : Num)","args_html":"(priv : Num)","location":{"filename":"src/secp256k1/point.cr","line_number":84,"url":null},"def":{"name":"new","args":[{"name":"priv","external_name":"priv","restriction":"Num"}],"visibility":"Public","body":"_ = allocate\n_.initialize(priv)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}},{"html_id":"new(pub:String)-class-method","name":"new","doc":"Provides a public point in the two-dimensional space on the given `Secp256k1`\nelliptic curve by passing a compressed or uncompressed public key.\n\nParameters:\n* `pub` (`String`): the public key string (compressed or uncompressed).\n\n```\npub = \"03aff8674d6b96a6c58dbab08b903565363271308888340a2caddf88e56165930f\"\nPoint.new pub\n# => #,\n# @y=#>\n```","summary":"

Provides a public point in the two-dimensional space on the given Secp256k1 elliptic curve by passing a compressed or uncompressed public key.

","abstract":false,"args":[{"name":"pub","external_name":"pub","restriction":"String"}],"args_string":"(pub : String)","args_html":"(pub : String)","location":{"filename":"src/secp256k1/point.cr","line_number":109,"url":null},"def":{"name":"new","args":[{"name":"pub","external_name":"pub","restriction":"String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(pub)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"html_id":"compressed:String-instance-method","name":"compressed","doc":"Returns a prefixed, compressed public key string for the given point\nin the format `prefix|x|y`.\n\n```\npriv = Num.new \"e50932676c9901f259659d62f0c56fd899feca3f57ecab147a5ef8a0b59defc3\"\nPoint.new(priv).compressed\n# => \"03aff8674d6b96a6c58dbab08b903565363271308888340a2caddf88e56165930f\"\n```","summary":"

Returns a prefixed, compressed public key string for the given point in the format prefix|x|y.

","abstract":false,"location":{"filename":"src/secp256k1/point.cr","line_number":161,"url":null},"def":{"name":"compressed","return_type":"String","visibility":"Public","body":"prefix = 2 + (@y.to_big % 2)\nprefix = \"0#{prefix}\"\n\"#{prefix}#{@x.to_zpadded_hex}\"\n"}},{"html_id":"uncompressed:String-instance-method","name":"uncompressed","doc":"Returns a prefixed, uncompressed public key string for the given point\nin the format `04|x|y`.\n\n```\npriv = Num.new \"e50932676c9901f259659d62f0c56fd899feca3f57ecab147a5ef8a0b59defc3\"\nPoint.new(priv).uncompressed\n# => \"04aff8674d6b96a6c58dbab08b903565363271308888340a2caddf88e56165930f21f4c49cfe90da39c254a51b8ee8afcdd8c02dd566f13582c23e104c7ed5936b\"\n```","summary":"

Returns a prefixed, uncompressed public key string for the given point in the format 04|x|y.

","abstract":false,"location":{"filename":"src/secp256k1/point.cr","line_number":148,"url":null},"def":{"name":"uncompressed","return_type":"String","visibility":"Public","body":"prefix = \"04\"\n\"#{prefix}#{@x.to_zpadded_hex}#{@y.to_zpadded_hex}\"\n"}},{"html_id":"x:Num-instance-method","name":"x","doc":"The position on the x-axis.","summary":"

The position on the x-axis.

","abstract":false,"location":{"filename":"src/secp256k1/point.cr","line_number":32,"url":null},"def":{"name":"x","return_type":"Num","visibility":"Public","body":"@x"}},{"html_id":"x=(x:Num)-instance-method","name":"x=","doc":"The position on the x-axis.","summary":"

The position on the x-axis.

","abstract":false,"args":[{"name":"x","external_name":"x","restriction":"Num"}],"args_string":"(x : Num)","args_html":"(x : Num)","location":{"filename":"src/secp256k1/point.cr","line_number":32,"url":null},"def":{"name":"x=","args":[{"name":"x","external_name":"x","restriction":"Num"}],"visibility":"Public","body":"@x = x"}},{"html_id":"y:Num-instance-method","name":"y","doc":"The position on the y-axis.","summary":"

The position on the y-axis.

","abstract":false,"location":{"filename":"src/secp256k1/point.cr","line_number":35,"url":null},"def":{"name":"y","return_type":"Num","visibility":"Public","body":"@y"}},{"html_id":"y=(y:Num)-instance-method","name":"y=","doc":"The position on the y-axis.","summary":"

The position on the y-axis.

","abstract":false,"args":[{"name":"y","external_name":"y","restriction":"Num"}],"args_string":"(y : Num)","args_html":"(y : Num)","location":{"filename":"src/secp256k1/point.cr","line_number":35,"url":null},"def":{"name":"y=","args":[{"name":"y","external_name":"y","restriction":"Num"}],"visibility":"Public","body":"@y = y"}}]},{"html_id":"secp256k1/Secp256k1/Signature","path":"Secp256k1/Signature.html","kind":"class","full_name":"Secp256k1::Signature","name":"Signature","abstract":false,"superclass":{"html_id":"secp256k1/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"secp256k1/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"secp256k1/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/secp256k1/signature.cr","line_number":22,"url":null}],"repository_name":"secp256k1","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"secp256k1/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"Provides an ECDSA Signature containing the random point `r`, the\nsignature proof `s`, and the recovery id or `v` value.\n\nProperties:\n* `r` (`Num`): the `x` coordinate of a random point `R` on the curve.\n* `s` (`Num`): the signature proof of a message.\n* `v` (`Num`): the recovery id or `v` value.","summary":"

Provides an ECDSA Signature containing the random point #r, the signature proof #s, and the recovery id or #v value.

","constructors":[{"html_id":"new(r:Num,s:Num,v:Num)-class-method","name":"new","doc":"Provides an ECDSA Signature containing the random point `r`, the\nsignature proof `s`, and the recovery id or `v` value.\n\nParameters:\n* `r` (`Num`): the `x` coordinate of a random point `R` on the curve.\n* `s` (`Num`): the signature proof of a message.\n* `v` (`Num`): the recovery id or `v` value.\n\n```\nr = Num.new \"efc4f8d8bfc778463e4d4916d88bf3f057e6dc96cb2adc26dfb91959c4bef4a5\"\ns = Num.new \"cecd9a83fefafcb3cf99fde0c340bbe2fed9cdd0d25b53f4e08254acefb69ae0\"\nv = Num.new \"00\"\nSignature.new r, s, v\n# => #,\n# @s=#,\n# @v=#>\n```","summary":"

Provides an ECDSA Signature containing the random point #r, the signature proof #s, and the recovery id or #v value.

","abstract":false,"args":[{"name":"r","external_name":"r","restriction":"Num"},{"name":"s","external_name":"s","restriction":"Num"},{"name":"v","external_name":"v","restriction":"Num"}],"args_string":"(r : Num, s : Num, v : Num)","args_html":"(r : Num, s : Num, v : Num)","location":{"filename":"src/secp256k1/signature.cr","line_number":59,"url":null},"def":{"name":"new","args":[{"name":"r","external_name":"r","restriction":"Num"},{"name":"s","external_name":"s","restriction":"Num"},{"name":"v","external_name":"v","restriction":"Num"}],"visibility":"Public","body":"_ = allocate\n_.initialize(r, s, v)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"html_id":"compact:String-instance-method","name":"compact","doc":"Returns a compact `String` containing the concatenated signature\nin the form `r|s|v`.\n\n```\nr = Num.new \"efc4f8d8bfc778463e4d4916d88bf3f057e6dc96cb2adc26dfb91959c4bef4a5\"\ns = Num.new \"cecd9a83fefafcb3cf99fde0c340bbe2fed9cdd0d25b53f4e08254acefb69ae0\"\nv = Num.new \"00\"\nSignature.new(r, s, v).compact\n# => \"efc4f8d8bfc778463e4d4916d88bf3f057e6dc96cb2adc26dfb91959c4bef4a5cecd9a83fefafcb3cf99fde0c340bbe2fed9cdd0d25b53f4e08254acefb69ae000\"\n```","summary":"

Returns a compact String containing the concatenated signature in the form r|s|v.

","abstract":false,"location":{"filename":"src/secp256k1/signature.cr","line_number":75,"url":null},"def":{"name":"compact","return_type":"String","visibility":"Public","body":"\"#{r.to_zpadded_hex}#{s.to_zpadded_hex}#{v.to_hex}\""}},{"html_id":"r:Num-instance-method","name":"r","doc":"The `x` coordinate of a random point `R` on the curve.","summary":"

The x coordinate of a random point R on the curve.

","abstract":false,"location":{"filename":"src/secp256k1/signature.cr","line_number":24,"url":null},"def":{"name":"r","return_type":"Num","visibility":"Public","body":"@r"}},{"html_id":"r=(r:Num)-instance-method","name":"r=","doc":"The `x` coordinate of a random point `R` on the curve.","summary":"

The x coordinate of a random point R on the curve.

","abstract":false,"args":[{"name":"r","external_name":"r","restriction":"Num"}],"args_string":"(r : Num)","args_html":"(r : Num)","location":{"filename":"src/secp256k1/signature.cr","line_number":24,"url":null},"def":{"name":"r=","args":[{"name":"r","external_name":"r","restriction":"Num"}],"visibility":"Public","body":"@r = r"}},{"html_id":"s:Num-instance-method","name":"s","doc":"The signature proof of a message.","summary":"

The signature proof of a message.

","abstract":false,"location":{"filename":"src/secp256k1/signature.cr","line_number":27,"url":null},"def":{"name":"s","return_type":"Num","visibility":"Public","body":"@s"}},{"html_id":"s=(s:Num)-instance-method","name":"s=","doc":"The signature proof of a message.","summary":"

The signature proof of a message.

","abstract":false,"args":[{"name":"s","external_name":"s","restriction":"Num"}],"args_string":"(s : Num)","args_html":"(s : Num)","location":{"filename":"src/secp256k1/signature.cr","line_number":27,"url":null},"def":{"name":"s=","args":[{"name":"s","external_name":"s","restriction":"Num"}],"visibility":"Public","body":"@s = s"}},{"html_id":"v:Num-instance-method","name":"v","doc":"The recovery id or `v` value.","summary":"

The recovery id or #v value.

","abstract":false,"location":{"filename":"src/secp256k1/signature.cr","line_number":30,"url":null},"def":{"name":"v","return_type":"Num","visibility":"Public","body":"@v"}},{"html_id":"v=(v:Num)-instance-method","name":"v=","doc":"The recovery id or `v` value.","summary":"

The recovery id or #v value.

","abstract":false,"args":[{"name":"v","external_name":"v","restriction":"Num"}],"args_string":"(v : Num)","args_html":"(v : Num)","location":{"filename":"src/secp256k1/signature.cr","line_number":30,"url":null},"def":{"name":"v=","args":[{"name":"v","external_name":"v","restriction":"Num"}],"visibility":"Public","body":"@v = v"}}]},{"html_id":"secp256k1/Secp256k1/Util","path":"Secp256k1/Util.html","kind":"module","full_name":"Secp256k1::Util","name":"Util","abstract":false,"locations":[{"filename":"src/secp256k1/util.cr","line_number":17,"url":null}],"repository_name":"secp256k1","program":false,"enum":false,"alias":false,"const":false,"extended_modules":[{"html_id":"secp256k1/Secp256k1/Util","kind":"module","full_name":"Secp256k1::Util","name":"Util"}],"namespace":{"html_id":"secp256k1/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"Provides a collection of utilities for convenience, e.g., to bind\nrelevant hashing algorithms, or to concatenate byte slices.","summary":"

Provides a collection of utilities for convenience, e.g., to bind relevant hashing algorithms, or to concatenate byte slices.

","instance_methods":[{"html_id":"concat_bytes(x:Bytes,y:Bytes):Bytes-instance-method","name":"concat_bytes","doc":"Concatenates two byte slices in the order provided, i.e., `x|y`.\n\nParameters:\n* `x` (`Bytes`): a byte slice.\n* `y` (`Bytes`): another byte slice.\n\nReturns a concatenated `Bytes` slice.\n\n```\nUtil.concat_bytes Bytes[1, 2, 3], Bytes[9, 8, 7]\n# => Bytes[1, 2, 3, 9, 8, 7]\n```","summary":"

Concatenates two byte slices in the order provided, i.e., x|y.

","abstract":false,"args":[{"name":"x","external_name":"x","restriction":"Bytes"},{"name":"y","external_name":"y","restriction":"Bytes"}],"args_string":"(x : Bytes, y : Bytes) : Bytes","args_html":"(x : Bytes, y : Bytes) : Bytes","location":{"filename":"src/secp256k1/util.cr","line_number":177,"url":null},"def":{"name":"concat_bytes","args":[{"name":"x","external_name":"x","restriction":"Bytes"},{"name":"y","external_name":"y","restriction":"Bytes"}],"return_type":"Bytes","visibility":"Public","body":"z = IO::Memory.new(x.bytesize + y.bytesize)\nx.each do |b|\n z.write_bytes(UInt8.new(b))\nend\ny.each do |b|\n z.write_bytes(UInt8.new(b))\nend\nreturn z.to_slice\n"}},{"html_id":"deterministic_k(priv:Num,hash:Num,order=N):Num-instance-method","name":"deterministic_k","doc":"Provides a deterministic secret based on private key and message hash\nas defined in RFC-6979.\n\nRef: [datatracker.ietf.org/doc/html/rfc6979](https://datatracker.ietf.org/doc/html/rfc6979)\n\nParameters:\n* `priv` (`Num`): the private key or secret number.\n* `hash` (`Num`): the message hash or arbirtrary data hash.\n* `order` (`Num`): the order of the curve over `G` (default `N`).\n\nReturns a deterministically random number of type `Num`.\n\n```\npriv = Num.new \"3b74fcc0b0c419a00d2d9e88b15fbd99e03920138da22e2a00c327b88d24cf45\"\nhash = Util.sha256 \"Henlo, Wordl\"\nUtil.deterministic_k(priv, hash)\n# => #\n```","summary":"

Provides a deterministic secret based on private key and message hash as defined in RFC-6979.

","abstract":false,"args":[{"name":"priv","external_name":"priv","restriction":"Num"},{"name":"hash","external_name":"hash","restriction":"Num"},{"name":"order","default_value":"N","external_name":"order","restriction":""}],"args_string":"(priv : Num, hash : Num, order = N) : Num","args_html":"(priv : Num, hash : Num, order = N) : Num","location":{"filename":"src/secp256k1/util.cr","line_number":135,"url":null},"def":{"name":"deterministic_k","args":[{"name":"priv","external_name":"priv","restriction":"Num"},{"name":"hash","external_name":"hash","restriction":"Num"},{"name":"order","default_value":"N","external_name":"order","restriction":""}],"return_type":"Num","visibility":"Public","body":"order_size = order.hex.size // 2\nv = Num.new(Bytes.new(order_size, 1))\nk = Num.new(Bytes.new(order_size, 0))\nconcat = Util.concat_bytes(v.bin, Bytes[0])\nconcat = Util.concat_bytes(concat, priv.bin)\nconcat = Util.concat_bytes(concat, hash.bin)\nk = OpenSSL::HMAC.digest(:sha256, k.bin, concat)\nv = OpenSSL::HMAC.digest(:sha256, k, v.bin)\nconcat = Util.concat_bytes(v, Bytes[0])\nconcat = Util.concat_bytes(concat, priv.bin)\nconcat = Util.concat_bytes(concat, hash.bin)\nk = OpenSSL::HMAC.digest(:sha256, k, concat)\nv = OpenSSL::HMAC.digest(:sha256, k, v)\nwhile true\n t = IO::Memory.new.to_slice\n while t.size < order_size\n v = OpenSSL::HMAC.digest(:sha256, k, v)\n t = Util.concat_bytes(t, v)\n end\n secret = Num.new(t)\n if secret.dec < order.dec && secret.dec > 0\n return secret\n end\n increment = Util.concat_bytes(v, Bytes[0])\n k = OpenSSL::HMAC.digest(:sha256, k, increment)\n v = OpenSSL::HMAC.digest(:sha256, k, v)\nend\n"}},{"html_id":"keccak(data:Num|String,entropy=256):Num-instance-method","name":"keccak","doc":"Operating a Keccak hash on a binary/number or string literal.\n\nParameters:\n* `data` (`Num | String`): the binary numeric or string literal to be hashed.\n* `entropy` (`Int32`): the required entropy (default `256`).\n\nReturns a `Num` representing the Keccak hash.\n\n```\nUtil.keccak(Num.new \"0xdeadbeef\").hex\n# => \"d4fd4e189132273036449fc9e11198c739161b4c0116a9a2dccdfa1c492006f1\"\n\nUtil.keccak(\"0xdeadbeef\").hex\n# => \"4f440a001006a49f24a7de53c04eca3f79aef851ac58e460c9630d044277c8b0\"\n```","summary":"

Operating a Keccak hash on a binary/number or string literal.

","abstract":false,"args":[{"name":"data","external_name":"data","restriction":"Num | String"},{"name":"entropy","default_value":"256","external_name":"entropy","restriction":""}],"args_string":"(data : Num | String, entropy = 256) : Num","args_html":"(data : Num | String, entropy = 256) : Num","location":{"filename":"src/secp256k1/util.cr","line_number":35,"url":null},"def":{"name":"keccak","args":[{"name":"data","external_name":"data","restriction":"Num | String"},{"name":"entropy","default_value":"256","external_name":"entropy","restriction":""}],"return_type":"Num","visibility":"Public","body":"keccak = Digest::Keccak3.new(entropy)\nif data.is_a?(String)\n return Num.new((keccak.update(data)).hexdigest)\nelse\n return Num.new((keccak.update(data.to_bytes)).hexdigest)\nend\n"}},{"html_id":"ripemd160(data:Num|String):Num-instance-method","name":"ripemd160","doc":"Operating a RIPEMD-160 hash on a binary/number or string literal.\n\nParameters:\n* `data` (`Num | String`): the binary numeric or string literal to be hashed.\n\nReturns a `Num` representing the RIPEMD hash.\n\n```\nUtil.ripemd160(Num.new \"0xdeadbeef\").hex\n# => \"226821c2f5423e11fe9af68bd285c249db2e4b5a\"\n\nUtil.ripemd160(\"0xdeadbeef\").hex\n# => \"4caf817f14e84b564e47afd19966e5d123ee0183\"\n```","summary":"

Operating a RIPEMD-160 hash on a binary/number or string literal.

","abstract":false,"args":[{"name":"data","external_name":"data","restriction":"Num | String"}],"args_string":"(data : Num | String) : Num","args_html":"(data : Num | String) : Num","location":{"filename":"src/secp256k1/util.cr","line_number":105,"url":null},"def":{"name":"ripemd160","args":[{"name":"data","external_name":"data","restriction":"Num | String"}],"return_type":"Num","visibility":"Public","body":"ripemd = OpenSSL::Digest.new(\"RIPEMD160\")\nif data.is_a?(String)\n return Num.new((ripemd.update(data)).final.hexstring)\nelse\n return Num.new((ripemd.update(data.to_bytes)).final.hexstring)\nend\n"}},{"html_id":"sha256(data:Num|String):Num-instance-method","name":"sha256","doc":"Operating a SHA2-256 hash on a binary/number or string literal.\n\nParameters:\n* `data` (`Num | String`): the binary numeric or string literal to be hashed.\n\nReturns a `Num` representing the SHA2 hash.\n\n```\nUtil.sha256(Num.new \"0xdeadbeef\").hex\n# => \"5f78c33274e43fa9de5659265c1d917e25c03722dcb0b8d27db8d5feaa813953\"\n\nUtil.sha256(\"0xdeadbeef\").hex\n# => \"4142710b9b4caaeb000b8e5de271bbebac7f509aab2f5e61d1ed1958bfe6d583\"\n```","summary":"

Operating a SHA2-256 hash on a binary/number or string literal.

","abstract":false,"args":[{"name":"data","external_name":"data","restriction":"Num | String"}],"args_string":"(data : Num | String) : Num","args_html":"(data : Num | String) : Num","location":{"filename":"src/secp256k1/util.cr","line_number":82,"url":null},"def":{"name":"sha256","args":[{"name":"data","external_name":"data","restriction":"Num | String"}],"return_type":"Num","visibility":"Public","body":"sha2 = OpenSSL::Digest.new(\"SHA256\")\nif data.is_a?(String)\n return Num.new((sha2.update(data)).final.hexstring)\nelse\n return Num.new((sha2.update(data.to_bytes)).final.hexstring)\nend\n"}},{"html_id":"sha3(data:Num|String,entropy=256):Num-instance-method","name":"sha3","doc":"Operating a SHA3 hash on a binary/number or string literal.\n\nParameters:\n* `data` (`Num | String`): the binary numeric or string literal to be hashed.\n* `entropy` (`Int32`): the required entropy (default `256`).\n\nReturns a `Num` representing the SHA3 hash.\n\n```\nUtil.sha3(Num.new \"0xdeadbeef\").hex\n# => \"352b82608dad6c7ac3dd665bc2666e5d97803cb13f23a1109e2105e93f42c448\"\n\nUtil.sha3(\"0xdeadbeef\").hex\n# => \"c12811e13ed75afe3e0945ef34e8a25b9d321a46e131c6463731de25a21b39eb\"\n```","summary":"

Operating a SHA3 hash on a binary/number or string literal.

","abstract":false,"args":[{"name":"data","external_name":"data","restriction":"Num | String"},{"name":"entropy","default_value":"256","external_name":"entropy","restriction":""}],"args_string":"(data : Num | String, entropy = 256) : Num","args_html":"(data : Num | String, entropy = 256) : Num","location":{"filename":"src/secp256k1/util.cr","line_number":59,"url":null},"def":{"name":"sha3","args":[{"name":"data","external_name":"data","restriction":"Num | String"},{"name":"entropy","default_value":"256","external_name":"entropy","restriction":""}],"return_type":"Num","visibility":"Public","body":"sha3 = Digest::SHA3.new(entropy)\nif data.is_a?(String)\n return Num.new((sha3.update(data)).hexdigest)\nelse\n return Num.new((sha3.update(data.to_bytes)).hexdigest)\nend\n"}}]}]}]}}) \ No newline at end of file +crystal_doc_search_index_callback({"repository_name":"secp256k1","body":"# secp256k1.cr\n\n[![Build Status](https://img.shields.io/github/workflow/status/q9f/secp256k1.cr/Nightly)](https://github.com/q9f/secp256k1.cr/actions)\n[![Code Coverage](https://codecov.io/gh/q9f/secp256k1.cr/branch/main/graph/badge.svg?token=ngxRs9HdJA)](https://codecov.io/gh/q9f/secp256k1.cr)\n[![Documentation](https://img.shields.io/badge/docs-html-black)](https://q9f.github.io/secp256k1.cr/)\n[![Release](https://img.shields.io/github/v/release/q9f/secp256k1.cr?include_prereleases&color=black)](https://github.com/q9f/secp256k1.cr/releases/latest)\n[![Language](https://img.shields.io/github/languages/top/q9f/secp256k1.cr?color=black)](https://github.com/q9f/secp256k1.cr/search?l=crystal)\n[![License](https://img.shields.io/github/license/q9f/secp256k1.cr.svg?color=black)](LICENSE)\n\nA library implementing the `Secp256k1` elliptic curve natively in pure Crystal.\n`Secp256k1` is the elliptic curve used in the public-private-key cryptography required by `Bitcoin`, `Ethereum`, and `Polkadot`.\n\nThis library allows for:\n* providing a `Secp256k1` cryptographic context, see `Secp256k1::Context`\n* managing `Secp256k1` signatures and verification, see `Secp256k1::Signature`\n* managing private-public keypairs, see `Secp256k1::Key`\n* generating public keys, see `Secp256k1::Point`\n* generating private keys, see `Secp256k1::Num`\n\n# Installation\n\nAdd the `Secp256k1` library to your `shard.yml`\n\n```yaml\ndependencies:\n secp256k1:\n github: q9f/secp256k1.cr\n version: \"~> 0.5\"\n```\n\n# Usage\n\nImport and expose the `Secp256k1` module.\n\n```crystal\nrequire \"secp256k1\"\n```\n\nThis library exposes the following modules and classes (in logical order):\n\n* `Secp256k1`: necessary constants and data structures, including:\n - `Secp256k1::Num`: for managing big numerics (private keys)\n - `Secp256k1::Point`: for handling of elliptic curve points (public keys)\n - `Secp256k1::Key`: for managing private-public keypairs (accounts)\n - `Secp256k1::Signature`: for handling ECDSA signatures (r, s, v)\n* `Secp256k1::Context`: providing a cryptographic context for signing and verification\n* `Secp256k1::Curve`: the entire core mathematics behind the elliptic curve cryptography\n* `Secp256k1::Util`: binding of various hashing algorithms for convenience\n\nBasic usage:\n\n```crystal\n# generates a new, random keypair\nkey = Secp256k1::Key.new\n# => #,\n# @public_key=#,\n# @y=#>>\n\n# gets the private key\nkey.private_hex\n# => \"3ccf84820c20d5e8c536ba84c52ba410375b29b1812b5f7e722445c969a0fb30\"\n\n# gets the compressed public key with prefix\nkey.public_hex_compressed\n# => \"02cd4a8712ee6efc15b5abe37c0dbfa979d89c427d3fe24b076008decefe94dba2\"\n```\n\nSignature generation and verification:\n\n```crystal\n# sign a message with a private key\nctx = Secp256k1::Context.new\npriv = Secp256k1::Num.new \"1f0c122d41ff536b19bfd83537c0dfc290e45cd3c375a43237c8b8fff7ac8af7\"\nkey = Secp256k1::Key.new priv\nhash = Secp256k1::Util.sha256 \"Henlo, Wordl\"\nsig = ctx.sign key, hash\n# => #,\n# @s=#,\n# @v=#>\n\n# verify a signature with a public key\nr = Secp256k1::Num.new \"c4079db44240b7afe94985c69fc89602e33629fd9b8623d711c30ce6378b33df\"\ns = Secp256k1::Num.new \"6842c1b63c94bdb8e4f5ae88fb65f7a98b77b197c8323004fb47ef57fab29053\"\nv = Secp256k1::Num.new \"00\"\nsig = Secp256k1::Signature.new r, s, v\nhash = Secp256k1::Util.sha256 \"Henlo, Wordl\"\npubl = Secp256k1::Point.new \"0416008a369439f1a8a75cf974860bed5b10180518d6b1dd3ac847f423fd375d6aa29474394f0cd79d2ea543507d069e97339284f01bdbfd27392daec0ec553816\"\nctx.verify sig, hash, publ\n# => true\n```\n\n# Documentation\n\nThe full library documentation can be found here: [q9f.github.io/secp256k1.cr](https://q9f.github.io/secp256k1.cr/)\n\nGenerate a local copy with:\n\n```shell\ncrystal docs\n```\n\n# Testing\n\nThe library is entirely specified through tests in `./spec`; run:\n\n```shell\ncrystal spec --verbose\n```\n\n# Understand\n\nPrivate keys are just scalars (`Secp256k1::Num`) and public keys are points (`Secp256k1::Point`) with `x` and `y` coordinates.\n\nBitcoin public keys can be uncompressed `p|x|y` or compressed `p|x`. both come with a prefix `p` which is useless for uncompressed keys but necessary for compressed keys to recover the `y` coordinate on the `Secp256k1` elliptic curve field.\n\nEthereum public keys are uncompressed `x|y` without any prefix. The last 20 bytes slice of the `y` coordinate is actually used as address without any checksum. A checksum was later added in EIP-55 using a `keccak256` hash and indicating character capitalization.\n\nNeither Bitcoin nor Ethereum allow for recovering public keys from an address unless there exists a transaction with a valid signature on the blockchain.\n\n# Known issues\n\n_Note: this library should not be used in production without proper auditing. It should be considered slow and insecure._\n\n* This library is not constant time and might be subject to side-channel attacks. ([#4](https://github.com/q9f/secp256k1.cr/issues/4))\n* This library does unnecessary big-integer math and should someday rather correctly implement the `Secp256k1` prime field ([#5](https://github.com/q9f/secp256k1.cr/issues/5))\n* This library is slow in recovering signatures. Future versions should respect the recovery ID to quickly identify the correct public key from a signature.\n\nFound any other issue? Report it: [github.com/q9f/secp256k1.cr/issues](https://github.com/q9f/secp256k1.cr/issues)\n\n# Contribute\n\nCreate a pull request, and make sure tests and linter pass.\n\nThis pure crystal implementation is based on the python implementation [wobine/blackboard101](https://github.com/wobine/blackboard101) which is also used as reference to write tests against. It's a complete rewrite of the abandoned [packetzero/bitcoinutils](https://github.com/packetzero/bitcoinutils) for educational purposes.\n\nHonerable mention for the [bitcoin wiki](https://en.bitcoin.it/wiki/Main_Page) and the [ethereum stackexchange](https://ethereum.stackexchange.com/) for providing so many in-depth resources that supported this project in reimplementing everything.\n\nLicense: Apache License v2.0\n\nContributors: [**@q9f**](https://github.com/q9f/), [@cserb](https://github.com/cserb), [MrSorcus](https://github.com/MrSorcus)\n","program":{"html_id":"secp256k1/toplevel","path":"toplevel.html","kind":"module","full_name":"Top Level Namespace","name":"Top Level Namespace","abstract":false,"locations":[],"repository_name":"secp256k1","program":true,"enum":false,"alias":false,"const":false,"types":[{"html_id":"secp256k1/Secp256k1","path":"Secp256k1.html","kind":"module","full_name":"Secp256k1","name":"Secp256k1","abstract":false,"locations":[{"filename":"src/secp256k1.cr","line_number":35,"url":null},{"filename":"src/secp256k1/context.cr","line_number":22,"url":null},{"filename":"src/secp256k1/version.cr","line_number":21,"url":null}],"repository_name":"secp256k1","program":false,"enum":false,"alias":false,"const":false,"constants":[{"id":"G","name":"G","value":"Point.new(Num.new(\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\"), Num.new(\"483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8\"))","doc":"A commonly used base point `G` with coordinates `x` and `y`\nsatisfying `y^2 = x^3 + 7`.","summary":"

A commonly used base point G with coordinates x and y satisfying y^2 = x^3 + 7.

"},{"id":"N","name":"N","value":"Num.new(\"fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141\")","doc":"The order `n` of `G` defines the finite size of the Secp256k1 field `E`.","summary":"

The order n of G defines the finite size of the Secp256k1 field E.

"},{"id":"P","name":"P","value":"Num.new(\"fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f\")","doc":"The elliptic curve domain parameters over `F_p` associated with a\nKoblitz curve `Secp256k1` are specified by the sextuple\n`T = (p, a, b, G, n, h)` where the finite field `F_p` is defined by\nthe prime `p = 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1`.","summary":"

The elliptic curve domain parameters over F_p associated with a Koblitz curve Secp256k1 are specified by the sextuple T = (p, a, b, G, n, h) where the finite field F_p is defined by the prime p = 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1.

"},{"id":"VERSION","name":"VERSION","value":"\"0.5.0\"","doc":"The `VERSION` of the `Secp256k1` module.","summary":"

The VERSION of the Secp256k1 module.

"}],"doc":"Provides the `Secp256k1` module with the elliptic curve parameters\nused by the `Bitcoin`, `Ethereum`, and `Polkadot` blockchains. It's\nprimarily used to generate key-pairs as well as signing messages and\nrecoverying signatures.\n\nRef: [secg.org/sec2-v2.pdf](https://www.secg.org/sec2-v2.pdf)","summary":"

Provides the Secp256k1 module with the elliptic curve parameters used by the Bitcoin, Ethereum, and Polkadot blockchains.

","types":[{"html_id":"secp256k1/Secp256k1/Context","path":"Secp256k1/Context.html","kind":"class","full_name":"Secp256k1::Context","name":"Context","abstract":false,"superclass":{"html_id":"secp256k1/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"secp256k1/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"secp256k1/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/secp256k1/context.cr","line_number":22,"url":null}],"repository_name":"secp256k1","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"secp256k1/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"Provides a `Secp256k1` context to allow signing arbitrary data,\nrecovering public keys, and verifying signatures.\n\n```\nctx = Context.new\n# => #\n```","summary":"

Provides a Secp256k1 context to allow signing arbitrary data, recovering public keys, and verifying signatures.

","instance_methods":[{"html_id":"sign(key:Key,hash:Num):Signature-instance-method","name":"sign","doc":"Signs a message hash or any other arbitrary data with a given keypair.\n\nParameters:\n* `key` (`Key`): the keypair containing a secret to sign the data.\n* `hash` (`Num`): the message or arbirtrary data hash.\n\nReturns a `Signature` proving the given key signed the message hash.\n\n```\nctx = Context.new\nkey = Key.new Num.new \"1f0c122d41ff536b19bfd83537c0dfc290e45cd3c375a43237c8b8fff7ac8af7\"\nhash = Util.sha256 \"Henlo, Wordl\"\nsig = ctx.sign key, hash\n# => #,\n# @s=#,\n# @v=#>\n```","summary":"

Signs a message hash or any other arbitrary data with a given keypair.

","abstract":false,"args":[{"name":"key","external_name":"key","restriction":"Key"},{"name":"hash","external_name":"hash","restriction":"Num"}],"args_string":"(key : Key, hash : Num) : Signature","args_html":"(key : Key, hash : Num) : Signature","location":{"filename":"src/secp256k1/context.cr","line_number":50,"url":null},"def":{"name":"sign","args":[{"name":"key","external_name":"key","restriction":"Key"},{"name":"hash","external_name":"hash","restriction":"Num"}],"return_type":"Signature","visibility":"Public","body":"k = Util.deterministic_k(key.private_key, hash)\nhash = hash.to_big\npriv = key.private_key.to_big\npoint = Curve.mul(G, k)\nr = point.x.to_big % N.to_big\nk_inv = Curve.mod_inv(k, N)\ns = ((hash + (r * priv)) * k_inv.to_big) % N.to_big\nx_mag = point.x.to_big > N.to_big\ny_parity = (point.y.to_big % 2) == 0\nrec_id : Int8 = -1\nif (!y_parity) && x_mag\n rec_id = 3\nelse\n if y_parity && x_mag\n rec_id = 2\n else\n if (!y_parity) && (!x_mag)\n rec_id = 1\n else\n rec_id = 0\n end\n end\nend\nr = Num.new(r)\ns = Num.new(s)\nv = Num.new(BigInt.new(rec_id))\nSignature.new(r, s, v)\n"}},{"html_id":"verify(sig:Signature,hash:Num,publ:Point):Bool-instance-method","name":"verify","doc":"Verifies that a given signature for a given message hash matches\nthe provided public key.\n\nParameters:\n* `sig` (`Signature`): the signature to be verified.\n* `hash` (`Num`): the message or arbirtrary data hash.\n* `publ` (`Point`): the public key to match.\n\nReturns _true_ if the signature verifies.\n\n```\nctx = Context.new\nr = Num.new \"c4079db44240b7afe94985c69fc89602e33629fd9b8623d711c30ce6378b33df\"\ns = Num.new \"6842c1b63c94bdb8e4f5ae88fb65f7a98b77b197c8323004fb47ef57fab29053\"\nv = Num.new \"00\"\nsig = Signature.new r, s, v\nhash = Util.sha256 \"Henlo, Wordl\"\npubl = Point.new \"0416008a369439f1a8a75cf974860bed5b10180518d6b1dd3ac847f423fd375d6aa29474394f0cd79d2ea543507d069e97339284f01bdbfd27392daec0ec553816\"\nctx.verify sig, hash, publ\n# => true\n```","summary":"

Verifies that a given signature for a given message hash matches the provided public key.

","abstract":false,"args":[{"name":"sig","external_name":"sig","restriction":"Signature"},{"name":"hash","external_name":"hash","restriction":"Num"},{"name":"publ","external_name":"publ","restriction":"Point"}],"args_string":"(sig : Signature, hash : Num, publ : Point) : Bool","args_html":"(sig : Signature, hash : Num, publ : Point) : Bool","location":{"filename":"src/secp256k1/context.cr","line_number":97,"url":null},"def":{"name":"verify","args":[{"name":"sig","external_name":"sig","restriction":"Signature"},{"name":"hash","external_name":"hash","restriction":"Num"},{"name":"publ","external_name":"publ","restriction":"Point"}],"return_type":"Bool","visibility":"Public","body":"s_inv = Curve.mod_inv(sig.s, N)\np0 = Curve.mul(G, (hash.to_big * s_inv.to_big) % N.to_big)\np1 = Curve.mul(publ, (sig.r.to_big * s_inv.to_big) % N.to_big)\np = Curve.add(p0, p1)\nsig.r.to_big === p.x.to_big\n"}}]},{"html_id":"secp256k1/Secp256k1/Curve","path":"Secp256k1/Curve.html","kind":"module","full_name":"Secp256k1::Curve","name":"Curve","abstract":false,"locations":[{"filename":"src/secp256k1/curve.cr","line_number":18,"url":null}],"repository_name":"secp256k1","program":false,"enum":false,"alias":false,"const":false,"extended_modules":[{"html_id":"secp256k1/Secp256k1/Curve","kind":"module","full_name":"Secp256k1::Curve","name":"Curve"}],"namespace":{"html_id":"secp256k1/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"Implements 256-bit `Secp256k1` Koblitz elliptic curve operations.\n\nRef: [secg.org/sec2-v2.pdf](https://www.secg.org/sec2-v2.pdf)","summary":"

Implements 256-bit Secp256k1 Koblitz elliptic curve operations.

","instance_methods":[{"html_id":"add(p:Point,q:Point,prime=P):Point-instance-method","name":"add","doc":"Computes the elliptic curve jive addition of point `p(x, y)` and `q(x, y)`.\nIt _draws_ a line between `p` and `q` which will intersect the\ncurve in the point `r` which will be mirrored over the `x`-axis.\n\nParamters:\n* `p` (`Num`): the point `p(x, y)` to be used in the jive addition.\n* `q` (`Num`): the point `q(x, y)` to be used in the jive addition.\n* `prime` (`Num`): the prime number that shapes the field (default `P`).\n\nReturns a `Point` containing the result of the intersection.\n```\np = Point.new Num.new \"5cb1eec17e38b004a8fd90fa8e423432430f60d76c30bb33f4091243c029e86d\"\nq = Point.new Num.new \"7e17f60baa7b8dc8581a55f7be1ea263c6a88452cf3f0a3f710651767654946c\"\nCurve.add p, q\n# => #,\n# @y=#>\n```","summary":"

Computes the elliptic curve jive addition of point p(x, y) and q(x, y).

","abstract":false,"args":[{"name":"p","external_name":"p","restriction":"Point"},{"name":"q","external_name":"q","restriction":"Point"},{"name":"prime","default_value":"P","external_name":"prime","restriction":""}],"args_string":"(p : Point, q : Point, prime = P) : Point","args_html":"(p : Point, q : Point, prime = P) : Point","location":{"filename":"src/secp256k1/curve.cr","line_number":82,"url":null},"def":{"name":"add","args":[{"name":"p","external_name":"p","restriction":"Point"},{"name":"q","external_name":"q","restriction":"Point"},{"name":"prime","default_value":"P","external_name":"prime","restriction":""}],"return_type":"Point","visibility":"Public","body":"if prime.is_a?(Num)\n prime = prime.to_big\nend\np_x = p.x.to_big\np_y = p.y.to_big\nq_x = q.x.to_big\nq_y = q.y.to_big\nx_delta = q_x - p_x\nx_inv = mod_inv(x_delta)\ny_delta = q_y - p_y\nm = (y_delta * x_inv.to_big) % prime\nx = (((m * m) - p_x) - q_x) % prime\ny = ((m * (p_x - x)) - p_y) % prime\nx = Num.new(x)\ny = Num.new(y)\nPoint.new(x, y)\n"}},{"html_id":"double(p:Point,prime=P):Point-instance-method","name":"double","doc":"Computes the elliptic curve juke point doubling of `p(x, y)`.\nThis is a special case of addition where both points are the same.\nIt _draws_ a tangent line at `p` which will intersect the curve\nat point `r` which will be mirrored over the `x`-axis.\n\nParamters:\n* `p` (`Point`): the point `p(x, y)` to be used in the juke doubling.\n* `prime` (`Num`): the prime number that shapes the field (default `P`).\n\nReturns a `Point` as a result of the intersection.\n\n```\np = Point.new Num.new \"5cb1eec17e38b004a8fd90fa8e423432430f60d76c30bb33f4091243c029e86d\"\nCurve.double p\n# => #,\n# @y=#>\n```","summary":"

Computes the elliptic curve juke point doubling of p(x, y).

","abstract":false,"args":[{"name":"p","external_name":"p","restriction":"Point"},{"name":"prime","default_value":"P","external_name":"prime","restriction":""}],"args_string":"(p : Point, prime = P) : Point","args_html":"(p : Point, prime = P) : Point","location":{"filename":"src/secp256k1/curve.cr","line_number":123,"url":null},"def":{"name":"double","args":[{"name":"p","external_name":"p","restriction":"Point"},{"name":"prime","default_value":"P","external_name":"prime","restriction":""}],"return_type":"Point","visibility":"Public","body":"if prime.is_a?(Num)\n prime = prime.to_big\nend\np_x = p.x.to_big\np_y = p.y.to_big\nlam_numer = (3 * p_x) * p_x\nlam_denom = 2 * p_y\nlam_inv = mod_inv(Num.new(lam_denom))\nlam = (lam_numer * lam_inv.to_big) % prime\nx = ((lam * lam) - (2 * p_x)) % prime\ny = ((lam * (p_x - x)) - p_y) % prime\nx = Num.new(x)\ny = Num.new(y)\nPoint.new(x, y)\n"}},{"html_id":"mod_inv(a:Num|BigInt,prime=P):Num-instance-method","name":"mod_inv","doc":"Computes the elliptic curve modular multiplicative inverse of `a`.\n\nParemeters:\n* `a` (`Num | BigInt`): the integer that we want the modular inverse of.\n* `prime` (`Num`): the prime number that shapes the field (default `P`).\n\nReturns a `Num` containing the mod inverse.\n\n```\na = Num.new \"ea678c668356d16d8bf5c69f95c1055e39bd24174605f64846e27c3ae6a88d81\"\nCurve.mod_inv a\n# => #\n```","summary":"

Computes the elliptic curve modular multiplicative inverse of a.

","abstract":false,"args":[{"name":"a","external_name":"a","restriction":"Num | BigInt"},{"name":"prime","default_value":"P","external_name":"prime","restriction":""}],"args_string":"(a : Num | BigInt, prime = P) : Num","args_html":"(a : Num | BigInt, prime = P) : Num","location":{"filename":"src/secp256k1/curve.cr","line_number":37,"url":null},"def":{"name":"mod_inv","args":[{"name":"a","external_name":"a","restriction":"Num | BigInt"},{"name":"prime","default_value":"P","external_name":"prime","restriction":""}],"return_type":"Num","visibility":"Public","body":"if a.is_a?(Num)\n a = a.to_big\nend\nif prime.is_a?(Num)\n prime = prime.to_big\nend\nm_low = 1\nm_high = 0\nv_low = a % prime\nv_high = prime\nwhile v_low > 1\n v_ratio = v_high // v_low\n m_low_r = m_low * v_ratio\n v_low_r = v_low * v_ratio\n m = m_high - m_low_r\n v = v_high - v_low_r\n m_high = m_low\n v_high = v_low\n m_low = m\n v_low = v\nend\nNum.new(m_low % prime)\n"}},{"html_id":"mul(p:Point,s:Num|BigInt):Point-instance-method","name":"mul","doc":"Computes the elliptic curve sequence multiplication of point `p(x, y)`\nand a skalar `s`; with `s` being a private key within the elliptic\ncurve field size of `N`.\n\nParamters:\n* `p` (`Point`): the point `p(x, y)` to be used in the sequencing.\n* `s` (`Num | BigInt`): a skalar, in most cases a private key.\n\nReturns a `Point` as a result of the multiplication.\n\n```\np = Point.new Num.new \"5cb1eec17e38b004a8fd90fa8e423432430f60d76c30bb33f4091243c029e86d\"\ns = Num.new \"f51ad125548b7a283ebf15ab830a25c850d4d863078c48cc9993b79ee18ee11e\"\nCurve.mul p, s\n# => #,\n# @y=#>\n```","summary":"

Computes the elliptic curve sequence multiplication of point p(x, y) and a skalar s; with s being a private key within the elliptic curve field size of N.

","abstract":false,"args":[{"name":"p","external_name":"p","restriction":"Point"},{"name":"s","external_name":"s","restriction":"Num | BigInt"}],"args_string":"(p : Point, s : Num | BigInt) : Point","args_html":"(p : Point, s : Num | BigInt) : Point","location":{"filename":"src/secp256k1/curve.cr","line_number":162,"url":null},"def":{"name":"mul","args":[{"name":"p","external_name":"p","restriction":"Point"},{"name":"s","external_name":"s","restriction":"Num | BigInt"}],"return_type":"Point","visibility":"Public","body":"if s.is_a?(Num)\n s = s.to_big\nend\nif (s === 0) || s >= N.to_big\n raise(\"Invalid scalar: outside of Secp256k1 field dimension.\")\nend\ns_bin = s.to_s(2)\nq = p\ns_bin.each_char_with_index do |char, index|\n if index === 0\n next\n end\n q = double(q)\n if char === '1'\n q = add(q, p)\n end\nend\nq\n"}}]},{"html_id":"secp256k1/Secp256k1/Key","path":"Secp256k1/Key.html","kind":"class","full_name":"Secp256k1::Key","name":"Key","abstract":false,"superclass":{"html_id":"secp256k1/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"secp256k1/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"secp256k1/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/secp256k1/key.cr","line_number":21,"url":null}],"repository_name":"secp256k1","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"secp256k1/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"Provides a `Secp256k1` keypair containing a secret number (private key)\nand a public point on the elliptic curve (public key).\n\nProperties:\n* `private_key` (`Num`): the secret number representing the private key.\n* `public_key` (`Point`): the point on the elliptic curve representing the public key.","summary":"

Provides a Secp256k1 keypair containing a secret number (private key) and a public point on the elliptic curve (public key).

","constructors":[{"html_id":"new(priv:Num)-class-method","name":"new","doc":"Creates a public-private keypair from an existing private key.\n\nParameters:\n* `priv` (`Num`): the private key for the keypair.\n\n```\npriv = Num.new \"3ccf84820c20d5e8c536ba84c52ba410375b29b1812b5f7e722445c969a0fb30\"\nKey.new priv\n# => #,\n# @public_key=#,\n# @y=#>>\n```","summary":"

Creates a public-private keypair from an existing private key.

","abstract":false,"args":[{"name":"priv","external_name":"priv","restriction":"Num"}],"args_string":"(priv : Num)","args_html":"(priv : Num)","location":{"filename":"src/secp256k1/key.cr","line_number":74,"url":null},"def":{"name":"new","args":[{"name":"priv","external_name":"priv","restriction":"Num"}],"visibility":"Public","body":"_ = allocate\n_.initialize(priv)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}},{"html_id":"new-class-method","name":"new","doc":"Creates a new, random `Secp256k1` keypair.\n\n```\nKey.new\n# => #,\n# @public_key=#,\n# @y=#>>\n```","summary":"

Creates a new, random Secp256k1 keypair.

","abstract":false,"location":{"filename":"src/secp256k1/key.cr","line_number":46,"url":null},"def":{"name":"new","visibility":"Public","body":"_ = allocate\n_.initialize\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"html_id":"private_bytes:Bytes-instance-method","name":"private_bytes","doc":"Returns the private key as binary byte slice.\n\n```\nKey.new(Num.new \"3ccf84820c20d5e8c536ba84c52ba410375b29b1812b5f7e722445c969a0fb30\").private_bytes\n# => Bytes[60, 207, 132, 130, 12, 32, 213, 232, 197, 54, 186, 132, 197, 43, 164, 16, 55, 91, 41, 177, 129, 43, 95, 126, 114, 36, 69, 201, 105, 160, 251, 48]\n```","summary":"

Returns the private key as binary byte slice.

","abstract":false,"location":{"filename":"src/secp256k1/key.cr","line_number":95,"url":null},"def":{"name":"private_bytes","return_type":"Bytes","visibility":"Public","body":"@private_key.to_zpadded_bytes"}},{"html_id":"private_hex:String-instance-method","name":"private_hex","doc":"Returns the private key as hexadecimal string literal.\n\n```\nKey.new(Num.new \"3ccf84820c20d5e8c536ba84c52ba410375b29b1812b5f7e722445c969a0fb30\").private_hex\n# => \"3ccf84820c20d5e8c536ba84c52ba410375b29b1812b5f7e722445c969a0fb30\"\n```","summary":"

Returns the private key as hexadecimal string literal.

","abstract":false,"location":{"filename":"src/secp256k1/key.cr","line_number":85,"url":null},"def":{"name":"private_hex","return_type":"String","visibility":"Public","body":"@private_key.to_zpadded_hex"}},{"html_id":"private_key:Num-instance-method","name":"private_key","doc":"The secret number representing the private key.","summary":"

The secret number representing the private key.

","abstract":false,"location":{"filename":"src/secp256k1/key.cr","line_number":23,"url":null},"def":{"name":"private_key","return_type":"Num","visibility":"Public","body":"@private_key"}},{"html_id":"private_key=(private_key:Num)-instance-method","name":"private_key=","doc":"The secret number representing the private key.","summary":"

The secret number representing the private key.

","abstract":false,"args":[{"name":"private_key","external_name":"private_key","restriction":"Num"}],"args_string":"(private_key : Num)","args_html":"(private_key : Num)","location":{"filename":"src/secp256k1/key.cr","line_number":23,"url":null},"def":{"name":"private_key=","args":[{"name":"private_key","external_name":"private_key","restriction":"Num"}],"visibility":"Public","body":"@private_key = private_key"}},{"html_id":"public_bytes:Bytes-instance-method","name":"public_bytes","doc":"Returns the public key as uncompressed, binary byte slice.\n\n```\nKey.new(Num.new \"3ccf84820c20d5e8c536ba84c52ba410375b29b1812b5f7e722445c969a0fb30\").public_bytes\n# => Bytes[4, 205, 74, 135, 18, 238, 110, 252, 21, 181, 171, 227, 124, 13, 191, 169, 121, 216, 156, 66, 125, 63, 226, 75, 7, 96, 8, 222, 206, 254, 148, 219, 162, 129, 54, 61, 41, 142, 74, 64, 235, 203, 19, 241, 175, 168, 90, 11, 148, 185, 103, 242, 67, 238, 89, 165, 144, 16, 203, 93, 234, 240, 215, 182, 108]\n```","summary":"

Returns the public key as uncompressed, binary byte slice.

","abstract":false,"location":{"filename":"src/secp256k1/key.cr","line_number":125,"url":null},"def":{"name":"public_bytes","return_type":"Bytes","visibility":"Public","body":"(Num.new(@public_key.uncompressed)).to_bytes"}},{"html_id":"public_bytes_compressed:Bytes-instance-method","name":"public_bytes_compressed","doc":"Returns the public key as compressed, binary byte slice.\n\n```\nKey.new(Num.new \"3ccf84820c20d5e8c536ba84c52ba410375b29b1812b5f7e722445c969a0fb30\").public_bytes_compressed\n# => Bytes[2, 205, 74, 135, 18, 238, 110, 252, 21, 181, 171, 227, 124, 13, 191, 169, 121, 216, 156, 66, 125, 63, 226, 75, 7, 96, 8, 222, 206, 254, 148, 219, 162]\n```","summary":"

Returns the public key as compressed, binary byte slice.

","abstract":false,"location":{"filename":"src/secp256k1/key.cr","line_number":135,"url":null},"def":{"name":"public_bytes_compressed","return_type":"Bytes","visibility":"Public","body":"(Num.new(@public_key.compressed)).to_bytes"}},{"html_id":"public_hex:String-instance-method","name":"public_hex","doc":"Returns the public key as uncompressed, hexadecimal string literal.\n\n```\nKey.new(Num.new \"3ccf84820c20d5e8c536ba84c52ba410375b29b1812b5f7e722445c969a0fb30\").public_hex\n# => \"04cd4a8712ee6efc15b5abe37c0dbfa979d89c427d3fe24b076008decefe94dba281363d298e4a40ebcb13f1afa85a0b94b967f243ee59a59010cb5deaf0d7b66c\"\n```","summary":"

Returns the public key as uncompressed, hexadecimal string literal.

","abstract":false,"location":{"filename":"src/secp256k1/key.cr","line_number":105,"url":null},"def":{"name":"public_hex","return_type":"String","visibility":"Public","body":"@public_key.uncompressed"}},{"html_id":"public_hex_compressed:String-instance-method","name":"public_hex_compressed","doc":"Returns the public key as compressed, hexadecimal string literal.\n\n```\nKey.new(Num.new \"3ccf84820c20d5e8c536ba84c52ba410375b29b1812b5f7e722445c969a0fb30\").public_hex_compressed\n# => \"02cd4a8712ee6efc15b5abe37c0dbfa979d89c427d3fe24b076008decefe94dba2\"\n```","summary":"

Returns the public key as compressed, hexadecimal string literal.

","abstract":false,"location":{"filename":"src/secp256k1/key.cr","line_number":115,"url":null},"def":{"name":"public_hex_compressed","return_type":"String","visibility":"Public","body":"@public_key.compressed"}},{"html_id":"public_key:Point-instance-method","name":"public_key","doc":"The point on the elliptic curve representing the public key.","summary":"

The point on the elliptic curve representing the public key.

","abstract":false,"location":{"filename":"src/secp256k1/key.cr","line_number":25,"url":null},"def":{"name":"public_key","return_type":"Point","visibility":"Public","body":"@public_key"}},{"html_id":"public_key=(public_key:Point)-instance-method","name":"public_key=","doc":"The point on the elliptic curve representing the public key.","summary":"

The point on the elliptic curve representing the public key.

","abstract":false,"args":[{"name":"public_key","external_name":"public_key","restriction":"Point"}],"args_string":"(public_key : Point)","args_html":"(public_key : Point)","location":{"filename":"src/secp256k1/key.cr","line_number":25,"url":null},"def":{"name":"public_key=","args":[{"name":"public_key","external_name":"public_key","restriction":"Point"}],"visibility":"Public","body":"@public_key = public_key"}}]},{"html_id":"secp256k1/Secp256k1/Num","path":"Secp256k1/Num.html","kind":"class","full_name":"Secp256k1::Num","name":"Num","abstract":false,"superclass":{"html_id":"secp256k1/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"secp256k1/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"secp256k1/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/secp256k1/num.cr","line_number":25,"url":null}],"repository_name":"secp256k1","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"secp256k1/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"Provides a class to conveniently handle big numbers on the elliptic\ncurve. It allows to easily access decimal, hexadecimal, and binary\nrepresentations of the numeric. In addition, it implements some\nutilities such as zpadding or asserting hexadecimal strings. It's suited\nto temporarily handle unencrypted private keys.\n\nProperties:\n* `hex` (`String`): the hexadecimal string representation of the number.\n* `dec` (`BigInt`): the decimal big-integer representation of the number.\n* `bin` (`Bytes`): the binary bytes-slice represenation of the number.","summary":"

Provides a class to conveniently handle big numbers on the elliptic curve.

","constructors":[{"html_id":"new(hex:String)-class-method","name":"new","doc":"Creates a number from a hexadecimal string literal.\n\nParameters:\n* `hex` (`String`): a hexadecimal string representating the number.\n\n```\nNum.new \"568a0f505bde902db4a6afd207c794c7845fe7715da5999bb276d453c702a46d\"\n# => #\n```","summary":"

Creates a number from a hexadecimal string literal.

","abstract":false,"args":[{"name":"hex","external_name":"hex","restriction":"String"}],"args_string":"(hex : String)","args_html":"(hex : String)","location":{"filename":"src/secp256k1/num.cr","line_number":67,"url":null},"def":{"name":"new","args":[{"name":"hex","external_name":"hex","restriction":"String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(hex)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}},{"html_id":"new(num:BigInt)-class-method","name":"new","doc":"Creates a number from a big integer numeric.\n\nParameters:\n* `dec` (`BigInt`): the decimal big-integer representating the number.\n\n```\nNum.new BigInt.new \"39142835565766237398843902819171565157710677457569850027793715608438337348717\"\n# => #\n```","summary":"

Creates a number from a big integer numeric.

","abstract":false,"args":[{"name":"num","external_name":"num","restriction":"BigInt"}],"args_string":"(num : BigInt)","args_html":"(num : BigInt)","location":{"filename":"src/secp256k1/num.cr","line_number":87,"url":null},"def":{"name":"new","args":[{"name":"num","external_name":"num","restriction":"BigInt"}],"visibility":"Public","body":"_ = allocate\n_.initialize(num)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}},{"html_id":"new(bin:Slice(UInt8))-class-method","name":"new","doc":"Creates a number from a binary bytes slice.\n\nParameters:\n* `bin` (`Bytes`): the binary bytes-slice represenating the number.\n\n```\nNum.new Bytes[86, 138, 15, 80, 91, 222, 144, 45, 180, 166, 175, 210, 7, 199, 148, 199, 132, 95, 231, 113, 93, 165, 153, 155, 178, 118, 212, 83, 199, 2, 164, 109]\n# => #\n```","summary":"

Creates a number from a binary bytes slice.

","abstract":false,"args":[{"name":"bin","external_name":"bin","restriction":"Slice(UInt8)"}],"args_string":"(bin : Slice(UInt8))","args_html":"(bin : Slice(UInt8))","location":{"filename":"src/secp256k1/num.cr","line_number":107,"url":null},"def":{"name":"new","args":[{"name":"bin","external_name":"bin","restriction":"Slice(UInt8)"}],"visibility":"Public","body":"_ = allocate\n_.initialize(bin)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}},{"html_id":"new-class-method","name":"new","doc":"Creates a random number using `Random::Secure` that can be used as\na secret (private key).\n\n```\nNum.new\n# => #\n```","summary":"

Creates a random number using Random::Secure that can be used as a secret (private key).

","abstract":false,"location":{"filename":"src/secp256k1/num.cr","line_number":43,"url":null},"def":{"name":"new","visibility":"Public","body":"_ = allocate\n_.initialize\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"html_id":"bin:Slice(UInt8)-instance-method","name":"bin","doc":"The binary bytes-slice represenation of the number.","summary":"

The binary bytes-slice represenation of the number.

","abstract":false,"location":{"filename":"src/secp256k1/num.cr","line_number":31,"url":null},"def":{"name":"bin","return_type":"Slice(UInt8)","visibility":"Public","body":"@bin"}},{"html_id":"bin=(bin:Slice(UInt8))-instance-method","name":"bin=","doc":"The binary bytes-slice represenation of the number.","summary":"

The binary bytes-slice represenation of the number.

","abstract":false,"args":[{"name":"bin","external_name":"bin","restriction":"Slice(UInt8)"}],"args_string":"(bin : Slice(UInt8))","args_html":"(bin : Slice(UInt8))","location":{"filename":"src/secp256k1/num.cr","line_number":31,"url":null},"def":{"name":"bin=","args":[{"name":"bin","external_name":"bin","restriction":"Slice(UInt8)"}],"visibility":"Public","body":"@bin = bin"}},{"html_id":"dec:BigInt-instance-method","name":"dec","doc":"The decimal big-integer representation of the number.","summary":"

The decimal big-integer representation of the number.

","abstract":false,"location":{"filename":"src/secp256k1/num.cr","line_number":29,"url":null},"def":{"name":"dec","return_type":"BigInt","visibility":"Public","body":"@dec"}},{"html_id":"dec=(dec:BigInt)-instance-method","name":"dec=","doc":"The decimal big-integer representation of the number.","summary":"

The decimal big-integer representation of the number.

","abstract":false,"args":[{"name":"dec","external_name":"dec","restriction":"BigInt"}],"args_string":"(dec : BigInt)","args_html":"(dec : BigInt)","location":{"filename":"src/secp256k1/num.cr","line_number":29,"url":null},"def":{"name":"dec=","args":[{"name":"dec","external_name":"dec","restriction":"BigInt"}],"visibility":"Public","body":"@dec = dec"}},{"html_id":"hex:String-instance-method","name":"hex","doc":"The hexadecimal string representation of the number.","summary":"

The hexadecimal string representation of the number.

","abstract":false,"location":{"filename":"src/secp256k1/num.cr","line_number":27,"url":null},"def":{"name":"hex","return_type":"String","visibility":"Public","body":"@hex"}},{"html_id":"hex=(hex:String)-instance-method","name":"hex=","doc":"The hexadecimal string representation of the number.","summary":"

The hexadecimal string representation of the number.

","abstract":false,"args":[{"name":"hex","external_name":"hex","restriction":"String"}],"args_string":"(hex : String)","args_html":"(hex : String)","location":{"filename":"src/secp256k1/num.cr","line_number":27,"url":null},"def":{"name":"hex=","args":[{"name":"hex","external_name":"hex","restriction":"String"}],"visibility":"Public","body":"@hex = hex"}},{"html_id":"to_big:BigInt-instance-method","name":"to_big","doc":"Returns a big-integer representation of the number.\n\n```\nNum.new(Bytes[137]).to_big\n# => 137\n```","summary":"

Returns a big-integer representation of the number.

","abstract":false,"location":{"filename":"src/secp256k1/num.cr","line_number":156,"url":null},"def":{"name":"to_big","return_type":"BigInt","visibility":"Public","body":"@dec"}},{"html_id":"to_bytes:Bytes-instance-method","name":"to_bytes","doc":"Returns a binary byte-slice representation of the number.\n\n```\nNum.new(\"0x89\").to_bytes\n# => Bytes[137]\n```","summary":"

Returns a binary byte-slice representation of the number.

","abstract":false,"location":{"filename":"src/secp256k1/num.cr","line_number":166,"url":null},"def":{"name":"to_bytes","return_type":"Bytes","visibility":"Public","body":"@bin"}},{"html_id":"to_hex:String-instance-method","name":"to_hex","doc":"Returns an unprefixed hexadecimal string representation.\n\n```\nNum.new(Bytes[137]).to_hex\n# => \"89\"\n```","summary":"

Returns an unprefixed hexadecimal string representation.

","abstract":false,"location":{"filename":"src/secp256k1/num.cr","line_number":119,"url":null},"def":{"name":"to_hex","return_type":"String","visibility":"Public","body":"@hex"}},{"html_id":"to_prefixed_hex:String-instance-method","name":"to_prefixed_hex","doc":"Returns an `0x`-prefixed hexadecimal string representation.\n\n```\nNum.new(Bytes[137]).to_prefixed_hex\n# => \"0x89\"\n```","summary":"

Returns an 0x-prefixed hexadecimal string representation.

","abstract":false,"location":{"filename":"src/secp256k1/num.cr","line_number":129,"url":null},"def":{"name":"to_prefixed_hex","return_type":"String","visibility":"Public","body":"\"0x#{@hex}\""}},{"html_id":"to_zpadded_bytes(length=32):Bytes-instance-method","name":"to_zpadded_bytes","doc":"Returns a z-padded byte-slice binary representation.\n\nParameters:\n* `length` (`Int`): the byte-size of the final z-padded slice (default `32`).\n\n```\nNum.new(Bytes[137]).to_zpadded_bytes\n# => Bytes[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 137]\n```","summary":"

Returns a z-padded byte-slice binary representation.

","abstract":false,"args":[{"name":"length","default_value":"32","external_name":"length","restriction":""}],"args_string":"(length = 32) : Bytes","args_html":"(length = 32) : Bytes","location":{"filename":"src/secp256k1/num.cr","line_number":179,"url":null},"def":{"name":"to_zpadded_bytes","args":[{"name":"length","default_value":"32","external_name":"length","restriction":""}],"return_type":"Bytes","visibility":"Public","body":"zpadded_bytes = @bin\nwhile zpadded_bytes.size < length\n zpadded_bytes = Util.concat_bytes(Bytes[0], zpadded_bytes)\nend\nzpadded_bytes\n"}},{"html_id":"to_zpadded_hex(length=32):String-instance-method","name":"to_zpadded_hex","doc":"Returns a z-padded hexadecimal string representation.\n\nParameters:\n* `length` (`Int`): the byte-size of the final z-padded hex-string (default `32`).\n\n```\nNum.new(Bytes[137]).to_zpadded_hex\n# => \"0000000000000000000000000000000000000000000000000000000000000089\"\n```","summary":"

Returns a z-padded hexadecimal string representation.

","abstract":false,"args":[{"name":"length","default_value":"32","external_name":"length","restriction":""}],"args_string":"(length = 32) : String","args_html":"(length = 32) : String","location":{"filename":"src/secp256k1/num.cr","line_number":142,"url":null},"def":{"name":"to_zpadded_hex","args":[{"name":"length","default_value":"32","external_name":"length","restriction":""}],"return_type":"String","visibility":"Public","body":"zpadded_hex = @hex\nwhile zpadded_hex.size < (length * 2)\n zpadded_hex = \"0#{zpadded_hex}\"\nend\nzpadded_hex\n"}}]},{"html_id":"secp256k1/Secp256k1/Point","path":"Secp256k1/Point.html","kind":"class","full_name":"Secp256k1::Point","name":"Point","abstract":false,"superclass":{"html_id":"secp256k1/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"secp256k1/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"secp256k1/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/secp256k1/point.cr","line_number":30,"url":null}],"repository_name":"secp256k1","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"secp256k1/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"Provides a point in the two-dimensional space of any elliptic curve.\nIn most cases, such a point on a given curve represents a public key.\nHowever, for keypairs, a `Key` type shall be used!\n\nProperties:\n* `x` (`Num`): the position on the x-axis.\n* `y` (`Num`): the position on the y-axis.","summary":"

Provides a point in the two-dimensional space of any elliptic curve.

","constructors":[{"html_id":"new(x:Num,y:Num)-class-method","name":"new","doc":"Provides a public point in the two-dimensional space on the given `Secp256k1`\nelliptic curve by passing the x- and y-coordinates (public key).\n\nParameters:\n* `x` (`Num`): the position on the x-axis.\n* `y` (`Num`): the position on the y-axis.\n\n```\nx = Num.new \"efc4f8d8bfc778463e4d4916d88bf3f057e6dc96cb2adc26dfb91959c4bef4a5\"\ny = Num.new \"cecd9a83fefafcb3cf99fde0c340bbe2fed9cdd0d25b53f4e08254acefb69ae0\"\nPoint.new x, y\n# => #,\n# @y=#>\n```","summary":"

Provides a public point in the two-dimensional space on the given Secp256k1 elliptic curve by passing the x- and y-coordinates (public key).

","abstract":false,"args":[{"name":"x","external_name":"x","restriction":"Num"},{"name":"y","external_name":"y","restriction":"Num"}],"args_string":"(x : Num, y : Num)","args_html":"(x : Num, y : Num)","location":{"filename":"src/secp256k1/point.cr","line_number":58,"url":null},"def":{"name":"new","args":[{"name":"x","external_name":"x","restriction":"Num"},{"name":"y","external_name":"y","restriction":"Num"}],"visibility":"Public","body":"_ = allocate\n_.initialize(x, y)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}},{"html_id":"new(priv:Num)-class-method","name":"new","doc":"Provides a public point in the two-dimensional space on the given `Secp256k1`\nelliptic curve by passing a random number (private key). Note, that the\nprivate key will be consumed by this constructor and should only be used\nto retrieve a public key. To manage keypairs, use the `Key` type instead.\n\nParameters:\n* `priv` (`Num`): the random number giving access to the point.\n\n```\npriv = Num.new \"e50932676c9901f259659d62f0c56fd899feca3f57ecab147a5ef8a0b59defc3\"\nPoint.new priv\n# => #,\n# @y=#>\n```","summary":"

Provides a public point in the two-dimensional space on the given Secp256k1 elliptic curve by passing a random number (private key).

","abstract":false,"args":[{"name":"priv","external_name":"priv","restriction":"Num"}],"args_string":"(priv : Num)","args_html":"(priv : Num)","location":{"filename":"src/secp256k1/point.cr","line_number":84,"url":null},"def":{"name":"new","args":[{"name":"priv","external_name":"priv","restriction":"Num"}],"visibility":"Public","body":"_ = allocate\n_.initialize(priv)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}},{"html_id":"new(pub:String)-class-method","name":"new","doc":"Provides a public point in the two-dimensional space on the given `Secp256k1`\nelliptic curve by passing a compressed or uncompressed public key.\n\nParameters:\n* `pub` (`String`): the public key string (compressed or uncompressed).\n\n```\npub = \"03aff8674d6b96a6c58dbab08b903565363271308888340a2caddf88e56165930f\"\nPoint.new pub\n# => #,\n# @y=#>\n```","summary":"

Provides a public point in the two-dimensional space on the given Secp256k1 elliptic curve by passing a compressed or uncompressed public key.

","abstract":false,"args":[{"name":"pub","external_name":"pub","restriction":"String"}],"args_string":"(pub : String)","args_html":"(pub : String)","location":{"filename":"src/secp256k1/point.cr","line_number":109,"url":null},"def":{"name":"new","args":[{"name":"pub","external_name":"pub","restriction":"String"}],"visibility":"Public","body":"_ = allocate\n_.initialize(pub)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"html_id":"compressed:String-instance-method","name":"compressed","doc":"Returns a prefixed, compressed public key string for the given point\nin the format `prefix|x|y`.\n\n```\npriv = Num.new \"e50932676c9901f259659d62f0c56fd899feca3f57ecab147a5ef8a0b59defc3\"\nPoint.new(priv).compressed\n# => \"03aff8674d6b96a6c58dbab08b903565363271308888340a2caddf88e56165930f\"\n```","summary":"

Returns a prefixed, compressed public key string for the given point in the format prefix|x|y.

","abstract":false,"location":{"filename":"src/secp256k1/point.cr","line_number":161,"url":null},"def":{"name":"compressed","return_type":"String","visibility":"Public","body":"prefix = 2 + (@y.to_big % 2)\nprefix = \"0#{prefix}\"\n\"#{prefix}#{@x.to_zpadded_hex}\"\n"}},{"html_id":"uncompressed:String-instance-method","name":"uncompressed","doc":"Returns a prefixed, uncompressed public key string for the given point\nin the format `04|x|y`.\n\n```\npriv = Num.new \"e50932676c9901f259659d62f0c56fd899feca3f57ecab147a5ef8a0b59defc3\"\nPoint.new(priv).uncompressed\n# => \"04aff8674d6b96a6c58dbab08b903565363271308888340a2caddf88e56165930f21f4c49cfe90da39c254a51b8ee8afcdd8c02dd566f13582c23e104c7ed5936b\"\n```","summary":"

Returns a prefixed, uncompressed public key string for the given point in the format 04|x|y.

","abstract":false,"location":{"filename":"src/secp256k1/point.cr","line_number":148,"url":null},"def":{"name":"uncompressed","return_type":"String","visibility":"Public","body":"prefix = \"04\"\n\"#{prefix}#{@x.to_zpadded_hex}#{@y.to_zpadded_hex}\"\n"}},{"html_id":"x:Num-instance-method","name":"x","doc":"The position on the x-axis.","summary":"

The position on the x-axis.

","abstract":false,"location":{"filename":"src/secp256k1/point.cr","line_number":32,"url":null},"def":{"name":"x","return_type":"Num","visibility":"Public","body":"@x"}},{"html_id":"x=(x:Num)-instance-method","name":"x=","doc":"The position on the x-axis.","summary":"

The position on the x-axis.

","abstract":false,"args":[{"name":"x","external_name":"x","restriction":"Num"}],"args_string":"(x : Num)","args_html":"(x : Num)","location":{"filename":"src/secp256k1/point.cr","line_number":32,"url":null},"def":{"name":"x=","args":[{"name":"x","external_name":"x","restriction":"Num"}],"visibility":"Public","body":"@x = x"}},{"html_id":"y:Num-instance-method","name":"y","doc":"The position on the y-axis.","summary":"

The position on the y-axis.

","abstract":false,"location":{"filename":"src/secp256k1/point.cr","line_number":35,"url":null},"def":{"name":"y","return_type":"Num","visibility":"Public","body":"@y"}},{"html_id":"y=(y:Num)-instance-method","name":"y=","doc":"The position on the y-axis.","summary":"

The position on the y-axis.

","abstract":false,"args":[{"name":"y","external_name":"y","restriction":"Num"}],"args_string":"(y : Num)","args_html":"(y : Num)","location":{"filename":"src/secp256k1/point.cr","line_number":35,"url":null},"def":{"name":"y=","args":[{"name":"y","external_name":"y","restriction":"Num"}],"visibility":"Public","body":"@y = y"}}]},{"html_id":"secp256k1/Secp256k1/Signature","path":"Secp256k1/Signature.html","kind":"class","full_name":"Secp256k1::Signature","name":"Signature","abstract":false,"superclass":{"html_id":"secp256k1/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"secp256k1/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"secp256k1/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/secp256k1/signature.cr","line_number":22,"url":null}],"repository_name":"secp256k1","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"secp256k1/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"Provides an ECDSA Signature containing the random point `r`, the\nsignature proof `s`, and the recovery id or `v` value.\n\nProperties:\n* `r` (`Num`): the `x` coordinate of a random point `R` on the curve.\n* `s` (`Num`): the signature proof of a message.\n* `v` (`Num`): the recovery id or `v` value.","summary":"

Provides an ECDSA Signature containing the random point #r, the signature proof #s, and the recovery id or #v value.

","constructors":[{"html_id":"new(r:Num,s:Num,v:Num)-class-method","name":"new","doc":"Provides an ECDSA Signature containing the random point `r`, the\nsignature proof `s`, and the recovery id or `v` value.\n\nParameters:\n* `r` (`Num`): the `x` coordinate of a random point `R` on the curve.\n* `s` (`Num`): the signature proof of a message.\n* `v` (`Num`): the recovery id or `v` value.\n\n```\nr = Num.new \"efc4f8d8bfc778463e4d4916d88bf3f057e6dc96cb2adc26dfb91959c4bef4a5\"\ns = Num.new \"cecd9a83fefafcb3cf99fde0c340bbe2fed9cdd0d25b53f4e08254acefb69ae0\"\nv = Num.new \"00\"\nSignature.new r, s, v\n# => #,\n# @s=#,\n# @v=#>\n```","summary":"

Provides an ECDSA Signature containing the random point #r, the signature proof #s, and the recovery id or #v value.

","abstract":false,"args":[{"name":"r","external_name":"r","restriction":"Num"},{"name":"s","external_name":"s","restriction":"Num"},{"name":"v","external_name":"v","restriction":"Num"}],"args_string":"(r : Num, s : Num, v : Num)","args_html":"(r : Num, s : Num, v : Num)","location":{"filename":"src/secp256k1/signature.cr","line_number":59,"url":null},"def":{"name":"new","args":[{"name":"r","external_name":"r","restriction":"Num"},{"name":"s","external_name":"s","restriction":"Num"},{"name":"v","external_name":"v","restriction":"Num"}],"visibility":"Public","body":"_ = allocate\n_.initialize(r, s, v)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"html_id":"compact:String-instance-method","name":"compact","doc":"Returns a compact `String` containing the concatenated signature\nin the form `r|s|v`.\n\n```\nr = Num.new \"efc4f8d8bfc778463e4d4916d88bf3f057e6dc96cb2adc26dfb91959c4bef4a5\"\ns = Num.new \"cecd9a83fefafcb3cf99fde0c340bbe2fed9cdd0d25b53f4e08254acefb69ae0\"\nv = Num.new \"00\"\nSignature.new(r, s, v).compact\n# => \"efc4f8d8bfc778463e4d4916d88bf3f057e6dc96cb2adc26dfb91959c4bef4a5cecd9a83fefafcb3cf99fde0c340bbe2fed9cdd0d25b53f4e08254acefb69ae000\"\n```","summary":"

Returns a compact String containing the concatenated signature in the form r|s|v.

","abstract":false,"location":{"filename":"src/secp256k1/signature.cr","line_number":75,"url":null},"def":{"name":"compact","return_type":"String","visibility":"Public","body":"\"#{r.to_zpadded_hex}#{s.to_zpadded_hex}#{v.to_hex}\""}},{"html_id":"r:Num-instance-method","name":"r","doc":"The `x` coordinate of a random point `R` on the curve.","summary":"

The x coordinate of a random point R on the curve.

","abstract":false,"location":{"filename":"src/secp256k1/signature.cr","line_number":24,"url":null},"def":{"name":"r","return_type":"Num","visibility":"Public","body":"@r"}},{"html_id":"r=(r:Num)-instance-method","name":"r=","doc":"The `x` coordinate of a random point `R` on the curve.","summary":"

The x coordinate of a random point R on the curve.

","abstract":false,"args":[{"name":"r","external_name":"r","restriction":"Num"}],"args_string":"(r : Num)","args_html":"(r : Num)","location":{"filename":"src/secp256k1/signature.cr","line_number":24,"url":null},"def":{"name":"r=","args":[{"name":"r","external_name":"r","restriction":"Num"}],"visibility":"Public","body":"@r = r"}},{"html_id":"s:Num-instance-method","name":"s","doc":"The signature proof of a message.","summary":"

The signature proof of a message.

","abstract":false,"location":{"filename":"src/secp256k1/signature.cr","line_number":27,"url":null},"def":{"name":"s","return_type":"Num","visibility":"Public","body":"@s"}},{"html_id":"s=(s:Num)-instance-method","name":"s=","doc":"The signature proof of a message.","summary":"

The signature proof of a message.

","abstract":false,"args":[{"name":"s","external_name":"s","restriction":"Num"}],"args_string":"(s : Num)","args_html":"(s : Num)","location":{"filename":"src/secp256k1/signature.cr","line_number":27,"url":null},"def":{"name":"s=","args":[{"name":"s","external_name":"s","restriction":"Num"}],"visibility":"Public","body":"@s = s"}},{"html_id":"v:Num-instance-method","name":"v","doc":"The recovery id or `v` value.","summary":"

The recovery id or #v value.

","abstract":false,"location":{"filename":"src/secp256k1/signature.cr","line_number":30,"url":null},"def":{"name":"v","return_type":"Num","visibility":"Public","body":"@v"}},{"html_id":"v=(v:Num)-instance-method","name":"v=","doc":"The recovery id or `v` value.","summary":"

The recovery id or #v value.

","abstract":false,"args":[{"name":"v","external_name":"v","restriction":"Num"}],"args_string":"(v : Num)","args_html":"(v : Num)","location":{"filename":"src/secp256k1/signature.cr","line_number":30,"url":null},"def":{"name":"v=","args":[{"name":"v","external_name":"v","restriction":"Num"}],"visibility":"Public","body":"@v = v"}}]},{"html_id":"secp256k1/Secp256k1/Util","path":"Secp256k1/Util.html","kind":"module","full_name":"Secp256k1::Util","name":"Util","abstract":false,"locations":[{"filename":"src/secp256k1/util.cr","line_number":17,"url":null}],"repository_name":"secp256k1","program":false,"enum":false,"alias":false,"const":false,"extended_modules":[{"html_id":"secp256k1/Secp256k1/Util","kind":"module","full_name":"Secp256k1::Util","name":"Util"}],"namespace":{"html_id":"secp256k1/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"Provides a collection of utilities for convenience, e.g., to bind\nrelevant hashing algorithms, or to concatenate byte slices.","summary":"

Provides a collection of utilities for convenience, e.g., to bind relevant hashing algorithms, or to concatenate byte slices.

","instance_methods":[{"html_id":"concat_bytes(x:Bytes,y:Bytes):Bytes-instance-method","name":"concat_bytes","doc":"Concatenates two byte slices in the order provided, i.e., `x|y`.\n\nParameters:\n* `x` (`Bytes`): a byte slice.\n* `y` (`Bytes`): another byte slice.\n\nReturns a concatenated `Bytes` slice.\n\n```\nUtil.concat_bytes Bytes[1, 2, 3], Bytes[9, 8, 7]\n# => Bytes[1, 2, 3, 9, 8, 7]\n```","summary":"

Concatenates two byte slices in the order provided, i.e., x|y.

","abstract":false,"args":[{"name":"x","external_name":"x","restriction":"Bytes"},{"name":"y","external_name":"y","restriction":"Bytes"}],"args_string":"(x : Bytes, y : Bytes) : Bytes","args_html":"(x : Bytes, y : Bytes) : Bytes","location":{"filename":"src/secp256k1/util.cr","line_number":177,"url":null},"def":{"name":"concat_bytes","args":[{"name":"x","external_name":"x","restriction":"Bytes"},{"name":"y","external_name":"y","restriction":"Bytes"}],"return_type":"Bytes","visibility":"Public","body":"z = IO::Memory.new(x.bytesize + y.bytesize)\nx.each do |b|\n z.write_bytes(UInt8.new(b))\nend\ny.each do |b|\n z.write_bytes(UInt8.new(b))\nend\nreturn z.to_slice\n"}},{"html_id":"deterministic_k(priv:Num,hash:Num,order=N):Num-instance-method","name":"deterministic_k","doc":"Provides a deterministic secret based on private key and message hash\nas defined in RFC-6979.\n\nRef: [datatracker.ietf.org/doc/html/rfc6979](https://datatracker.ietf.org/doc/html/rfc6979)\n\nParameters:\n* `priv` (`Num`): the private key or secret number.\n* `hash` (`Num`): the message hash or arbirtrary data hash.\n* `order` (`Num`): the order of the curve over `G` (default `N`).\n\nReturns a deterministically random number of type `Num`.\n\n```\npriv = Num.new \"3b74fcc0b0c419a00d2d9e88b15fbd99e03920138da22e2a00c327b88d24cf45\"\nhash = Util.sha256 \"Henlo, Wordl\"\nUtil.deterministic_k(priv, hash)\n# => #\n```","summary":"

Provides a deterministic secret based on private key and message hash as defined in RFC-6979.

","abstract":false,"args":[{"name":"priv","external_name":"priv","restriction":"Num"},{"name":"hash","external_name":"hash","restriction":"Num"},{"name":"order","default_value":"N","external_name":"order","restriction":""}],"args_string":"(priv : Num, hash : Num, order = N) : Num","args_html":"(priv : Num, hash : Num, order = N) : Num","location":{"filename":"src/secp256k1/util.cr","line_number":135,"url":null},"def":{"name":"deterministic_k","args":[{"name":"priv","external_name":"priv","restriction":"Num"},{"name":"hash","external_name":"hash","restriction":"Num"},{"name":"order","default_value":"N","external_name":"order","restriction":""}],"return_type":"Num","visibility":"Public","body":"order_size = order.hex.size // 2\nv = Num.new(Bytes.new(order_size, 1))\nk = Num.new(Bytes.new(order_size, 0))\nconcat = Util.concat_bytes(v.bin, Bytes[0])\nconcat = Util.concat_bytes(concat, priv.bin)\nconcat = Util.concat_bytes(concat, hash.bin)\nk = OpenSSL::HMAC.digest(:sha256, k.bin, concat)\nv = OpenSSL::HMAC.digest(:sha256, k, v.bin)\nconcat = Util.concat_bytes(v, Bytes[0])\nconcat = Util.concat_bytes(concat, priv.bin)\nconcat = Util.concat_bytes(concat, hash.bin)\nk = OpenSSL::HMAC.digest(:sha256, k, concat)\nv = OpenSSL::HMAC.digest(:sha256, k, v)\nwhile true\n t = IO::Memory.new.to_slice\n while t.size < order_size\n v = OpenSSL::HMAC.digest(:sha256, k, v)\n t = Util.concat_bytes(t, v)\n end\n secret = Num.new(t)\n if secret.dec < order.dec && secret.dec > 0\n return secret\n end\n increment = Util.concat_bytes(v, Bytes[0])\n k = OpenSSL::HMAC.digest(:sha256, k, increment)\n v = OpenSSL::HMAC.digest(:sha256, k, v)\nend\n"}},{"html_id":"keccak(data:Num|String,entropy=256):Num-instance-method","name":"keccak","doc":"Operating a Keccak hash on a binary/number or string literal.\n\nParameters:\n* `data` (`Num | String`): the binary numeric or string literal to be hashed.\n* `entropy` (`Int32`): the required entropy (default `256`).\n\nReturns a `Num` representing the Keccak hash.\n\n```\nUtil.keccak(Num.new \"0xdeadbeef\").hex\n# => \"d4fd4e189132273036449fc9e11198c739161b4c0116a9a2dccdfa1c492006f1\"\n\nUtil.keccak(\"0xdeadbeef\").hex\n# => \"4f440a001006a49f24a7de53c04eca3f79aef851ac58e460c9630d044277c8b0\"\n```","summary":"

Operating a Keccak hash on a binary/number or string literal.

","abstract":false,"args":[{"name":"data","external_name":"data","restriction":"Num | String"},{"name":"entropy","default_value":"256","external_name":"entropy","restriction":""}],"args_string":"(data : Num | String, entropy = 256) : Num","args_html":"(data : Num | String, entropy = 256) : Num","location":{"filename":"src/secp256k1/util.cr","line_number":35,"url":null},"def":{"name":"keccak","args":[{"name":"data","external_name":"data","restriction":"Num | String"},{"name":"entropy","default_value":"256","external_name":"entropy","restriction":""}],"return_type":"Num","visibility":"Public","body":"keccak = Digest::Keccak3.new(entropy)\nif data.is_a?(String)\n return Num.new((keccak.update(data)).hexdigest)\nelse\n return Num.new((keccak.update(data.to_bytes)).hexdigest)\nend\n"}},{"html_id":"ripemd160(data:Num|String):Num-instance-method","name":"ripemd160","doc":"Operating a RIPEMD-160 hash on a binary/number or string literal.\n\nParameters:\n* `data` (`Num | String`): the binary numeric or string literal to be hashed.\n\nReturns a `Num` representing the RIPEMD hash.\n\n```\nUtil.ripemd160(Num.new \"0xdeadbeef\").hex\n# => \"226821c2f5423e11fe9af68bd285c249db2e4b5a\"\n\nUtil.ripemd160(\"0xdeadbeef\").hex\n# => \"4caf817f14e84b564e47afd19966e5d123ee0183\"\n```","summary":"

Operating a RIPEMD-160 hash on a binary/number or string literal.

","abstract":false,"args":[{"name":"data","external_name":"data","restriction":"Num | String"}],"args_string":"(data : Num | String) : Num","args_html":"(data : Num | String) : Num","location":{"filename":"src/secp256k1/util.cr","line_number":105,"url":null},"def":{"name":"ripemd160","args":[{"name":"data","external_name":"data","restriction":"Num | String"}],"return_type":"Num","visibility":"Public","body":"ripemd = OpenSSL::Digest.new(\"RIPEMD160\")\nif data.is_a?(String)\n return Num.new((ripemd.update(data)).final.hexstring)\nelse\n return Num.new((ripemd.update(data.to_bytes)).final.hexstring)\nend\n"}},{"html_id":"sha256(data:Num|String):Num-instance-method","name":"sha256","doc":"Operating a SHA2-256 hash on a binary/number or string literal.\n\nParameters:\n* `data` (`Num | String`): the binary numeric or string literal to be hashed.\n\nReturns a `Num` representing the SHA2 hash.\n\n```\nUtil.sha256(Num.new \"0xdeadbeef\").hex\n# => \"5f78c33274e43fa9de5659265c1d917e25c03722dcb0b8d27db8d5feaa813953\"\n\nUtil.sha256(\"0xdeadbeef\").hex\n# => \"4142710b9b4caaeb000b8e5de271bbebac7f509aab2f5e61d1ed1958bfe6d583\"\n```","summary":"

Operating a SHA2-256 hash on a binary/number or string literal.

","abstract":false,"args":[{"name":"data","external_name":"data","restriction":"Num | String"}],"args_string":"(data : Num | String) : Num","args_html":"(data : Num | String) : Num","location":{"filename":"src/secp256k1/util.cr","line_number":82,"url":null},"def":{"name":"sha256","args":[{"name":"data","external_name":"data","restriction":"Num | String"}],"return_type":"Num","visibility":"Public","body":"sha2 = OpenSSL::Digest.new(\"SHA256\")\nif data.is_a?(String)\n return Num.new((sha2.update(data)).final.hexstring)\nelse\n return Num.new((sha2.update(data.to_bytes)).final.hexstring)\nend\n"}},{"html_id":"sha3(data:Num|String,entropy=256):Num-instance-method","name":"sha3","doc":"Operating a SHA3 hash on a binary/number or string literal.\n\nParameters:\n* `data` (`Num | String`): the binary numeric or string literal to be hashed.\n* `entropy` (`Int32`): the required entropy (default `256`).\n\nReturns a `Num` representing the SHA3 hash.\n\n```\nUtil.sha3(Num.new \"0xdeadbeef\").hex\n# => \"352b82608dad6c7ac3dd665bc2666e5d97803cb13f23a1109e2105e93f42c448\"\n\nUtil.sha3(\"0xdeadbeef\").hex\n# => \"c12811e13ed75afe3e0945ef34e8a25b9d321a46e131c6463731de25a21b39eb\"\n```","summary":"

Operating a SHA3 hash on a binary/number or string literal.

","abstract":false,"args":[{"name":"data","external_name":"data","restriction":"Num | String"},{"name":"entropy","default_value":"256","external_name":"entropy","restriction":""}],"args_string":"(data : Num | String, entropy = 256) : Num","args_html":"(data : Num | String, entropy = 256) : Num","location":{"filename":"src/secp256k1/util.cr","line_number":59,"url":null},"def":{"name":"sha3","args":[{"name":"data","external_name":"data","restriction":"Num | String"},{"name":"entropy","default_value":"256","external_name":"entropy","restriction":""}],"return_type":"Num","visibility":"Public","body":"sha3 = Digest::SHA3.new(entropy)\nif data.is_a?(String)\n return Num.new((sha3.update(data)).hexdigest)\nelse\n return Num.new((sha3.update(data.to_bytes)).hexdigest)\nend\n"}}]}]}]}}) \ No newline at end of file diff --git a/spec/secp256k1/key_spec.cr b/spec/secp256k1/key_spec.cr index ce6bf58..196f506 100644 --- a/spec/secp256k1/key_spec.cr +++ b/spec/secp256k1/key_spec.cr @@ -25,7 +25,7 @@ describe Secp256k1::Key do end end - it "generates valid kai-pairs from private key" do + it "generates valid key-pairs from private key" do priv = Num.new "a0dc65ffca799873cbea0ac274015b9526505daaaed385155425f7337704883e" key = Key.new priv key.private_hex.should eq "a0dc65ffca799873cbea0ac274015b9526505daaaed385155425f7337704883e" diff --git a/src/secp256k1/num.cr b/src/secp256k1/num.cr index 8d623e0..380ca36 100644 --- a/src/secp256k1/num.cr +++ b/src/secp256k1/num.cr @@ -178,15 +178,8 @@ class Secp256k1::Num # ``` def to_zpadded_bytes(length = 32) : Bytes zpadded_bytes = @bin - byte_zero = Bytes[0] while zpadded_bytes.size < length - slice_size = zpadded_bytes.size + 1 - zpadded_slice = Slice(UInt8).new slice_size - slice_pointer = zpadded_slice.to_unsafe - byte_zero.copy_to(slice_pointer, 0) - slice_pointer += 1 - zpadded_bytes.copy_to(slice_pointer, zpadded_bytes.size) - zpadded_bytes = zpadded_slice + zpadded_bytes = Util.concat_bytes Bytes[0x00], zpadded_bytes end zpadded_bytes end