├── static ├── style.css └── js │ ├── secrets.min.js │ └── qrcode.min.js ├── README.md ├── index.html ├── update.html └── generate.html /static/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | } 4 | 5 | html,body { 6 | font-family: sans-serif; 7 | line-height: 1.2rem; 8 | } 9 | 10 | h1 { 11 | color: green; 12 | margin-left: .5rem; 13 | } 14 | 15 | input[type="button"] { 16 | font-size: 5em; 17 | font-weight: bold; 18 | } 19 | 20 | .textarea > label { 21 | display: block; 22 | } 23 | 24 | .box { 25 | box-shadow: -1px 2px 5px gray; 26 | padding: .2rem .5rem; 27 | margin-bottom: 2rem; 28 | max-width: 800px; 29 | } 30 | 31 | .box .row { 32 | margin: 0.45em 0; 33 | } 34 | 35 | .ciphertext { 36 | font-size: 1.2em; 37 | margin-bottom: 1em; 38 | } 39 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Pass share 2 | 3 | This tool is for setting up a way for others (family or those you mostly trust) to recover a master passphrase in the event you aren't able to due to death or illness. It's designed with 1password's master passphrase in mind 4 | 5 | This is obviously a fairly tricky thing to do, and involves a few compromises. 6 | 7 | Check out the [Generator](https://lox.github.io/pass-share/generate.html) to get a sense of how it works. 8 | 9 | ## Approach 10 | 11 | * Passphrase is encrypted with a randomly generated key and IV. 12 | * The intermediate ciphertext and IV are printed out and stored somewhere physical that your loved ones could access. The fact that this portion is offline provides a "something you have" vs the keys later which are "something you know". This prevents brute force attacks with out physical access. It also means you can update your encrypted passphrase without re-distributing shares. 13 | * The intermediate key is split into shares using [Shamir's threshold secret sharing scheme](http://en.wikipedia.org/wiki/Shamir's_Secret_Sharing) using a customizable threshold and number of shares. 14 | * The shares are distibuted as makes sense to people you trust. You might choose a consensus of 2 and distribute it to 3 people, such that no one person could act alone. In my case I'm going with 4 shares and a consensus of 2. My wife gets 2 shares, and I give a backup share to two family members. This means that even if both my wife and I go, the backups can still combine their shares to meet the threshold. 15 | 16 | ## Updating 17 | 18 | Provided you keep track of intermediate key that is distributed in shares, you can update the passphrase so that you can actually update your Master Passphrase over time. 19 | 20 | See https://lox.github.io/pass-share/update.html. 21 | 22 | ## Recovery 23 | 24 | When the shares are distributed, they come with instructions along the lines of: 25 | 26 | > This is a piece of a secret code, that when combined with X others can be used to recover Lachlan's 1password Master Password in the event something has happened to him. 27 | > 28 | > Your code is: `801203c28043c4576a7fd43530cd66f4898a7b4e704833a32dadf13a83bbda343705d3fb5b1970d1160e33cc1ca01c3fd75` 29 | > 30 | > You need to get in touch with at least X other people on this list: 31 | > 32 | > * Person 1 33 | > * Person 2 34 | > * Person 3 35 | > 36 | > You will also need the recovery kit that is located in his desk at his primary residence. 37 | > 38 | > When you have enough secret code pieces and the recovery kit, visit this page: 39 | > 40 | > https://lox.github.io/pass-share/ 41 | > 42 | > Enter your code pieces, and the encrypted passphrase from the paper you got from the desk. Press "recover". 43 | > 44 | > At this stage you have the passphrase and you can access Lachlan's 1password vault. 45 | > 46 | > Good luck! 47 | 48 | 49 | ## Risks 50 | 51 | * Sarah is like "What?" 52 | * Nobody cares about my passwords 53 | * WebCrypto API breaks in future 54 | * Web page is inaccessible (Github pages) 55 | * Can't access encrypted passphrase at residence 56 | * Family conspires against me 🤷🏼‍♂️ 57 | 58 | ## Todo 59 | 60 | * [ ] Less horrible design, with better words 61 | * [ ] Decide whether passphrase should be padded before intermediate encryption. 62 | * [ ] PDF Generator? 63 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Recover Passphrase 6 | 7 | 8 | 9 | 10 |
11 |

Recover Passphrase

12 |
13 |
14 | 15 | 16 |
17 |
18 | 19 | 20 |
21 | 22 |
23 |
24 |
25 |
26 | 27 | 106 | 107 | -------------------------------------------------------------------------------- /update.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Update Encrypted Passphrase 6 | 7 | 8 | 9 | 10 |
11 |

Update Encrypted Passphrase

12 |
13 |
14 | 15 | 16 |
17 |
18 | 19 | 20 |
21 |
22 | 23 | 24 |
25 | 26 |
27 |
28 |
29 |
30 |
31 |
32 | 33 | 139 | 140 | -------------------------------------------------------------------------------- /generate.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Generate Passphrase Shares 6 | 7 | 8 | 9 | 10 | 11 |
12 |

Generate Passphrase Shares

13 |
14 |
15 | 16 | 17 |
18 |
19 | 20 | 21 |
22 |
23 | 24 | 25 |
26 |
27 | 28 | 29 |
30 | 31 |
32 |
33 |
34 |
35 |
36 |
37 | 38 | 175 | 176 | -------------------------------------------------------------------------------- /static/js/secrets.min.js: -------------------------------------------------------------------------------- 1 | /*! secrets.js-grempe 2015-03-02 */ 2 | // @preserve author Alexander Stetsyuk 3 | // @preserve author Glenn Rempe 4 | // @license MIT 5 | !function(a,b){"use strict";"function"==typeof define&&define.amd?define([],function(){return a.secrets=b()}):"object"==typeof exports?module.exports=b(require("crypto")):a.secrets=b(a.crypto)}(this,function(a){"use strict";function b(){p={bits:8,radix:16,minBits:3,maxBits:20,bytesPerChar:2,maxBytesPerChar:6,primitivePolynomials:[null,null,1,3,3,5,3,3,29,17,9,5,83,27,43,3,45,9,39,39,9,5,3,33,27,9,71,39,9,5,83]},q={},r=new Array(1024).join("0"),s=!0,t=10,u=["nodeCryptoRandomBytes","browserCryptoGetRandomValues","browserSJCLRandom","testRandom"]}function c(){return q&&q.rng&&"function"==typeof q.rng?!0:!1}function d(a,b){var c;if(0===b||1===b)return a;if(b&&b>1024)throw new Error("Padding must be multiples of no larger than 1024 bits.");return b=b||q.bits,a&&(c=a.length%b),c?(r+a).slice(-(b-c+a.length)):a}function e(a){var b,c,e="";for(c=a.length-1;c>=0;c--){if(b=parseInt(a[c],16),isNaN(b))throw new Error("Invalid hex character.");e=d(b.toString(2),4)+e}return e}function f(a){var b,c,e="";for(a=d(a,4),c=a.length;c>=4;c-=4){if(b=parseInt(a.slice(c-4,c),2),isNaN(b))throw new Error("Invalid binary character.");e=b.toString(16)+e}return e}function g(){return!a||"object"!=typeof a||"function"!=typeof a.getRandomValues&&"object"!=typeof a.getRandomValues||"function"!=typeof Uint32Array&&"object"!=typeof Uint32Array?!1:!0}function h(){return"object"==typeof a&&"function"==typeof a.randomBytes?!0:!1}function i(){return"object"==typeof sjcl&&"object"==typeof sjcl.random?!0:!1}function j(b){function c(a,b,c,e){var f,g,h=0,i="";for(b&&(f=b.length-1);f>h||i.lengthq.bits;c-=q.bits)e.push(parseInt(a.slice(c-q.bits,c),2));return e.push(parseInt(a.slice(0,c),2)),e}function l(a,b){var c,d=q.logs[a],e=0;for(c=b.length-1;c>=0;c--)e=0!==e?q.exps[(d+q.logs[e])%q.maxShares]^b[c]:b[c];return e}function m(a,b,c){var d,e,f,g,h=0;for(f=0,d=b.length;d>f;f++)if(c[f]){for(e=q.logs[c[f]],g=0;d>g;g++)if(f!==g){if(a===b[g]){e=-1;break}e=(e+q.logs[a^b[g]]-q.logs[b[f]^b[g]]+q.maxShares)%q.maxShares}h=-1===e?h:h^q.exps[e]}return h}function n(a,b,c){var d,e,f=[],g=[a];for(d=1;c>d;d++)g[d]=parseInt(q.rng(q.bits),2);for(d=1,e=b+1;e>d;d++)f[d-1]={x:d,y:l(d,g)};return f}function o(a,b,c){var e,f,g,h,i;if(b=parseInt(b,q.radix),a=parseInt(a,10)||q.bits,e=a.toString(36).toUpperCase(),g=Math.pow(2,a)-1,h=g.toString(q.radix).length,f=d(b.toString(q.radix),h),"number"!=typeof b||b%1!==0||1>b||b>g)throw new Error("Share id must be an integer between 1 and "+g+", inclusive.");return i=e+f+c}var p,q,r,s,t,u,v={init:function(a,d){var e,f,h=[],j=[],k=1;if(b(),a&&("number"!=typeof a||a%1!==0||ap.maxBits))throw new Error("Number of bits must be an integer between "+p.minBits+" and "+p.maxBits+", inclusive.");if(d&&-1===u.indexOf(d))throw new Error("Invalid RNG type argument : '"+d+"'");for(q.radix=p.radix,q.bits=a||p.bits,q.size=Math.pow(2,q.bits),q.maxShares=q.size-1,e=p.primitivePolynomials[q.bits],f=0;f=q.size&&(k^=e,k&=q.maxShares);if(q.logs=h,q.exps=j,d&&this.setRNG(d),c()||this.setRNG(),i()&&"browserSJCLRandom"===q.typeCSPRNG&&(sjcl.random=new sjcl.prng(t),g()&&sjcl.random.startCollectors(),this.seedRNG()),!(c()&&q.bits&&q.size&&q.maxShares&&q.logs&&q.exps&&q.logs.length===q.size&&q.exps.length===q.size))throw new Error("Initialization failed.")},seedRNG:function(b,c,d){var e,f;c=parseInt(c,10),d=d||"seedRNG",i()&&g()&&(e=new Uint32Array(256),f=a.getRandomValues(e),sjcl.random.addEntropy(f,2048,"cryptoGetRandomValues")),i()&&h()&&a.randomBytes(256,function(a,b){if(a)throw a;sjcl.random.addEntropy(b.toString("hex"),2048,"cryptoRandomBytes")}),i()&&b&&c&&d&&"browserSJCLRandom"===q.typeCSPRNG&&sjcl.random.addEntropy(b,c,d)},combine:function(a,b){var c,g,h,i,j,l,n,o="",p=[],r=[];for(b=b||0,c=0,h=a.length;h>c;c++){if(l=this.extractShareComponents(a[c]),void 0===j)j=l.bits;else if(l.bits!==j)throw new Error("Mismatched shares: Different bit settings.");if(q.bits!==j&&this.init(j),-1===p.indexOf(l.id))for(p.push(l.id),n=k(e(l.data)),g=0,i=n.length;i>g;g++)r[g]=r[g]||[],r[g][p.length-1]=n[g]}for(c=0,h=r.length;h>c;c++)o=d(m(b,p,r[c]).toString(2))+o;return f(b>=1?o:o.slice(o.indexOf("1")+1))},getConfig:function(){var a={};return a.radix=q.radix,a.bits=q.bits,a.maxShares=q.maxShares,a.hasCSPRNG=c(),a.typeCSPRNG=q.typeCSPRNG,a},extractShareComponents:function(a){var b,c,d,e,f,g,h={};if(b=parseInt(a.substr(0,1),36),b&&("number"!=typeof b||b%1!==0||bp.maxBits))throw new Error("Invalid share : Number of bits must be an integer between "+p.minBits+" and "+p.maxBits+", inclusive.");if(e=Math.pow(2,b)-1,d=(Math.pow(2,b)-1).toString(q.radix).length,f="^([a-kA-K3-9]{1})([a-fA-F0-9]{"+d+"})([a-fA-F0-9]+)$",g=new RegExp(f).exec(a),g&&(c=parseInt(g[2],q.radix)),"number"!=typeof c||c%1!==0||1>c||c>e)throw new Error("Invalid share : Share id must be an integer between 1 and "+q.maxShares+", inclusive.");if(g&&g[3])return h.bits=b,h.id=c,h.data=g[3],h;throw new Error("The share data provided is invalid : "+a)},setRNG:function(a){var b="Random number generator is invalid ",c=" Supply an CSPRNG of the form function(bits){} that returns a string containing 'bits' number of random 1's and 0's.";if(a&&"string"==typeof a&&-1===u.indexOf(a))throw new Error("Invalid RNG type argument : '"+a+"'");if(a||(a=j()),a&&"string"==typeof a&&(a=j(a)),s){if(a&&"function"!=typeof a)throw new Error(b+"(Not a function)."+c);if(a&&"string"!=typeof a(q.bits))throw new Error(b+"(Output is not a string)."+c);if(a&&!parseInt(a(q.bits),2))throw new Error(b+"(Binary string output not parseable to an Integer)."+c);if(a&&a(q.bits).length>q.bits)throw new Error(b+"(Output length is greater than config.bits)."+c);if(a&&a(q.bits).lengthb||b>p.maxBytesPerChar||b%1!==0)throw new Error("Bytes per character must be an integer between 1 and "+p.maxBytesPerChar+", inclusive.");for(c=2*b,e=Math.pow(16,c)-1,h=0,i=a.length;i>h;h++){if(g=a[h].charCodeAt(),isNaN(g))throw new Error("Invalid character: "+a[h]);if(g>e)throw f=Math.ceil(Math.log(g+1)/Math.log(256)),new Error("Invalid character code ("+g+"). Maximum allowable is 256^bytes-1 ("+e+"). To convert this character, use at least "+f+" bytes.");j=d(g.toString(16),c)+j}return j},hex2str:function(a,b){var c,e,f,g="";if("string"!=typeof a)throw new Error("Input must be a hexadecimal string.");if(b=b||p.bytesPerChar,"number"!=typeof b||b%1!==0||1>b||b>p.maxBytesPerChar)throw new Error("Bytes per character must be an integer between 1 and "+p.maxBytesPerChar+", inclusive.");for(c=2*b,a=d(a,c),e=0,f=a.length;f>e;e+=c)g=String.fromCharCode(parseInt(a.slice(e,e+c),16))+g;return g},random:function(a){if("number"!=typeof a||a%1!==0||2>a||a>65536)throw new Error("Number of bits must be an Integer between 1 and 65536.");if("browserSJCLRandom"===q.typeCSPRNG&&sjcl.random.isReady(t)<1)throw new Error("SJCL isn't finished seeding the RNG yet. Needs new entropy added or more mouse movement.");return f(q.rng(a))},share:function(a,b,c,g){var h,i,j,l,m,p=new Array(b),r=new Array(b);if(g=g||128,"string"!=typeof a)throw new Error("Secret must be a string.");if("number"!=typeof b||b%1!==0||2>b)throw new Error("Number of shares must be an integer between 2 and 2^bits-1 ("+q.maxShares+"), inclusive.");if(b>q.maxShares)throw h=Math.ceil(Math.log(b+1)/Math.LN2),new Error("Number of shares must be an integer between 2 and 2^bits-1 ("+q.maxShares+"), inclusive. To create "+b+" shares, use at least "+h+" bits.");if("number"!=typeof c||c%1!==0||2>c)throw new Error("Threshold number of shares must be an integer between 2 and 2^bits-1 ("+q.maxShares+"), inclusive.");if(c>q.maxShares)throw h=Math.ceil(Math.log(c+1)/Math.LN2),new Error("Threshold number of shares must be an integer between 2 and 2^bits-1 ("+q.maxShares+"), inclusive. To use a threshold of "+c+", use at least "+h+" bits.");if(c>b)throw new Error("Threshold number of shares was "+c+" but must be less than or equal to the "+b+" shares specified as the total to generate.");if("number"!=typeof g||g%1!==0||0>g||g>1024)throw new Error("Zero-pad length must be an integer between 0 and 1024 inclusive.");for(a="1"+e(a),a=k(a,g),j=0,m=a.length;m>j;j++)for(i=n(a[j],b,c),l=0;b>l;l++)p[l]=p[l]||i[l].x.toString(q.radix),r[l]=d(i[l].y.toString(2))+(r[l]||"");for(j=0;b>j;j++)p[j]=o(q.bits,p[j],f(r[j]));return p},newShare:function(a,b){var c;if(a&&"string"==typeof a&&(a=parseInt(a,q.radix)),a&&b&&b[0])return c=this.extractShareComponents(b[0]),o(c.bits,a,this.combine(b,a));throw new Error("Invalid 'id' or 'shares' Array argument to newShare().")},_reset:b,_padLeft:d,_hex2bin:e,_bin2hex:f,_hasCryptoGetRandomValues:g,_hasCryptoRandomBytes:h,_hasSJCL:i,_getRNG:j,_isSetRNG:c,_splitNumStringToIntArray:k,_horner:l,_lagrange:m,_getShares:n,_constructPublicShareString:o};return v.init(),v}); -------------------------------------------------------------------------------- /static/js/qrcode.min.js: -------------------------------------------------------------------------------- 1 | var QRCode;!function(){function a(a){this.mode=c.MODE_8BIT_BYTE,this.data=a,this.parsedData=[];for(var b=[],d=0,e=this.data.length;e>d;d++){var f=this.data.charCodeAt(d);f>65536?(b[0]=240|(1835008&f)>>>18,b[1]=128|(258048&f)>>>12,b[2]=128|(4032&f)>>>6,b[3]=128|63&f):f>2048?(b[0]=224|(61440&f)>>>12,b[1]=128|(4032&f)>>>6,b[2]=128|63&f):f>128?(b[0]=192|(1984&f)>>>6,b[1]=128|63&f):b[0]=f,this.parsedData=this.parsedData.concat(b)}this.parsedData.length!=this.data.length&&(this.parsedData.unshift(191),this.parsedData.unshift(187),this.parsedData.unshift(239))}function b(a,b){this.typeNumber=a,this.errorCorrectLevel=b,this.modules=null,this.moduleCount=0,this.dataCache=null,this.dataList=[]}function i(a,b){if(void 0==a.length)throw new Error(a.length+"/"+b);for(var c=0;c=f;f++){var h=0;switch(b){case d.L:h=l[f][0];break;case d.M:h=l[f][1];break;case d.Q:h=l[f][2];break;case d.H:h=l[f][3]}if(h>=e)break;c++}if(c>l.length)throw new Error("Too long data");return c}function s(a){var b=encodeURI(a).toString().replace(/\%[0-9a-fA-F]{2}/g,"a");return b.length+(b.length!=a?3:0)}a.prototype={getLength:function(){return this.parsedData.length},write:function(a){for(var b=0,c=this.parsedData.length;c>b;b++)a.put(this.parsedData[b],8)}},b.prototype={addData:function(b){var c=new a(b);this.dataList.push(c),this.dataCache=null},isDark:function(a,b){if(0>a||this.moduleCount<=a||0>b||this.moduleCount<=b)throw new Error(a+","+b);return this.modules[a][b]},getModuleCount:function(){return this.moduleCount},make:function(){this.makeImpl(!1,this.getBestMaskPattern())},makeImpl:function(a,c){this.moduleCount=4*this.typeNumber+17,this.modules=new Array(this.moduleCount);for(var d=0;d=7&&this.setupTypeNumber(a),null==this.dataCache&&(this.dataCache=b.createData(this.typeNumber,this.errorCorrectLevel,this.dataList)),this.mapData(this.dataCache,c)},setupPositionProbePattern:function(a,b){for(var c=-1;7>=c;c++)if(!(-1>=a+c||this.moduleCount<=a+c))for(var d=-1;7>=d;d++)-1>=b+d||this.moduleCount<=b+d||(this.modules[a+c][b+d]=c>=0&&6>=c&&(0==d||6==d)||d>=0&&6>=d&&(0==c||6==c)||c>=2&&4>=c&&d>=2&&4>=d?!0:!1)},getBestMaskPattern:function(){for(var a=0,b=0,c=0;8>c;c++){this.makeImpl(!0,c);var d=f.getLostPoint(this);(0==c||a>d)&&(a=d,b=c)}return b},createMovieClip:function(a,b,c){var d=a.createEmptyMovieClip(b,c),e=1;this.make();for(var f=0;f=g;g++)for(var h=-2;2>=h;h++)this.modules[d+g][e+h]=-2==g||2==g||-2==h||2==h||0==g&&0==h?!0:!1}},setupTypeNumber:function(a){for(var b=f.getBCHTypeNumber(this.typeNumber),c=0;18>c;c++){var d=!a&&1==(1&b>>c);this.modules[Math.floor(c/3)][c%3+this.moduleCount-8-3]=d}for(var c=0;18>c;c++){var d=!a&&1==(1&b>>c);this.modules[c%3+this.moduleCount-8-3][Math.floor(c/3)]=d}},setupTypeInfo:function(a,b){for(var c=this.errorCorrectLevel<<3|b,d=f.getBCHTypeInfo(c),e=0;15>e;e++){var g=!a&&1==(1&d>>e);6>e?this.modules[e][8]=g:8>e?this.modules[e+1][8]=g:this.modules[this.moduleCount-15+e][8]=g}for(var e=0;15>e;e++){var g=!a&&1==(1&d>>e);8>e?this.modules[8][this.moduleCount-e-1]=g:9>e?this.modules[8][15-e-1+1]=g:this.modules[8][15-e-1]=g}this.modules[this.moduleCount-8][8]=!a},mapData:function(a,b){for(var c=-1,d=this.moduleCount-1,e=7,g=0,h=this.moduleCount-1;h>0;h-=2)for(6==h&&h--;;){for(var i=0;2>i;i++)if(null==this.modules[d][h-i]){var j=!1;g>>e));var k=f.getMask(b,d,h-i);k&&(j=!j),this.modules[d][h-i]=j,e--,-1==e&&(g++,e=7)}if(d+=c,0>d||this.moduleCount<=d){d-=c,c=-c;break}}}},b.PAD0=236,b.PAD1=17,b.createData=function(a,c,d){for(var e=j.getRSBlocks(a,c),g=new k,h=0;h8*l)throw new Error("code length overflow. ("+g.getLengthInBits()+">"+8*l+")");for(g.getLengthInBits()+4<=8*l&&g.put(0,4);0!=g.getLengthInBits()%8;)g.putBit(!1);for(;;){if(g.getLengthInBits()>=8*l)break;if(g.put(b.PAD0,8),g.getLengthInBits()>=8*l)break;g.put(b.PAD1,8)}return b.createBytes(g,e)},b.createBytes=function(a,b){for(var c=0,d=0,e=0,g=new Array(b.length),h=new Array(b.length),j=0;j=0?p.get(q):0}}for(var r=0,m=0;mm;m++)for(var j=0;jm;m++)for(var j=0;j=0;)b^=f.G15<=0;)b^=f.G18<>>=1;return b},getPatternPosition:function(a){return f.PATTERN_POSITION_TABLE[a-1]},getMask:function(a,b,c){switch(a){case e.PATTERN000:return 0==(b+c)%2;case e.PATTERN001:return 0==b%2;case e.PATTERN010:return 0==c%3;case e.PATTERN011:return 0==(b+c)%3;case e.PATTERN100:return 0==(Math.floor(b/2)+Math.floor(c/3))%2;case e.PATTERN101:return 0==b*c%2+b*c%3;case e.PATTERN110:return 0==(b*c%2+b*c%3)%2;case e.PATTERN111:return 0==(b*c%3+(b+c)%2)%2;default:throw new Error("bad maskPattern:"+a)}},getErrorCorrectPolynomial:function(a){for(var b=new i([1],0),c=0;a>c;c++)b=b.multiply(new i([1,g.gexp(c)],0));return b},getLengthInBits:function(a,b){if(b>=1&&10>b)switch(a){case c.MODE_NUMBER:return 10;case c.MODE_ALPHA_NUM:return 9;case c.MODE_8BIT_BYTE:return 8;case c.MODE_KANJI:return 8;default:throw new Error("mode:"+a)}else if(27>b)switch(a){case c.MODE_NUMBER:return 12;case c.MODE_ALPHA_NUM:return 11;case c.MODE_8BIT_BYTE:return 16;case c.MODE_KANJI:return 10;default:throw new Error("mode:"+a)}else{if(!(41>b))throw new Error("type:"+b);switch(a){case c.MODE_NUMBER:return 14;case c.MODE_ALPHA_NUM:return 13;case c.MODE_8BIT_BYTE:return 16;case c.MODE_KANJI:return 12;default:throw new Error("mode:"+a)}}},getLostPoint:function(a){for(var b=a.getModuleCount(),c=0,d=0;b>d;d++)for(var e=0;b>e;e++){for(var f=0,g=a.isDark(d,e),h=-1;1>=h;h++)if(!(0>d+h||d+h>=b))for(var i=-1;1>=i;i++)0>e+i||e+i>=b||(0!=h||0!=i)&&g==a.isDark(d+h,e+i)&&f++;f>5&&(c+=3+f-5)}for(var d=0;b-1>d;d++)for(var e=0;b-1>e;e++){var j=0;a.isDark(d,e)&&j++,a.isDark(d+1,e)&&j++,a.isDark(d,e+1)&&j++,a.isDark(d+1,e+1)&&j++,(0==j||4==j)&&(c+=3)}for(var d=0;b>d;d++)for(var e=0;b-6>e;e++)a.isDark(d,e)&&!a.isDark(d,e+1)&&a.isDark(d,e+2)&&a.isDark(d,e+3)&&a.isDark(d,e+4)&&!a.isDark(d,e+5)&&a.isDark(d,e+6)&&(c+=40);for(var e=0;b>e;e++)for(var d=0;b-6>d;d++)a.isDark(d,e)&&!a.isDark(d+1,e)&&a.isDark(d+2,e)&&a.isDark(d+3,e)&&a.isDark(d+4,e)&&!a.isDark(d+5,e)&&a.isDark(d+6,e)&&(c+=40);for(var k=0,e=0;b>e;e++)for(var d=0;b>d;d++)a.isDark(d,e)&&k++;var l=Math.abs(100*k/b/b-50)/5;return c+=10*l}},g={glog:function(a){if(1>a)throw new Error("glog("+a+")");return g.LOG_TABLE[a]},gexp:function(a){for(;0>a;)a+=255;for(;a>=256;)a-=255;return g.EXP_TABLE[a]},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)},h=0;8>h;h++)g.EXP_TABLE[h]=1<h;h++)g.EXP_TABLE[h]=g.EXP_TABLE[h-4]^g.EXP_TABLE[h-5]^g.EXP_TABLE[h-6]^g.EXP_TABLE[h-8];for(var h=0;255>h;h++)g.LOG_TABLE[g.EXP_TABLE[h]]=h;i.prototype={get:function(a){return this.num[a]},getLength:function(){return this.num.length},multiply:function(a){for(var b=new Array(this.getLength()+a.getLength()-1),c=0;cf;f++)for(var g=c[3*f+0],h=c[3*f+1],i=c[3*f+2],k=0;g>k;k++)e.push(new j(h,i));return e},j.getRsBlockTable=function(a,b){switch(b){case d.L:return j.RS_BLOCK_TABLE[4*(a-1)+0];case d.M:return j.RS_BLOCK_TABLE[4*(a-1)+1];case d.Q:return j.RS_BLOCK_TABLE[4*(a-1)+2];case d.H:return j.RS_BLOCK_TABLE[4*(a-1)+3];default:return void 0}},k.prototype={get:function(a){var b=Math.floor(a/8);return 1==(1&this.buffer[b]>>>7-a%8)},put:function(a,b){for(var c=0;b>c;c++)this.putBit(1==(1&a>>>b-c-1))},getLengthInBits:function(){return this.length},putBit:function(a){var b=Math.floor(this.length/8);this.buffer.length<=b&&this.buffer.push(0),a&&(this.buffer[b]|=128>>>this.length%8),this.length++}};var l=[[17,14,11,7],[32,26,20,14],[53,42,32,24],[78,62,46,34],[106,84,60,44],[134,106,74,58],[154,122,86,64],[192,152,108,84],[230,180,130,98],[271,213,151,119],[321,251,177,137],[367,287,203,155],[425,331,241,177],[458,362,258,194],[520,412,292,220],[586,450,322,250],[644,504,364,280],[718,560,394,310],[792,624,442,338],[858,666,482,382],[929,711,509,403],[1003,779,565,439],[1091,857,611,461],[1171,911,661,511],[1273,997,715,535],[1367,1059,751,593],[1465,1125,805,625],[1528,1190,868,658],[1628,1264,908,698],[1732,1370,982,742],[1840,1452,1030,790],[1952,1538,1112,842],[2068,1628,1168,898],[2188,1722,1228,958],[2303,1809,1283,983],[2431,1911,1351,1051],[2563,1989,1423,1093],[2699,2099,1499,1139],[2809,2213,1579,1219],[2953,2331,1663,1273]],o=function(){var a=function(a,b){this._el=a,this._htOption=b};return a.prototype.draw=function(a){function g(a,b){var c=document.createElementNS("http://www.w3.org/2000/svg",a);for(var d in b)b.hasOwnProperty(d)&&c.setAttribute(d,b[d]);return c}var b=this._htOption,c=this._el,d=a.getModuleCount();Math.floor(b.width/d),Math.floor(b.height/d),this.clear();var h=g("svg",{viewBox:"0 0 "+String(d)+" "+String(d),width:"100%",height:"100%",fill:b.colorLight});h.setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns:xlink","http://www.w3.org/1999/xlink"),c.appendChild(h),h.appendChild(g("rect",{fill:b.colorDark,width:"1",height:"1",id:"template"}));for(var i=0;d>i;i++)for(var j=0;d>j;j++)if(a.isDark(i,j)){var k=g("use",{x:String(i),y:String(j)});k.setAttributeNS("http://www.w3.org/1999/xlink","href","#template"),h.appendChild(k)}},a.prototype.clear=function(){for(;this._el.hasChildNodes();)this._el.removeChild(this._el.lastChild)},a}(),p="svg"===document.documentElement.tagName.toLowerCase(),q=p?o:m()?function(){function a(){this._elImage.src=this._elCanvas.toDataURL("image/png"),this._elImage.style.display="block",this._elCanvas.style.display="none"}function d(a,b){var c=this;if(c._fFail=b,c._fSuccess=a,null===c._bSupportDataURI){var d=document.createElement("img"),e=function(){c._bSupportDataURI=!1,c._fFail&&_fFail.call(c)},f=function(){c._bSupportDataURI=!0,c._fSuccess&&c._fSuccess.call(c)};return d.onabort=e,d.onerror=e,d.onload=f,d.src="data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==",void 0}c._bSupportDataURI===!0&&c._fSuccess?c._fSuccess.call(c):c._bSupportDataURI===!1&&c._fFail&&c._fFail.call(c)}if(this._android&&this._android<=2.1){var b=1/window.devicePixelRatio,c=CanvasRenderingContext2D.prototype.drawImage;CanvasRenderingContext2D.prototype.drawImage=function(a,d,e,f,g,h,i,j){if("nodeName"in a&&/img/i.test(a.nodeName))for(var l=arguments.length-1;l>=1;l--)arguments[l]=arguments[l]*b;else"undefined"==typeof j&&(arguments[1]*=b,arguments[2]*=b,arguments[3]*=b,arguments[4]*=b);c.apply(this,arguments)}}var e=function(a,b){this._bIsPainted=!1,this._android=n(),this._htOption=b,this._elCanvas=document.createElement("canvas"),this._elCanvas.width=b.width,this._elCanvas.height=b.height,a.appendChild(this._elCanvas),this._el=a,this._oContext=this._elCanvas.getContext("2d"),this._bIsPainted=!1,this._elImage=document.createElement("img"),this._elImage.style.display="none",this._el.appendChild(this._elImage),this._bSupportDataURI=null};return e.prototype.draw=function(a){var b=this._elImage,c=this._oContext,d=this._htOption,e=a.getModuleCount(),f=d.width/e,g=d.height/e,h=Math.round(f),i=Math.round(g);b.style.display="none",this.clear();for(var j=0;e>j;j++)for(var k=0;e>k;k++){var l=a.isDark(j,k),m=k*f,n=j*g;c.strokeStyle=l?d.colorDark:d.colorLight,c.lineWidth=1,c.fillStyle=l?d.colorDark:d.colorLight,c.fillRect(m,n,f,g),c.strokeRect(Math.floor(m)+.5,Math.floor(n)+.5,h,i),c.strokeRect(Math.ceil(m)-.5,Math.ceil(n)-.5,h,i)}this._bIsPainted=!0},e.prototype.makeImage=function(){this._bIsPainted&&d.call(this,a)},e.prototype.isPainted=function(){return this._bIsPainted},e.prototype.clear=function(){this._oContext.clearRect(0,0,this._elCanvas.width,this._elCanvas.height),this._bIsPainted=!1},e.prototype.round=function(a){return a?Math.floor(1e3*a)/1e3:a},e}():function(){var a=function(a,b){this._el=a,this._htOption=b};return a.prototype.draw=function(a){for(var b=this._htOption,c=this._el,d=a.getModuleCount(),e=Math.floor(b.width/d),f=Math.floor(b.height/d),g=[''],h=0;d>h;h++){g.push("");for(var i=0;d>i;i++)g.push('');g.push("")}g.push("
"),c.innerHTML=g.join("");var j=c.childNodes[0],k=(b.width-j.offsetWidth)/2,l=(b.height-j.offsetHeight)/2;k>0&&l>0&&(j.style.margin=l+"px "+k+"px")},a.prototype.clear=function(){this._el.innerHTML=""},a}();QRCode=function(a,b){if(this._htOption={width:256,height:256,typeNumber:4,colorDark:"#000000",colorLight:"#ffffff",correctLevel:d.H},"string"==typeof b&&(b={text:b}),b)for(var c in b)this._htOption[c]=b[c];"string"==typeof a&&(a=document.getElementById(a)),this._android=n(),this._el=a,this._oQRCode=null,this._oDrawing=new q(this._el,this._htOption),this._htOption.text&&this.makeCode(this._htOption.text)},QRCode.prototype.makeCode=function(a){this._oQRCode=new b(r(a,this._htOption.correctLevel),this._htOption.correctLevel),this._oQRCode.addData(a),this._oQRCode.make(),this._el.title=a,this._oDrawing.draw(this._oQRCode),this.makeImage()},QRCode.prototype.makeImage=function(){"function"==typeof this._oDrawing.makeImage&&(!this._android||this._android>=3)&&this._oDrawing.makeImage()},QRCode.prototype.clear=function(){this._oDrawing.clear()},QRCode.CorrectLevel=d}(); --------------------------------------------------------------------------------