paseto-browser
Version:
In-browser JavaScript implementation of PASETO
2 lines (1 loc) • 15.7 kB
JavaScript
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("tweetnacl"),require("crypto")):"function"==typeof define&&define.amd?define(["exports","tweetnacl","crypto"],e):e(((t="undefined"!=typeof globalThis?globalThis:t||self).paserk=t.paserk||{},t.paserk.k4=t.paserk.k4||{},t.paserk.k4.seal={}),t.nacl,t.crypto)}(this,(function(t,e,n){"use strict";function r(t){if(t&&t.__esModule)return t;var e=Object.create(null);return t&&Object.keys(t).forEach((function(n){if("default"!==n){var r=Object.getOwnPropertyDescriptor(t,n);Object.defineProperty(e,n,r.get?r:{enumerable:!0,get:function(){return t[n]}})}})),e.default=t,Object.freeze(e)}var o=r(e);function i(t){let e;if(t instanceof Uint8Array)e=t;else{if("string"!=typeof t)throw new Error("Input must be an string, Buffer or Uint8Array");e=(new TextEncoder).encode(t)}return e}function c(t,e,n){const r=t[e]+t[n];let o=t[e+1]+t[n+1];r>=4294967296&&o++,t[e]=r,t[e+1]=o}function s(t,e,n,r){let o=t[e]+n;n<0&&(o+=4294967296);let i=t[e+1]+r;o>=4294967296&&i++,t[e]=o,t[e+1]=i}function l(t,e){return t[e]^t[e+1]<<8^t[e+2]<<16^t[e+3]<<24}function a(t,e,n,r,o,i){const l=d[o],a=d[o+1],u=d[i],f=d[i+1];c(y,t,e),s(y,t,l,a);let h=y[r]^y[t],w=y[r+1]^y[t+1];y[r]=w,y[r+1]=h,c(y,n,r),h=y[e]^y[n],w=y[e+1]^y[n+1],y[e]=h>>>24^w<<8,y[e+1]=w>>>24^h<<8,c(y,t,e),s(y,t,u,f),h=y[r]^y[t],w=y[r+1]^y[t+1],y[r]=h>>>16^w<<16,y[r+1]=w>>>16^h<<16,c(y,n,r),h=y[e]^y[n],w=y[e+1]^y[n+1],y[e]=w>>>31^h<<1,y[e+1]=h>>>31^w<<1}const u=new Uint32Array([4089235720,1779033703,2227873595,3144134277,4271175723,1013904242,1595750129,2773480762,2917565137,1359893119,725511199,2600822924,4215389547,528734635,327033209,1541459225]),f=new Uint8Array([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,14,10,4,8,9,15,13,6,1,12,0,2,11,7,5,3,11,8,12,0,5,2,15,13,10,14,3,6,7,1,9,4,7,9,3,1,13,12,11,14,2,6,5,10,4,0,15,8,9,0,5,7,2,4,10,15,14,1,11,12,6,8,3,13,2,12,6,10,0,11,8,3,4,13,7,5,15,14,1,9,12,5,1,15,14,13,4,10,0,7,6,3,9,2,8,11,13,11,7,14,12,1,3,9,5,0,15,4,8,6,2,10,6,15,14,9,11,3,0,8,12,2,13,7,1,4,10,5,10,2,8,4,7,6,1,5,15,11,9,14,3,12,13,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,14,10,4,8,9,15,13,6,1,12,0,2,11,7,5,3].map((function(t){return 2*t}))),y=new Uint32Array(32),d=new Uint32Array(32);function h(t,e){let n=0;for(n=0;n<16;n++)y[n]=t.h[n],y[n+16]=u[n];for(y[24]=y[24]^t.t,y[25]=y[25]^t.t/4294967296,e&&(y[28]=~y[28],y[29]=~y[29]),n=0;n<32;n++)d[n]=l(t.b,4*n);for(n=0;n<12;n++)a(0,8,16,24,f[16*n+0],f[16*n+1]),a(2,10,18,26,f[16*n+2],f[16*n+3]),a(4,12,20,28,f[16*n+4],f[16*n+5]),a(6,14,22,30,f[16*n+6],f[16*n+7]),a(0,10,20,30,f[16*n+8],f[16*n+9]),a(2,12,22,24,f[16*n+10],f[16*n+11]),a(4,14,16,26,f[16*n+12],f[16*n+13]),a(6,8,18,28,f[16*n+14],f[16*n+15]);for(n=0;n<16;n++)t.h[n]=t.h[n]^y[n]^y[n+16]}const w=new Uint8Array([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,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,0,0]);function p(t,e,n,r){if(0===t||t>64)throw new Error("Illegal output length, expected 0 < length <= 64");if(e&&e.length>64)throw new Error("Illegal key, expected Uint8Array with 0 < length <= 64");if(n&&16!==n.length)throw new Error("Illegal salt, expected Uint8Array with length is 16");if(r&&16!==r.length)throw new Error("Illegal personal, expected Uint8Array with length is 16");const o={b:new Uint8Array(128),h:new Uint32Array(16),t:0,c:0,outlen:t};w.fill(0),w[0]=t,e&&(w[1]=e.length),w[2]=1,w[3]=1,n&&w.set(n,32),r&&w.set(r,48);for(let t=0;t<16;t++)o.h[t]=u[t]^l(w,4*t);return e&&(g(o,e),o.c=128),o}function g(t,e){for(let n=0;n<e.length;n++)128===t.c&&(t.t+=t.c,h(t,!1),t.c=0),t.b[t.c++]=e[n]}function b(t){for(t.t+=t.c;t.c<128;)t.b[t.c++]=0;h(t,!0);const e=new Uint8Array(t.outlen);for(let n=0;n<t.outlen;n++)e[n]=t.h[n>>2]>>8*(3&n);return e}function A(t,e,n,r,o){n=n||64,t=i(t),r&&(r=i(r)),o&&(o=i(o));const c=p(n,e,r,o);return g(c,t),b(c)}for(let t=0;t<=255;++t)t.toString(16).padStart(2,"0");const U="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_",m=new Uint8Array(256);for(let t=0;t<U.length;t++)m[U.charCodeAt(t)]=t;function k(t,e=!1){let n,r,o,i,c,s=.75*t.length,l=t.length,a=0;const u=new Uint8Array(s);for(n=0;n<l;n+=4)r=m[t.charCodeAt(n)],o=m[t.charCodeAt(n+1)],i=m[t.charCodeAt(n+2)],c=m[t.charCodeAt(n+3)],u[a++]=r<<2|o>>4,u[a++]=(15&o)<<4|i>>2,u[a++]=(3&i)<<6|63&c;return e?u:(new TextDecoder).decode(u)}function x(t){let e,n=t.length,r="";for(e=0;e<n;e+=3)r+=U[t[e]>>2],r+=U[(3&t[e])<<4|t[e+1]>>4],r+=U[(15&t[e+1])<<2|t[e+2]>>6],r+=U[63&t[e+2]];return n%3==2?r.substring(0,r.length-1):n%3==1?r.substring(0,r.length-2):r}function v(t){S(Number.isSafeInteger(t),"Number too large for JavaScript to safely process");const e=t/4294967296|0,n=4294967295&t,r=new Uint8Array(8);return r[0]=255&n,r[1]=n>>>8&255,r[2]=n>>>16&255,r[3]=n>>>24&255,r[4]=255&e,r[5]=e>>>8&255,r[6]=e>>>16&255,r[7]=e>>>24&255,r}function I(t){return t[0]|t[1]<<8|t[2]<<16|t[3]<<24}function E(t,e){return I(t.slice(e,e+4))}function K(t,e,n){return n>=t.length?t:(t[n]=255&e,n+1>=t.length?t:(t[n+1]=e>>>8&255,n+2>=t.length?t:(t[n+2]=e>>>16&255,n+3>=t.length||(t[n+3]=e>>>24&255),t)))}function S(t,e="An unknown error occurred"){if(!t)throw new Error(e)}function N(...t){let e=v(t.length);for(let n of t){let t=j(n);S(t instanceof Uint8Array,"Only string and Uint8Array is allowed");let r=v(t.length);e=new Uint8Array([...e,...r,...t])}return e}function O(t=0){const e=new Uint8Array(t);if("undefined"!=typeof window){if(window.crypto&&window.crypto.getRandomValues)return window.crypto.getRandomValues(e),e;if("object"==typeof window.msCrypto&&"export function"==typeof window.msCrypto.getRandomValues)return window.msCrypto.getRandomValues(e),e}if(n.randomBytes){const r=n.randomBytes(t);return e.set(r,0),e}throw new Error("No secure random number generator available")}function j(t,e=!1){if(t instanceof Uint8Array)return t;if("string"==typeof t)return(new TextEncoder).encode(t);if(t instanceof Number&&e)return v(t);throw new Error("Unsupported type: "+typeof t)}function P(...t){let e=0;for(const n of t)n.length&&(e+=n.length);const n=new Uint8Array(e);let r=0;for(const e of t)n.set(e,r),r+=e.length;return n}function C(t,e){if(void 0===n.timingSafeEqual){if(S(t instanceof Uint8Array,"Must be Uint8Array"),S(e instanceof Uint8Array,"Must be Uint8Array"),t.length!==e.length)return!1;let n=0;for(let r=0;r<t.length;r++)n|=t[r]^e[r];return 0===n}return n.timingSafeEqual(j(t),j(e))}function T(t,e){return(t+e&4294967295)>>>0}function M(t,e){return((t&=4294967295)<<(e&=31)|t>>>32-e)>>>0}function J(t,e){return(4294967295&(t^e))>>>0}function V(t,e,n,r){return r=M(r^(t=t+e&4294967295),16),e=M(e^(n=n+r&4294967295),12),r=M(r^(t=t+e&4294967295),8),[t>>>0,(e=M(e^(n=n+r&4294967295),7))>>>0,n>>>0,r>>>0]}function _(t,e,n=0){return S(32===t.length,"Invalid key size"),S(12===e.length,"Invalid nonce length"),n=function(t){S(Number.isSafeInteger(t),"Number too large for JavaScript to safely process");const e=4294967295&t,n=new Uint8Array(4);return n[0]=255&e,n[1]=e>>>8&255,n[2]=e>>>16&255,n[3]=e>>>24&255,n}(n),new Uint8Array([101,120,112,97,110,100,32,51,50,45,98,121,116,101,32,107].concat([...t,...n,...e]))}function q(t,e,n,r){return S(32===n.length,`Key must be 32 bytes; ${n.length} provided`),S(12===e.length,"Nonce must be 12 bytes"),function(t,e){let n,r,o,i,c,s,l,a,u,f,y,d,h,w,p,g,b,A=E(t,0),U=E(t,4),m=E(t,8),k=E(t,12),x=E(t,16),v=E(t,20),S=E(t,24),N=E(t,28),O=E(t,32),j=E(t,36),P=E(t,40),C=E(t,44),M=E(t,48),_=E(t,52),q=E(t,56),D=E(t,60),F=0,R=e.length,z=new Uint8Array(R),B=new Uint8Array(64);for(;F<R;){b=F+64>=R?R:F+64,B.fill(0,0);let t=0;for(let n=F;n<b;n++)B[t++]=e[n];n=A,r=U,o=m,i=k,c=x,s=v,l=S,a=N,u=O,f=j,y=P,d=C,h=M,w=_,p=q,g=D;for(let t=0;t<10;t++)[n,c,u,h]=V(n,c,u,h),[r,s,f,w]=V(r,s,f,w),[o,l,y,p]=V(o,l,y,p),[i,a,d,g]=V(i,a,d,g),[n,s,y,g]=V(n,s,y,g),[r,l,d,h]=V(r,l,d,h),[o,a,u,w]=V(o,a,u,w),[i,c,f,p]=V(i,c,f,p);n=T(n,A),r=T(r,U),o=T(o,m),i=T(i,k),c=T(c,x),s=T(s,v),l=T(l,S),a=T(a,N),u=T(u,O),f=T(f,j),y=T(y,P),d=T(d,C),h=T(h,M),w=T(w,_),p=T(p,q),g=T(g,D),n=J(n,I(B.slice(0,4))),r=J(r,I(B.slice(4,8))),o=J(o,I(B.slice(8,12))),i=J(i,I(B.slice(12,16))),c=J(c,I(B.slice(16,20))),s=J(s,I(B.slice(20,24))),l=J(l,I(B.slice(24,28))),a=J(a,I(B.slice(28,32))),u=J(u,I(B.slice(32,36))),f=J(f,I(B.slice(36,40))),y=J(y,I(B.slice(40,44))),d=J(d,I(B.slice(44,48))),h=J(h,I(B.slice(48,52))),w=J(w,I(B.slice(52,56))),p=J(p,I(B.slice(56,60))),g=J(g,I(B.slice(60,64))),z=K(z,n,F),z=K(z,r,F+4),z=K(z,o,F+8),z=K(z,i,F+12),z=K(z,c,F+16),z=K(z,s,F+20),z=K(z,l,F+24),z=K(z,a,F+28),z=K(z,u,F+32),z=K(z,f,F+36),z=K(z,y,F+40),z=K(z,d,F+44),z=K(z,h,F+48),z=K(z,w,F+52),z=K(z,p,F+56),z=K(z,g,F+60),M++,F+=64}return z.slice(0,R)}(_(n,e,r),t)}function D(t,e){const n=function(t,e){return S(32===t.length,"Invalid key size"),S(16===e.length,"Invalid nonce length"),new Uint8Array([101,120,112,97,110,100,32,51,50,45,98,121,116,101,32,107].concat([...t,...e]))}(e,t);let r=E(n,0),o=E(n,4),i=E(n,8),c=E(n,12),s=E(n,16),l=E(n,20),a=E(n,24),u=E(n,28),f=E(n,32),y=E(n,36),d=E(n,40),h=E(n,44),w=E(n,48),p=E(n,52),g=E(n,56),b=E(n,60);for(let t=0;t<10;t++)[r,s,f,w]=V(r,s,f,w),[o,l,y,p]=V(o,l,y,p),[i,a,d,g]=V(i,a,d,g),[c,u,h,b]=V(c,u,h,b),[r,l,d,b]=V(r,l,d,b),[o,a,h,w]=V(o,a,h,w),[i,u,f,p]=V(i,u,f,p),[c,s,y,g]=V(c,s,y,g);const A=new Uint8Array(32);return K(A,r,0),K(A,o,4),K(A,i,8),K(A,c,12),K(A,w,16),K(A,p,20),K(A,g,24),K(A,b,28),A}function F(t,e,n,r=1){S(32===n.length,`Key must be 32 bytes; ${n.length} provided`),S(24===e.length,"Nonce must be 24 bytes");const o=new Uint8Array(12);return o.set(e.slice(16,24),4),q(t,o,D(e.slice(0,16),n),r)}const R="v4.local.",z=new TextEncoder,B=z.encode(R),L=z.encode("paseto-encryption-key"),$=z.encode("paseto-auth-key-for-aead");class G{constructor(t){S(t instanceof Uint8Array,"Input must be a Uint8Array"),S(32===t.length,"Key must be 32 bytes"),this.bytes=t}static generate(){const t=O(32);return new G(t)}async decode(t,e=""){return JSON.parse(await this.decrypt(t,e))}async encode(t,e="",n=""){return"object"==typeof e&&(e=JSON.stringify(e)),"string"==typeof e&&(e=j(e)),this.encrypt(JSON.stringify(t),e,n)}async assertFooter(t,e){const n=t.split(".");S(4===n.length,"No footer provided");return C(k(n[3],e instanceof Uint8Array),e)}static getFooter(t,e=!1){const n=t.split(".");S(4===n.length,"No footer provided");const r=k(n[3],e);return e?JSON.parse(function(t){if("string"==typeof t)return t;if(t instanceof Uint8Array)return(new TextDecoder).decode(t);throw new Error("Unsupported type: "+typeof t)}(r)):r}getKey(){return this.bytes}async encrypt(t,e="",n=""){const r=O(32);let o;o=p(56,this.bytes),g(o,L),g(o,r);const i=b(o),c=i.slice(0,32),s=i.slice(32);o=p(32,this.bytes),g(o,$),g(o,r);const l=b(o),a=await F(j(t),s,c,0);o=p(32,l),g(o,N(B,r,a,e,n));const u=x(P(r,a,b(o)));return e.length>0?[R.slice(0,8),u,x(e)].join("."):[R.slice(0,8),u].join(".")}async decrypt(t,e=""){const{n:n,c:r,t:o,footer:i}=await this.decompose(t);let c;c=p(56,this.bytes),g(c,L),g(c,n);const s=b(c),l=s.slice(0,32),a=s.slice(32);c=p(32,this.bytes),g(c,$),g(c,n);c=p(32,b(c)),g(c,N(B,n,r,i,e));S(C(o,b(c)),"Invalid tag");const u=await F(r,a,l,0);return(new TextDecoder).decode(u)}async decompose(t){S(C(j(t.slice(0,9)),B),"Invalid token");const e=t.split("."),n=k(e[2],!0),r=n.length;return{n:n.slice(0,32),c:n.slice(32,r-32),t:n.slice(r-32),footer:e.length>3?k(e[3]):new Uint8Array(0)}}}"undefined"!=typeof window&&(window.PasetoV4Local=G);const H=function(t){let e,n=new Float64Array(16);if(t)for(e=0;e<t.length;e++)n[e]=t[e];return n};let Q=H(),W=H([1]),X=H([30883,4953,19914,30187,55467,16705,2637,112,59544,30585,16505,36039,65139,11119,27886,20995]),Y=H([41136,18958,6951,50414,58488,44335,6150,12099,55207,15867,153,11085,57099,20417,9344,11139]);function Z(t){let e,n;for(n=0;n<16;n++)t[n]+=65536,e=Math.floor(t[n]/65536),t[(n+1)*(n<15?1:0)]+=e-1+37*(e-1)*(15===n?1:0),t[n]-=65536*e}function tt(t,e,n){let r,o=~(n-1);for(let n=0;n<16;n++)r=o&(t[n]^e[n]),t[n]^=r,e[n]^=r}function et(t,e,n){let r;for(r=0;r<16;r++)t[r]=e[r]+n[r]|0}function nt(t,e,n){let r;for(r=0;r<16;r++)t[r]=e[r]-n[r]|0}function rt(t,e,n){let r,o,i=new Float64Array(31);for(r=0;r<31;r++)i[r]=0;for(r=0;r<16;r++)for(o=0;o<16;o++)i[r+o]+=e[r]*n[o];for(r=0;r<15;r++)i[r]+=38*i[r+16];for(r=0;r<16;r++)t[r]=i[r];Z(t),Z(t)}function ot(t,e){rt(t,e,e)}function it(t,e){let n,r,o,i=H(),c=H();for(n=0;n<16;n++)c[n]=e[n];for(Z(c),Z(c),Z(c),r=0;r<2;r++){for(i[0]=c[0]-65517,n=1;n<15;n++)i[n]=c[n]-65535-(i[n-1]>>16&1),i[n-1]&=65535;i[15]=c[15]-32767-(i[14]>>16&1),o=i[15]>>16&1,i[14]&=65535,tt(c,i,1-o)}for(n=0;n<16;n++)t[2*n]=255&c[n],t[2*n+1]=c[n]>>8}function ct(t,e){let n=new Uint8Array(32),r=new Uint8Array(32);return it(n,t),it(r,e),function(t,e,n,r,o){let i,c=0;for(i=0;i<o;i++)c|=t[e+i]^n[r+i];return(1&c-1>>>8)-1}(n,0,r,0,32)}function st(t,e){let n=H(),r=H(),o=H(),i=H(),c=H(),s=H(),l=H();return function(t,e){let n;for(n=0;n<16;n++)t[n]=0|e[n]}(t[2],W),function(t,e){let n;for(n=0;n<16;n++)t[n]=e[2*n]+(e[2*n+1]<<8);t[15]&=32767}(t[1],e),ot(o,t[1]),rt(i,o,X),nt(o,o,t[2]),et(i,t[2],i),ot(c,i),ot(s,c),rt(l,s,c),rt(n,l,o),rt(n,n,i),function(t,e){let n,r=H();for(n=0;n<16;n++)r[n]=e[n];for(n=250;n>=0;n--)ot(r,r),1!==n&&rt(r,r,e);for(n=0;n<16;n++)t[n]=r[n]}(n,n),rt(n,n,o),rt(n,n,i),rt(n,n,i),rt(t[0],n,i),ot(r,t[0]),rt(r,r,i),ct(r,o)&&rt(t[0],t[0],Y),ot(r,t[0]),rt(r,r,i),ct(r,o)?-1:(function(t){let e=new Uint8Array(32);return it(e,t),1&e[0]}(t[0])===e[31]>>7&&nt(t[0],Q,t[0]),rt(t[3],t[0],t[1]),0)}function lt(t){let e=new Uint8Array(32),n=[H(),H(),H(),H()],r=H(),o=H();if(st(n,t))return null;let i=n[1];return et(r,W,i),nt(o,W,i),function(t,e){let n,r=H();for(n=0;n<16;n++)r[n]=e[n];for(n=253;n>=0;n--)ot(r,r),2!==n&&4!==n&&rt(r,r,e);for(n=0;n<16;n++)t[n]=r[n]}(o,o),rt(r,r,o),it(e,r),e}const at="k4.seal.",ut=(new TextEncoder).encode(at),ft=new Uint8Array([1]),yt=new Uint8Array([2]);class dt{constructor(t,e=null){S(t instanceof Uint8Array,"Input must be a Uint8Array"),S(32===t.length,"Public Key must be 32 bytes"),this.xpk=t,e?(S(e instanceof Uint8Array,"Input must be a Uint8Array"),S(32===e.length,"Secret Key must be 64 bytes"),this.xsk=e):this.xsk=null}static fromV4Public(t){return dt.fromEdwardsKeys(t.pk,t.sk)}static fromEdwardsKeys(t,e=null){S(t instanceof Uint8Array,"Input must be a Uint8Array"),S(32===t.length,"Public Key must be 32 bytes");const n=lt(t);return e?(S(e instanceof Uint8Array,"Input must be a Uint8Array"),S(64===e.length,"Secret Key must be 64 bytes"),new dt(n,function(t){let e,n=new Uint8Array(64),r=new Uint8Array(32);for(o.default.lowlevel.crypto_hash(n,t,32),n[0]&=248,n[31]&=127,n[31]|=64,e=0;e<32;e++)r[e]=n[e];for(e=0;e<64;e++)n[e]=0;return r}(e))):new dt(n,null)}static generate(){const t=o.default.sign.keyPair();return dt.fromEdwardsKeys(t.publicKey,t.secretKey)}async wrap(t){const e=o.default.box.keyPair(),n=e.publicKey.slice(),r=o.default.scalarMult(e.secretKey,this.xpk),i=A(P(ft,ut,r,n,this.xpk),null,32),c=A(P(yt,ut,r,n,this.xpk),null,32),s=A(P(n,this.xpk),null,24),l=F(t.getKey(),s,i,0),a=A(P(ut,n,l),c,32);return at+x(P(a,n,l))}async unwrap(t){S(this.xsk,"Cannot unwrap: No secret key was provided");const{tag:e,epk:n,edk:r}=await this.decompose(t),i=o.default.scalarMult(this.xsk,n),c=A(P(yt,ut,i,n,this.xpk),null,32);S(C(e,A(P(ut,n,r),c,32)),"Invalid auth tag");const s=A(P(n,this.xpk),null,24),l=A(P(ft,ut,i,n,this.xpk),null,32);return new G(F(r,s,l,0))}async decompose(t){S(C(j(t.slice(0,8)),ut),"Invalid token");const e=t.split(".");S(3===e.length,"Invalid token");const n=k(e[2],!0);return S(96===n.length,"Invalid payload length"),{tag:n.slice(0,32),epk:n.slice(32,64),edk:n.slice(64)}}}"undefined"!=typeof window&&(window.PaserkK4Seal=dt),t.PaserkK4Seal=dt,Object.defineProperty(t,"__esModule",{value:!0})}));//# sourceMappingURL=paserk.k4.seal.js.map