diff --git a/src/index.html b/src/index.html index 95bd51d..7efab54 100644 --- a/src/index.html +++ b/src/index.html @@ -2692,6 +2692,26 @@ body.dark .layoutTab.active, body.dark button.primary { color:#fff; } .sheetWrap{margin:0 auto;} + +
@@ -4387,6 +4407,147 @@ const safe$ = (id) => { try { return $(id); } catch { return null; } }; const on = (id, type, fn) => { const el = $(id); if (el) el.addEventListener(type, fn); }; + // ---- NWC crypto (Phase 0) ------------------------------------------------ + // The NIP-47 (Nostr Wallet Connect) flow signs / encrypts as a *different* + // pubkey than the user's identity — the NWC URI carries its own secret key. + // window.nostr can only operate on the user's identity, so we need a + // bundled secp256k1 + NIP-04 implementation. The bundle (noble-bundle.min.js, + // loaded above) provides schnorr + ECDH + sha256; we layer NIP-04 (AES-256 + // -CBC via crypto.subtle) and a tiny event-signing helper on top. + const NWC = (() => { + const N = () => window.ArtstrNoble; + + const utf8ToBytes = (s) => new TextEncoder().encode(s); + const bytesToUtf8 = (b) => new TextDecoder().decode(b); + const bytesToBase64 = (b) => { + let s = ''; for (let i = 0; i < b.length; i++) s += String.fromCharCode(b[i]); + return btoa(s); + }; + const base64ToBytes = (b64) => Uint8Array.from(atob(b64), (c) => c.charCodeAt(0)); + const hexToBytes = (h) => N().hexToBytes(h); + const bytesToHex = (b) => N().bytesToHex(b); + + // NIP-04: shared secret is the 32-byte X coord of ECDH(priv, pub). + // noble's getSharedSecret returns a 33-byte compressed point — slice the + // 02/03 prefix off. + function sharedSecret(privHex, pubHex) { + const priv = hexToBytes(privHex); + // Pub on the wire is x-only (32 bytes). secp256k1 wants the full point; + // prepend 02 to lift the x to the even-Y point on the curve. + let pub; + if (pubHex.length === 64) pub = hexToBytes('02' + pubHex); + else if (pubHex.length === 66) pub = hexToBytes(pubHex); + else throw new Error('sharedSecret: pubkey must be 32 or 33 bytes hex'); + const compressed = N().getSharedSecret(priv, pub); + return compressed.slice(1, 33); + } + + // NIP-04 encrypt: AES-256-CBC with PKCS#7 padding (Web Crypto default), + // 16-byte random IV. Output: `?iv=`. + async function encrypt04(privHex, peerPubHex, plaintext) { + const key = await crypto.subtle.importKey( + 'raw', sharedSecret(privHex, peerPubHex), + { name: 'AES-CBC' }, false, ['encrypt'] + ); + const iv = crypto.getRandomValues(new Uint8Array(16)); + const ct = new Uint8Array(await crypto.subtle.encrypt( + { name: 'AES-CBC', iv }, key, utf8ToBytes(plaintext) + )); + return bytesToBase64(ct) + '?iv=' + bytesToBase64(iv); + } + + async function decrypt04(privHex, peerPubHex, content) { + const [ctB64, ivPart] = String(content).split('?iv='); + if (!ctB64 || !ivPart) throw new Error('decrypt04: malformed NIP-04 payload'); + const key = await crypto.subtle.importKey( + 'raw', sharedSecret(privHex, peerPubHex), + { name: 'AES-CBC' }, false, ['decrypt'] + ); + const pt = new Uint8Array(await crypto.subtle.decrypt( + { name: 'AES-CBC', iv: base64ToBytes(ivPart) }, key, base64ToBytes(ctB64) + )); + return bytesToUtf8(pt); + } + + // NIP-01 event id = sha256(serialized([0, pubkey, created_at, kind, tags, content])) + function getEventHash(event) { + const serial = JSON.stringify([ + 0, event.pubkey, event.created_at, event.kind, event.tags || [], event.content || '' + ]); + return bytesToHex(N().sha256(utf8ToBytes(serial))); + } + + // Sign an event with a hex privkey (NOT the user's identity key — this + // is for NWC's wallet-side keypair). Returns the event with id + sig + pubkey. + function signEventWithKey(event, privHex) { + const priv = hexToBytes(privHex); + const pubkey = bytesToHex(N().schnorr.getPublicKey(priv)); + const draft = { ...event, pubkey, tags: event.tags || [], content: event.content || '' }; + const id = getEventHash(draft); + const sig = bytesToHex(N().schnorr.sign(hexToBytes(id), priv)); + return { ...draft, id, sig }; + } + + // Verify a Nostr event signature. Used for relay-fast-path receipt + // verification later in Phase 3. + function verifyEvent(event) { + try { + if (!event?.id || !event?.sig || !event?.pubkey) return false; + if (getEventHash(event) !== event.id) return false; + return N().schnorr.verify(hexToBytes(event.sig), hexToBytes(event.id), hexToBytes(event.pubkey)); + } catch { return false; } + } + + // Derive the schnorr x-only pubkey for a hex privkey. + function getPubkeyHex(privHex) { + return bytesToHex(N().schnorr.getPublicKey(hexToBytes(privHex))); + } + + return { + utf8ToBytes, bytesToUtf8, bytesToBase64, base64ToBytes, + hexToBytes, bytesToHex, + sharedSecret, encrypt04, decrypt04, + getEventHash, signEventWithKey, verifyEvent, getPubkeyHex, + }; + })(); + + // Phase-0 self-test (runs once at load). BIP-340 test vector index 1 for + // schnorr signing + a NIP-04 round-trip. Logs a single warning if anything + // breaks; silent on success so we don't spam the console for everyone. + (async () => { + try { + if (!window.ArtstrNoble) throw new Error('noble bundle did not load'); + // BIP-340 test vector #1 (from bitcoin/bips bip-0340/test-vectors.csv). + const tvPriv = 'B7E151628AED2A6ABF7158809CF4F3C762E7160F38B4DA56A784D9045190CFEF'; + const tvPub = 'DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659'; + const tvMsg = '243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89'; + const tvSig = '6896BD60EEAE296DB48A229FF71DFE071BDE413E6D43F917DC8DCF8C78DE33418906D11AC976ABCCB20B091292BFF4EA897EFCB639EA871CFA95F6DE339E4B0A'; + const derivedPub = NWC.getPubkeyHex(tvPriv); + if (derivedPub.toUpperCase() !== tvPub) throw new Error('schnorr pubkey mismatch'); + const okSig = window.ArtstrNoble.schnorr.verify( + NWC.hexToBytes(tvSig), NWC.hexToBytes(tvMsg), NWC.hexToBytes(tvPub) + ); + if (!okSig) throw new Error('schnorr.verify failed on BIP-340 test vector'); + // NIP-04 round-trip: encrypt + decrypt with two random keypairs. + const aPriv = NWC.bytesToHex(window.ArtstrNoble.randomBytes(32)); + const bPriv = NWC.bytesToHex(window.ArtstrNoble.randomBytes(32)); + const aPub = NWC.getPubkeyHex(aPriv); + const bPub = NWC.getPubkeyHex(bPriv); + const msg = 'NIP-04 round-trip — Artstr NWC self-test ✓'; + const ct = await NWC.encrypt04(aPriv, bPub, msg); + const pt = await NWC.decrypt04(bPriv, aPub, ct); + if (pt !== msg) throw new Error('NIP-04 round-trip mismatch'); + // Sign + verify a synthetic Nostr event using a random key. + const ev = { kind: 1, created_at: Math.floor(Date.now() / 1000), tags: [], content: 'hello' }; + const signed = NWC.signEventWithKey(ev, aPriv); + if (!NWC.verifyEvent(signed)) throw new Error('verifyEvent failed on signed event'); + } catch (err) { + console.warn('[Artstr] Crypto self-test failed — NWC features will not work:', err); + } + })(); + // ---- end NWC crypto ----------------------------------------------------- + + // In-app toast — replaces all uses of native toastError(). Default type is // 'info'; use toastError / toastSuccess for the common severity flavors. function toast(message, opts = {}) { diff --git a/src/noble-bundle.min.js b/src/noble-bundle.min.js new file mode 100644 index 0000000..a336a60 --- /dev/null +++ b/src/noble-bundle.min.js @@ -0,0 +1,6 @@ +(()=>{var ae=Object.defineProperty;var ue=(t,e,n)=>e in t?ae(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n;var l=(t,e,n)=>ue(t,typeof e!="symbol"?e+"":e,n);var Ht=Object.freeze({p:0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2fn,n:0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141n,h:1n,a:0n,b:7n,Gx:0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798n,Gy:0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8n}),{p:v,n:Z,Gx:he,Gy:de,b:St}=Ht,w=32,K=64,P={publicKey:w+1,publicKeyUncompressed:K+1,signature:K,seed:w+w/2},b=(t="",e=Error)=>{let n=new e(t),{captureStackTrace:s}=Error;throw typeof s=="function"&&s(n,b),n},le=t=>t instanceof Uint8Array||ArrayBuffer.isView(t)&&t.constructor.name==="Uint8Array"&&t.BYTES_PER_ELEMENT===1,E=(t,e,n="")=>{let s=le(t),r=t?.length,o=e!==void 0;if(!s||o&&r!==e){let c=n&&`"${n}" `,f=o?` of length ${e}`:"",a=s?`length=${r}`:`type=${typeof t}`,h=c+"expected Uint8Array"+f+", got "+a;return s?b(h,RangeError):b(h,TypeError)}return t},j=t=>new Uint8Array(t),Bt=(t,e)=>t.toString(16).padStart(e,"0"),Lt=t=>{let e="";for(let n of E(t))e+=Bt(n,2);return e},_={_0:48,_9:57,A:65,F:70,a:97,f:102},bt=t=>t>=_._0&&t<=_._9?t-_._0:t>=_.A&&t<=_.F?t-(_.A-10):t>=_.a&&t<=_.f?t-(_.a-10):void 0,Ut=t=>{let e="hex invalid";if(typeof t!="string")return b(e);let n=t.length,s=n/2;if(n%2)return b(e);let r=j(s);for(let o=0,c=0;oglobalThis?.crypto?.subtle??b("crypto.subtle must be defined, consider polyfill"),R=(...t)=>{let e=0;for(let r of t)e+=E(r).length;let n=j(e),s=0;for(let r of t)n.set(r,s),s+=r.length;return n},at=(t=w)=>(globalThis?.crypto).getRandomValues(j(t)),ot=BigInt,V=(t,e,n,s="bad number: out of range")=>typeof t!="bigint"?b(s,TypeError):e<=t&&t{let n=t%e;return n>=0n?n:e+n},z=t=>i(t,Z),xe=(t,e)=>{(t===0n||e<=0n)&&b("no inverse n="+t+" mod="+e);let n=i(t,e),s=e,r=0n,o=1n,c=1n,f=0n;for(;n!==0n;){let a=s/n,h=s%n,d=r-c*a,u=o-f*a;s=n,n=h,r=c,o=f,c=d,f=u}return s===1n?i(r,e):b("no inverse")},_t=t=>{let e=J[t];return typeof e!="function"&&b("hashes."+t+" not set"),e},pt=(t,e,n)=>E(_t(t)(e,n),w,"digest"),gt=(t,e,n)=>Promise.resolve(_t(t)(e,n)).then(s=>E(s,w,"digest"));var rt=t=>t instanceof L?t:b("Point expected"),Tt=t=>i(i(t*t)*t+St),mt=t=>V(t,0n,v),M=t=>V(t,1n,v),be=t=>V(t,1n,Z),W=t=>!(t&1n),It=t=>Uint8Array.of(t),ye=t=>It(W(t)?2:3),vt=t=>{let e=Tt(M(t)),n=1n;for(let s=e,r=(v+1n)/4n;r>0n;r>>=1n)r&1n&&(n=n*s%v),s=s*s%v;return i(n*n)!==e&&b("sqrt invalid"),W(n)?n:i(-n)};var B=class B{constructor(e,n,s){l(this,"X");l(this,"Y");l(this,"Z");this.X=mt(e),this.Y=M(n),this.Z=mt(s),Object.freeze(this)}static CURVE(){return Ht}static fromAffine(e){let{x:n,y:s}=e;return n===0n&&s===0n?F:new B(n,s,1n)}static fromBytes(e){E(e);let{publicKey:n,publicKeyUncompressed:s}=P,r,o=e.length,c=e[0],f=e.subarray(1),a=Y(f,0,w);if(o===n&&(c===2||c===3)){let h=vt(a);c===3&&(h=i(-h)),r=new B(a,h,1n)}return o===s&&c===4&&(r=new B(a,Y(f,w,K),1n)),r?r.assertValidity():b("bad point: not on curve")}static fromHex(e){return B.fromBytes(Ut(e))}get x(){return this.toAffine().x}get y(){return this.toAffine().y}equals(e){let{X:n,Y:s,Z:r}=this,{X:o,Y:c,Z:f}=rt(e),a=i(n*f),h=i(o*r),d=i(s*f),u=i(c*r);return a===h&&d===u}is0(){return this.equals(F)}negate(){return new B(this.X,i(-this.Y),this.Z)}double(){return this.add(this)}add(e){let{X:n,Y:s,Z:r}=this,{X:o,Y:c,Z:f}=rt(e),a=0n,h=St,d=0n,u=0n,x=0n,y=i(h*3n),p=i(n*o),g=i(s*c),A=i(r*f),O=i(n+s),m=i(o+c);O=i(O*m),m=i(p+g),O=i(O-m),m=i(n+r);let S=i(o+f);return m=i(m*S),S=i(p+A),m=i(m-S),S=i(s+r),d=i(c+f),S=i(S*d),d=i(g+A),S=i(S-d),x=i(a*m),d=i(y*A),x=i(d+x),d=i(g-x),x=i(g+x),u=i(d*x),g=i(p+p),g=i(g+p),A=i(a*A),m=i(y*m),g=i(g+A),A=i(p-A),A=i(a*A),m=i(m+A),p=i(g*m),u=i(u+p),p=i(S*m),d=i(O*d),d=i(d-p),p=i(O*g),x=i(S*x),x=i(x+p),new B(d,u,x)}subtract(e){return this.add(rt(e).negate())}multiply(e,n=!0){if(!n&&e===0n)return F;if(be(e),e===1n)return this;if(this.equals(C))return _e(e).p;let s=F,r=C;for(let o=this;e>0n;o=o.double(),e>>=1n)e&1n?s=s.add(o):n&&(r=r.add(o));return s}multiplyUnsafe(e){return this.multiply(e,!1)}toAffine(){let{X:e,Y:n,Z:s}=this;if(this.equals(F))return{x:0n,y:0n};if(s===1n)return{x:e,y:n};let r=xe(s,v);return i(s*r)!==1n&&b("inverse invalid"),{x:i(e*r),y:i(n*r)}}assertValidity(){let{x:e,y:n}=this.toAffine();return M(e),M(n),i(n*n)===Tt(e)?this:b("bad point: not on curve")}toBytes(e=!0){let{x:n,y:s}=this.assertValidity().toAffine(),r=U(n);return e?R(ye(s),r):R(It(4),r,U(s))}toHex(e){return Lt(this.toBytes(e))}};l(B,"BASE"),l(B,"ZERO");var L=B,C=new L(he,de,1n),F=new L(0n,1n,0n);L.BASE=C;L.ZERO=F;var pe=(t,e,n)=>C.multiply(e,!1).add(t.multiply(n,!1)).assertValidity(),G=t=>ot("0x"+(Lt(t)||"0")),Y=(t,e,n)=>G(t.subarray(e,n)),ge=2n**256n,U=t=>Ut(Bt(V(t,0n,ge),K)),q=t=>{let e=G(E(t,w,"secret key"));return V(e,1n,Z,"invalid secret key: outside of range")};var Ct=(t,e=!0)=>C.multiply(q(t)).toBytes(e),me=t=>{try{return!!q(t)}catch{return!1}},we=(t,e)=>{let{publicKey:n,publicKeyUncompressed:s}=P;try{let r=t.length;return e===!0&&r!==n||e===!1&&r!==s?!1:!!L.fromBytes(t)}catch{return!1}};var wt="SHA-256",J={hmacSha256Async:async(t,e)=>{let n=yt(),s="HMAC",r=await n.importKey("raw",t,{name:s,hash:{name:wt}},!1,["sign"]);return j(await n.sign(s,r,e))},hmacSha256:void 0,sha256Async:async t=>j(await yt().digest(wt,t)),sha256:void 0};var kt=(t,e,n=!0)=>L.fromBytes(e).multiply(q(t)).toBytes(n),Ft=t=>{if(t=t===void 0?at(P.seed):t,E(t),t.length1024)return b("expected 48-1024b",RangeError);let e=i(G(t),Z-1n);return U(e+1n)},Ae=t=>e=>{let n=Ft(e);return{secretKey:n,publicKey:t(n)}};var Vt=Object.freeze({isValidSecretKey:me,isValidPublicKey:we,randomSecretKey:Ft}),Gt=t=>Uint8Array.from("BIP0340/"+t,e=>e.charCodeAt(0)),Dt="aux",Ot="nonce",Kt="challenge",ct=(t,...e)=>{let n=pt("sha256",Gt(t));return pt("sha256",R(n,n,...e))},it=(t,...e)=>gt("sha256Async",Gt(t)).then(n=>gt("sha256Async",R(n,n,...e))),ut=t=>{let e=q(t),n=C.multiply(e),{x:s,y:r}=n.assertValidity().toAffine(),o=W(r)?e:z(-e),c=U(s);return{d:o,px:c}},ht=t=>z(G(t)),Rt=(...t)=>ht(ct(Kt,...t)),Nt=async(...t)=>ht(await it(Kt,...t)),Xt=t=>ut(t).px,Ee=Ae(Xt),jt=(t,e,n)=>{let{px:s,d:r}=ut(e);return{m:E(t),px:s,d:r,a:E(n,w)}},Zt=t=>{let e=ht(t);e===0n&&b("sign failed: k is zero");let{px:n,d:s}=ut(U(e));return{rx:n,k:s}},Mt=(t,e,n,s)=>R(e,U(z(t+n*s))),Pt="invalid signature produced",He=(t,e,n=at(w))=>{let{m:s,px:r,d:o,a:c}=jt(t,e,n),f=ct(Dt,c),a=U(o^G(f)),h=ct(Ot,a,r,s),{rx:d,k:u}=Zt(h),x=Rt(d,r,s),y=Mt(u,d,x,o);return $t(y,s,r)||b(Pt),y},Se=async(t,e,n=at(w))=>{let{m:s,px:r,d:o,a:c}=jt(t,e,n),f=await it(Dt,c),a=U(o^G(f)),h=await it(Ot,a,r,s),{rx:d,k:u}=Zt(h),x=await Nt(d,r,s),y=Mt(u,d,x,o);return await zt(y,s,r)||b(Pt),y},Be=(t,e)=>t instanceof Promise?t.then(e):e(t),Yt=(t,e,n,s)=>{let r=E(t,K,"signature"),o=E(e,void 0,"message"),c=E(n,w,"publicKey");try{let f=G(c),a=vt(f),h=new L(f,a,1n).assertValidity(),d=U(h.toAffine().x),u=Y(r,0,w);V(u,1n,v);let x=Y(r,w,K);V(x,1n,Z);let y=R(U(u),d,o);return Be(s(y),p=>{let{x:g,y:A}=pe(h,x,z(-p)).toAffine();return!(!W(A)||g!==u)})}catch{return!1}},$t=(t,e,n)=>Yt(t,e,n,Rt),zt=async(t,e,n)=>Yt(t,e,n,Nt),Wt=Object.freeze({keygen:Ee,getPublicKey:Xt,sign:He,verify:$t,signAsync:Se,verifyAsync:zt}),$=8,Le=256,qt=Math.ceil(Le/$)+1,ft=2**($-1),Ue=()=>{let t=[],e=C,n=e;for(let s=0;s{let n=e.negate();return t?n:e},_e=t=>{let e=At||(At=Ue()),n=F,s=C,r=2**$,o=r,c=ot(r-1),f=ot($);for(let a=0;a>=f,h>ft&&(h-=o,t+=1n);let d=a*ft,u=d,x=d+Math.abs(h)-1,y=a%2!==0,p=h<0;h===0?s=s.add(Et(y,e[u])):n=n.add(Et(p,e[x]))}return t!==0n&&b("invalid wnaf"),{p:n,f:s}};function Te(t){return t instanceof Uint8Array||ArrayBuffer.isView(t)&&t.constructor.name==="Uint8Array"&&"BYTES_PER_ELEMENT"in t&&t.BYTES_PER_ELEMENT===1}function dt(t,e=""){if(typeof t!="number"){let n=e&&`"${e}" `;throw new TypeError(`${n}expected number, got ${typeof t}`)}if(!Number.isSafeInteger(t)||t<0){let n=e&&`"${e}" `;throw new RangeError(`${n}expected integer >= 0, got ${t}`)}}function N(t,e,n=""){let s=Te(t),r=t?.length,o=e!==void 0;if(!s||o&&r!==e){let c=n&&`"${n}" `,f=o?` of length ${e}`:"",a=s?`length=${r}`:`type=${typeof t}`,h=c+"expected Uint8Array"+f+", got "+a;throw s?new RangeError(h):new TypeError(h)}return t}function Qt(t){if(typeof t!="function"||typeof t.create!="function")throw new TypeError("Hash must wrapped by utils.createHasher");if(dt(t.outputLen),dt(t.blockLen),t.outputLen<1)throw new Error('"outputLen" must be >= 1');if(t.blockLen<1)throw new Error('"blockLen" must be >= 1')}function X(t,e=!0){if(t.destroyed)throw new Error("Hash instance has been destroyed");if(e&&t.finished)throw new Error("Hash#digest() has already been called")}function Q(t,e){N(t,void 0,"digestInto() output");let n=e.outputLen;if(t.length='+n)}function D(...t){for(let e=0;e>>e}var te=typeof Uint8Array.from([]).toHex=="function"&&typeof Uint8Array.fromHex=="function",Ie=Array.from({length:256},(t,e)=>e.toString(16).padStart(2,"0"));function ee(t){if(N(t),te)return t.toHex();let e="";for(let n=0;n=T._0&&t<=T._9)return t-T._0;if(t>=T.A&&t<=T.F)return t-(T.A-10);if(t>=T.a&&t<=T.f)return t-(T.a-10)}function ne(t){if(typeof t!="string")throw new TypeError("hex string expected, got "+typeof t);if(te)try{return Uint8Array.fromHex(t)}catch(r){throw r instanceof SyntaxError?new RangeError(r.message):r}let e=t.length,n=e/2;if(e%2)throw new RangeError("hex string expected, got unpadded hex of length "+e);let s=new Uint8Array(n);for(let r=0,o=0;rt(o).update(r).digest(),s=t(void 0);return n.outputLen=s.outputLen,n.blockLen=s.blockLen,n.canXOF=s.canXOF,n.create=r=>t(r),Object.assign(n,e),Object.freeze(n)}function re(t=32){dt(t,"bytesLength");let e=typeof globalThis=="object"?globalThis.crypto:null;if(typeof e?.getRandomValues!="function")throw new Error("crypto.getRandomValues must be defined");if(t>65536)throw new RangeError(`"bytesLength" expected <= 65536, got ${t}`);return e.getRandomValues(new Uint8Array(t))}var oe=t=>({oid:Uint8Array.from([6,9,96,134,72,1,101,3,4,2,t])});function ce(t,e,n){return t&e^~t&n}function ie(t,e,n){return t&e^t&n^e&n}var et=class{constructor(e,n,s,r){l(this,"blockLen");l(this,"outputLen");l(this,"canXOF",!1);l(this,"padOffset");l(this,"isLE");l(this,"buffer");l(this,"view");l(this,"finished",!1);l(this,"length",0);l(this,"pos",0);l(this,"destroyed",!1);this.blockLen=e,this.outputLen=n,this.padOffset=s,this.isLE=r,this.buffer=new Uint8Array(e),this.view=tt(this.buffer)}update(e){X(this),N(e);let{view:n,buffer:s,blockLen:r}=this,o=e.length;for(let c=0;cr-c&&(this.process(s,0),c=0);for(let u=c;ud.length)throw new Error("_sha2: outputLen bigger than state");for(let u=0;u>>3,g=H(y,17)^H(y,19)^y>>>10;k[u]=g+k[u-7]+p+k[u-16]|0}let{A:s,B:r,C:o,D:c,E:f,F:a,G:h,H:d}=this;for(let u=0;u<64;u++){let x=H(f,6)^H(f,11)^H(f,25),y=d+x+ce(f,a,h)+ve[u]+k[u]|0,g=(H(s,2)^H(s,13)^H(s,22))+ie(s,r,o)|0;d=h,h=a,a=f,f=c+y|0,c=o,o=r,r=s,s=y+g|0}s=s+this.A|0,r=r+this.B|0,o=o+this.C|0,c=c+this.D|0,f=f+this.E|0,a=a+this.F|0,h=h+this.G|0,d=d+this.H|0,this.set(s,r,o,c,f,a,h,d)}roundClean(){D(k)}destroy(){this.destroyed=!0,this.set(0,0,0,0,0,0,0,0),D(this.buffer)}},xt=class extends lt{constructor(){super(32);l(this,"A",I[0]|0);l(this,"B",I[1]|0);l(this,"C",I[2]|0);l(this,"D",I[3]|0);l(this,"E",I[4]|0);l(this,"F",I[5]|0);l(this,"G",I[6]|0);l(this,"H",I[7]|0)}};var nt=se(()=>new xt,oe(1));var st=class{constructor(e,n){l(this,"oHash");l(this,"iHash");l(this,"blockLen");l(this,"outputLen");l(this,"canXOF",!1);l(this,"finished",!1);l(this,"destroyed",!1);if(Qt(e),N(n,void 0,"key"),this.iHash=e.create(),typeof this.iHash.update!="function")throw new Error("Expected instance of class which extends utils.Hash");this.blockLen=this.iHash.blockLen,this.outputLen=this.iHash.outputLen;let s=this.blockLen,r=new Uint8Array(s);r.set(n.length>s?e.create().update(n).digest():n);for(let o=0;o{let t=((e,n,s)=>new st(e,n).update(s).digest());return t.create=(e,n)=>new st(e,n),t})();J.sha256=nt;J.hmacSha256=(t,...e)=>fe(nt,t,e.length===1?e[0]:(()=>{let n=e.reduce((o,c)=>o+c.length,0),s=new Uint8Array(n),r=0;for(let o of e)s.set(o,r),r+=o.length;return s})());window.ArtstrNoble={schnorr:Wt,getPublicKey:Ct,getSharedSecret:kt,sha256:nt,hexToBytes:ne,bytesToHex:ee,randomBytes:re,secpUtils:Vt};})(); +/*! Bundled license information: + +@noble/secp256k1/index.js: + (*! noble-secp256k1 - MIT License (c) 2019 Paul Miller (paulmillr.com) *) +*/