<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><title> </title><script>"use strict";var CurrentKeyEnc,InitedFormOptions,AlgType,InputMsg,MsgEnc,KeyEnc,Seed,PublicKey,Signature,Kyp,AppMessage;const EmptyMSPPS={Msg:"",SedHex:"",PukHex:"",KypHex:"",SigHex:"",Sed64:"",Puk64:"",Kyp64:"",Sig64:"",Sedb:"",Pukb:"",Kypb:"",Sigb:""},AppMsgEmpty=" ",FormOptions={FormParameters:[{name:"alg_type",id:"AlgType"},{name:"msg_enc",id:"MsgEnc"},{name:"msg",id:"InputMsg"},{name:"key_enc",id:"KeyEnc"},{name:"seed",id:"Seed"},{name:"key",id:"PublicKey"},{name:"sig",id:"Signature"},{name:"verify",type:"bool",funcTrue:async function(){CurrentKeyEnc=KeyEnc.value,Verify()}},]};async function GetMSPPS(){let e={},t=InputMsg.value;switch(MsgEnc.value){case"B64":e.Msg=new Uint8Array(await HexToUI8(B64ToHex(t)));break;case"Hex":e.Msg=new Uint8Array(await HexToUI8(t));break;case"Text":let n=new TextEncoder("utf-8");e.Msg=new Uint8Array(n.encode(t));break;default:return console.error("unsupported message encoding"),null}if("Dig"===AlgType.value)throw AppMessage.textContent=" ",Error(" ");let a=Seed.value,i=PublicKey.value,r=Signature.value;if("Hex"===CurrentKeyEnc?(e.SedHex=a,e.PukHex=i,e.KypHex=a+i,e.SigHex=r):"B64"===CurrentKeyEnc&&(e.SedHex=B64ToHex(a),e.PukHex=B64ToHex(i),e.KypHex=B64ToHex(a)+B64ToHex(i),e.SigHex=B64ToHex(r)),!isEmpty(e.SedHex)&&(128==e.SedHex.length&&(e.SedHex=e.SedHex.slice(0,64)),64!==e.SedHex.length))throw SyntaxError("Seed is not 32 bytes.");try{await SetMSPPSFromHex(e),isEmpty(e.Pukb)&&KeyFromSeed(e)}catch(u){AppMessage.textContent="❌ "+u;return}return e}async function SetMSPPSFromHex(e){e.Sed64=await HexTob64ut(e.SedHex),e.Puk64=await HexTob64ut(e.PukHex),e.Sig64=await HexTob64ut(e.SigHex),e.Kyp64=await HexTob64ut(e.KypHex),e.Sedb=await HexToUI8(e.SedHex),e.Pukb=await HexToUI8(e.PukHex),e.Sigb=await HexToUI8(e.SigHex),e.Kypb=await HexToUI8(e.KypHex)}async function ChangeKeyEncGui(){console.log("ChangeKeyEncGui",CurrentKeyEnc,KeyEnc.value);await SetGuiIn(await GetMSPPS()),CurrentKeyEnc=KeyEnc.value}async function SetGuiIn(e){console.log(e),"Hex"===KeyEnc.value&&(Seed.value=e.SedHex,PublicKey.value=e.PukHex,Signature.value=e.SigHex,Kyp.textContent=e.KypHex),"B64"===KeyEnc.value&&(Seed.value=e.Sed64,PublicKey.value=e.Puk64,Signature.value=e.Sig64,Kyp.textContent=e.Kyp64)}async function GenRadomGUI(){AppMessage.textContent=" ";let e={};e.Sedb=await crypto.getRandomValues(new Uint8Array(32)),e.SedHex=await ArrayBufferToHex(e.Sedb);let t=await window.nobleEd25519.utils.getExtendedPublicKey(e.Sedb);e.PukHex=t.point.toHex().toUpperCase(),e.KypHex=e.SedHex+e.PukHex,e.SigHex="",await SetMSPPSFromHex(e),await SetGuiIn(e)}async function KeyFromSeed(e){console.log("KeyFromSeed",e);let t=await window.nobleEd25519.utils.getExtendedPublicKey(e.Sedb);e.PukHex=t.point.toHex().toUpperCase(),e.KypHex=e.SedHex+e.PukHex,e.Puk64=await HexTob64ut(e.PukHex),e.Kyp64=await HexTob64ut(e.KypHex)}async function KeyFromSeedBtn(){try{AppMessage.textContent=" ";let e=await GetMSPPS();await KeyFromSeed(e),SetGuiIn(e)}catch(t){AppMessage.textContent="❌ "+t;return}}async function Sign(){AppMessage.textContent=" ";try{Signature.value="";var e=await GetMSPPS();if(void 0===e.Sedb)throw SyntaxError("Private key is empty.");if(e.SigHex=await ArrayBufferToHex(await window.nobleEd25519.sign(e.Msg,e.Sedb)),128!==e.SigHex.length)throw RangeError("Invalid Signature length")}catch(t){AppMessage.textContent="❌ "+t;return}e.Sig64=await HexTob64ut(e.SigHex),await SetGuiIn(e),Verify()}async function Verify(){AppMessage.textContent=" ";try{let e=await GetMSPPS();console.log("Verify",e);var t=await window.nobleEd25519.verify(e.Sigb,e.Msg,e.Pukb)}catch(n){console.error(n)}if(!t){AppMessage.textContent="    ❌  Signature is Invalid";return}AppMessage.textContent="    ✅  Signature is Valid"}async function ClearAll(){InputMsg.value="",Seed.value="",PublicKey.value="",Signature.value="",AppMessage.textContent=" ",URLForm.Clear(InitedFormOptions),SetGuiIn(EmptyMSPPS)}function B64ToHex(e){let t=URISafeToUnsafe(e),n=atob(t),a="";for(let i=0;i<n.length;i++){let r=n.charCodeAt(i).toString(16).toUpperCase();a+=2===r.length?r:"0"+r}return a}function URISafeToUnsafe(e){return e.replace(/-/g,"+").replace(/_/g,"/")}async function HexTob64ut(e){return await ArrayBufferTo64ut(await HexToUI8(e))}function URIUnsafeToSafe(e){return e.replace(/\+/g,"-").replace(/\//g,"_")}function base64t(e){return e.replace(/=/g,"")}function ArrayBufferTo64ut(e){return base64t(URIUnsafeToSafe(btoa(String.fromCharCode.apply(null,new Uint8Array(e)))))}async function HexToUI8(e){if(void 0===e)return new Uint8Array;if(e.length%2!=0)throw RangeError("HexToUI8: Hex is not even.");for(var t=new Uint8Array(e.length/2),n=0;n<e.length;n+=2)t[n/2]=parseInt(e.substring(n,n+2),16);return t}async function ArrayBufferToHex(e){return[...new Uint8Array(e)].map(e=>e.toString(16).padStart(2,"0")).join("").toUpperCase()}function isEmpty(e){return"function"!=typeof e&&(!!Array.isArray(e)&&0==e.length||(e===Object(e)?0===Object.keys(e).length:!isBool(e)))}function isBool(e){return!(!1===e||"false"===e||void 0===e||"undefined"===e||""===e||0===e||"0"===e||null===e||"null"===e||"NaN"===e||Number.isNaN(e))&&e!==Object(e)}document.addEventListener("DOMContentLoaded",async()=>{AlgType=document.getElementById("AlgType"),InputMsg=document.getElementById("InputMsg"),MsgEnc=document.getElementById("MsgEnc"),KeyEnc=document.getElementById("KeyEnc"),Seed=document.getElementById("Seed"),PublicKey=document.getElementById("PublicKey"),Signature=document.getElementById("Signature"),Kyp=document.getElementById("Kyp"),AppMessage=document.getElementById("AppMessage");try{await URLForm.Populate(InitedFormOptions=await URLForm.Init(FormOptions))}catch(e){console.info("Unable to start share button/share link (URLFormJS).  If this was suppose to work, see the docs on cloning `URLFormJS`."),document.querySelectorAll(".shareElement").forEach(function(e){e.style.display="none"})}AppMessage.textContent=" ",CurrentKeyEnc=KeyEnc.value,document.getElementById("GenRandKeyPairBtn").addEventListener("click",GenRadomGUI),document.getElementById("GenKeyFromSeedBtn").addEventListener("click",KeyFromSeedBtn),document.getElementById("SignBtn").addEventListener("click",Sign),document.getElementById("VerifyBtn").addEventListener("click",Verify),document.getElementById("ClearBtn").addEventListener("click",ClearAll),KeyEnc.addEventListener("change",ChangeKeyEncGui)});
