├── .gitignore ├── .travis.yml ├── example.js ├── test.js ├── index.d.ts ├── package.json ├── README.md ├── LICENSE └── index.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 0.6 4 | - 0.8 5 | - "0.10" 6 | -------------------------------------------------------------------------------- /example.js: -------------------------------------------------------------------------------- 1 | var keypair = require('./'); 2 | 3 | var pair = keypair(); 4 | console.log(pair); 5 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | var keypair = require('./index.js'); 2 | var test = require('tape'); 3 | 4 | test('keypair', function (t) { 5 | var pair = keypair(); 6 | t.ok(pair.private, 'private key'); 7 | t.assert(/BEGIN RSA PRIVATE KEY/.test(pair.private), 'private header'); 8 | t.ok(pair.public, 'public key'); 9 | t.assert(/BEGIN RSA PUBLIC KEY/.test(pair.public), 'public header'); 10 | t.end(); 11 | }); 12 | -------------------------------------------------------------------------------- /index.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for keypair 1.0 2 | // Project: https://www.npmjs.com/package/keypair 3 | // Definitions by: eskelter 4 | // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped 5 | // TypeScript Version: 2.2 6 | export interface KeypairOptions { 7 | bits?: number; 8 | e?: number; 9 | } 10 | export interface KeypairResults { 11 | public: string; 12 | private: string; 13 | } 14 | 15 | /** 16 | * Get an RSA PEM key pair. 17 | * @param opts 18 | */ 19 | export function keypair(opts?: KeypairOptions): KeypairResults; 20 | export default keypair; 21 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "keypair", 3 | "description": "Generate a RSA PEM key pair from pure JS", 4 | "version": "1.0.4", 5 | "repository": { 6 | "type": "git", 7 | "url": "git://github.com/juliangruber/keypair.git" 8 | }, 9 | "homepage": "https://github.com/juliangruber/keypair", 10 | "main": "index.js", 11 | "scripts": { 12 | "test": "tape test.js" 13 | }, 14 | "devDependencies": { 15 | "tape": "~1.0.2" 16 | }, 17 | "keywords": [ 18 | "rsa", 19 | "keypair", 20 | "keys", 21 | "encryption", 22 | "public", 23 | "private", 24 | "key", 25 | "ssh" 26 | ], 27 | "author": { 28 | "name": "Julian Gruber", 29 | "email": "mail@juliangruber.com", 30 | "url": "http://juliangruber.com" 31 | }, 32 | "testling": { 33 | "files": "test.js", 34 | "browsers": [ 35 | "ie/6..latest", 36 | "firefox/10", 37 | "chrome/20..latest", 38 | "safari/5.0.5..latest", 39 | "opera/11.0..latest", 40 | "iphone/6.0", 41 | "ipad/6.0", 42 | "android-browser/4.2" 43 | ] 44 | }, 45 | "license": "BSD / GPL" 46 | } 47 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # keypair 2 | 3 | Generate a RSA PEM key pair from pure JS 4 | 5 | [![Build Status](https://travis-ci.org/juliangruber/keypair.svg?branch=master)](https://travis-ci.org/juliangruber/keypair) 6 | [![downloads](https://img.shields.io/npm/dm/keypair.svg)](https://www.npmjs.org/package/keypair) 7 | 8 | [![browser support](https://ci.testling.com/juliangruber/keypair.png)](https://ci.testling.com/juliangruber/keypair) 9 | 10 | ## Usage 11 | 12 | ```js 13 | var keypair = require('keypair'); 14 | 15 | var pair = keypair(); 16 | console.log(pair); 17 | ``` 18 | 19 | outputs 20 | 21 | ``` 22 | $ node example.js 23 | { public: '-----BEGIN RSA PUBLIC KEY-----\r\nMIGJAoGBAM3CosR73CBNcJsLv5E90NsFt6qN1uziQ484gbOoule8leXHFbyIzPQRozgEpSpi\r\nwhr6d2/c0CfZHEJ3m5tV0klxfjfM7oqjRMURnH/rmBjcETQ7qzIISZQ/iptJ3p7Gi78X5ZMh\r\nLNtDkUFU9WaGdiEb+SnC39wjErmJSfmGb7i1AgMBAAE=\r\n-----END RSA PUBLIC KEY-----\n', 24 | private: '-----BEGIN RSA PRIVATE KEY-----\r\nMIICXAIBAAKBgQDNwqLEe9wgTXCbC7+RPdDbBbeqjdbs4kOPOIGzqLpXvJXlxxW8iMz0EaM4\r\nBKUqYsIa+ndv3NAn2RxCd5ubVdJJcX43zO6Ko0TFEZx/65gY3BE0O6syCEmUP4qbSd6exou/\r\nF+WTISzbQ5FBVPVmhnYhG/kpwt/cIxK5iUn5hm+4tQIDAQABAoGBAI+8xiPoOrA+KMnG/T4j\r\nJsG6TsHQcDHvJi7o1IKC/hnIXha0atTX5AUkRRce95qSfvKFweXdJXSQ0JMGJyfuXgU6dI0T\r\ncseFRfewXAa/ssxAC+iUVR6KUMh1PE2wXLitfeI6JLvVtrBYswm2I7CtY0q8n5AGimHWVXJP\r\nLfGV7m0BAkEA+fqFt2LXbLtyg6wZyxMA/cnmt5Nt3U2dAu77MzFJvibANUNHE4HPLZxjGNXN\r\n+a6m0K6TD4kDdh5HfUYLWWRBYQJBANK3carmulBwqzcDBjsJ0YrIONBpCAsXxk8idXb8jL9a\r\nNIg15Wumm2enqqObahDHB5jnGOLmbasizvSVqypfM9UCQCQl8xIqy+YgURXzXCN+kwUgHinr\r\nutZms87Jyi+D8Br8NY0+Nlf+zHvXAomD2W5CsEK7C+8SLBr3k/TsnRWHJuECQHFE9RA2OP8W\r\noaLPuGCyFXaxzICThSRZYluVnWkZtxsBhW2W8z1b8PvWUE7kMy7TnkzeJS2LSnaNHoyxi7Ia\r\nPQUCQCwWU4U+v4lD7uYBw00Ga/xt+7+UqFPlPVdz1yyr4q24Zxaw0LgmuEvgU5dycq8N7Jxj\r\nTubX0MIRR+G9fmDBBl8=\r\n-----END RSA PRIVATE KEY-----\n' } 25 | ``` 26 | 27 | ## Performance 28 | 29 | Performance greatly depends on the bit size of the generated private key. With 1024 bits you get a key in 0.5s-2s, with 2048 bits it takes 8s-20s, on the same machine. As this will block the event loop while generating the key, 30 | make sure that's ok or to spawn a child process or run it inside a webworker. 31 | 32 | ## Pro Tip: authorized_keys 33 | 34 | @maxogden found out how to use this module to create entries for the `authorized_keys` file: 35 | 36 | ```js 37 | var keypair = require('keypair'); 38 | var forge = require('node-forge'); 39 | 40 | var pair = keypair(); 41 | var publicKey = forge.pki.publicKeyFromPem(pair.public); 42 | var ssh = forge.ssh.publicKeyToOpenSSH(publicKey, 'user@domain.tld'); 43 | console.log(ssh); 44 | ``` 45 | 46 | ## API 47 | 48 | ### keypair([opts]) 49 | 50 | Get an RSA PEM key pair. 51 | 52 | `opts` can be 53 | 54 | * `bits`: the size for the private key in bits. Default: **2048**. 55 | * `e`: the public exponent to use. Default: **65537**. 56 | 57 | ## Installation 58 | 59 | With [npm](http://npmjs.org) do 60 | 61 | ```bash 62 | $ npm install keypair 63 | ``` 64 | 65 | ## Kudos 66 | 67 | To [digitalbazaar](https://github.com/digitalbazaar) for their 68 | [forge](https://github.com/digitalbazaar/forge) project, this library is merely a 69 | wrapper around some of forge's functions. 70 | 71 | ## License 72 | 73 | BSD / GPL 74 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | You may use the Forge project under the terms of either the BSD License or the 2 | GNU General Public License (GPL) Version 2. 3 | 4 | The BSD License is recommended for most projects. It is simple and easy to 5 | understand and it places almost no restrictions on what you can do with the 6 | Forge project. 7 | 8 | If the GPL suits your project better you are also free to use Forge under 9 | that license. 10 | 11 | You don't have to do anything special to choose one license or the other and 12 | you don't have to notify anyone which license you are using. You are free to 13 | use this project in commercial projects as long as the copyright header is 14 | left intact. 15 | 16 | If you are a commercial entity and use this set of libraries in your 17 | commercial software then reasonable payment to Digital Bazaar, if you can 18 | afford it, is not required but is expected and would be appreciated. If this 19 | library saves you time, then it's saving you money. The cost of developing 20 | the Forge software was on the order of several hundred hours and tens of 21 | thousands of dollars. We are attempting to strike a balance between helping 22 | the development community while not being taken advantage of by lucrative 23 | commercial entities for our efforts. 24 | 25 | ------------------------------------------------------------------------------- 26 | New BSD License (3-clause) 27 | Copyright (c) 2010, Digital Bazaar, Inc. 28 | All rights reserved. 29 | 30 | Redistribution and use in source and binary forms, with or without 31 | modification, are permitted provided that the following conditions are met: 32 | * Redistributions of source code must retain the above copyright 33 | notice, this list of conditions and the following disclaimer. 34 | * Redistributions in binary form must reproduce the above copyright 35 | notice, this list of conditions and the following disclaimer in the 36 | documentation and/or other materials provided with the distribution. 37 | * Neither the name of Digital Bazaar, Inc. nor the 38 | names of its contributors may be used to endorse or promote products 39 | derived from this software without specific prior written permission. 40 | 41 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 42 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 43 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 44 | DISCLAIMED. IN NO EVENT SHALL DIGITAL BAZAAR BE LIABLE FOR ANY 45 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 46 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 47 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 48 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 49 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 50 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 51 | 52 | ------------------------------------------------------------------------------- 53 | GNU GENERAL PUBLIC LICENSE 54 | Version 2, June 1991 55 | 56 | Copyright (C) 1989, 1991 Free Software Foundation, Inc. 57 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 58 | Everyone is permitted to copy and distribute verbatim copies 59 | of this license document, but changing it is not allowed. 60 | 61 | Preamble 62 | 63 | The licenses for most software are designed to take away your 64 | freedom to share and change it. By contrast, the GNU General Public 65 | License is intended to guarantee your freedom to share and change free 66 | software--to make sure the software is free for all its users. This 67 | General Public License applies to most of the Free Software 68 | Foundation's software and to any other program whose authors commit to 69 | using it. (Some other Free Software Foundation software is covered by 70 | the GNU Lesser General Public License instead.) You can apply it to 71 | your programs, too. 72 | 73 | When we speak of free software, we are referring to freedom, not 74 | price. Our General Public Licenses are designed to make sure that you 75 | have the freedom to distribute copies of free software (and charge for 76 | this service if you wish), that you receive source code or can get it 77 | if you want it, that you can change the software or use pieces of it 78 | in new free programs; and that you know you can do these things. 79 | 80 | To protect your rights, we need to make restrictions that forbid 81 | anyone to deny you these rights or to ask you to surrender the rights. 82 | These restrictions translate to certain responsibilities for you if you 83 | distribute copies of the software, or if you modify it. 84 | 85 | For example, if you distribute copies of such a program, whether 86 | gratis or for a fee, you must give the recipients all the rights that 87 | you have. You must make sure that they, too, receive or can get the 88 | source code. And you must show them these terms so they know their 89 | rights. 90 | 91 | We protect your rights with two steps: (1) copyright the software, and 92 | (2) offer you this license which gives you legal permission to copy, 93 | distribute and/or modify the software. 94 | 95 | Also, for each author's protection and ours, we want to make certain 96 | that everyone understands that there is no warranty for this free 97 | software. If the software is modified by someone else and passed on, we 98 | want its recipients to know that what they have is not the original, so 99 | that any problems introduced by others will not reflect on the original 100 | authors' reputations. 101 | 102 | Finally, any free program is threatened constantly by software 103 | patents. We wish to avoid the danger that redistributors of a free 104 | program will individually obtain patent licenses, in effect making the 105 | program proprietary. To prevent this, we have made it clear that any 106 | patent must be licensed for everyone's free use or not licensed at all. 107 | 108 | The precise terms and conditions for copying, distribution and 109 | modification follow. 110 | 111 | GNU GENERAL PUBLIC LICENSE 112 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 113 | 114 | 0. This License applies to any program or other work which contains 115 | a notice placed by the copyright holder saying it may be distributed 116 | under the terms of this General Public License. The "Program", below, 117 | refers to any such program or work, and a "work based on the Program" 118 | means either the Program or any derivative work under copyright law: 119 | that is to say, a work containing the Program or a portion of it, 120 | either verbatim or with modifications and/or translated into another 121 | language. (Hereinafter, translation is included without limitation in 122 | the term "modification".) Each licensee is addressed as "you". 123 | 124 | Activities other than copying, distribution and modification are not 125 | covered by this License; they are outside its scope. The act of 126 | running the Program is not restricted, and the output from the Program 127 | is covered only if its contents constitute a work based on the 128 | Program (independent of having been made by running the Program). 129 | Whether that is true depends on what the Program does. 130 | 131 | 1. You may copy and distribute verbatim copies of the Program's 132 | source code as you receive it, in any medium, provided that you 133 | conspicuously and appropriately publish on each copy an appropriate 134 | copyright notice and disclaimer of warranty; keep intact all the 135 | notices that refer to this License and to the absence of any warranty; 136 | and give any other recipients of the Program a copy of this License 137 | along with the Program. 138 | 139 | You may charge a fee for the physical act of transferring a copy, and 140 | you may at your option offer warranty protection in exchange for a fee. 141 | 142 | 2. You may modify your copy or copies of the Program or any portion 143 | of it, thus forming a work based on the Program, and copy and 144 | distribute such modifications or work under the terms of Section 1 145 | above, provided that you also meet all of these conditions: 146 | 147 | a) You must cause the modified files to carry prominent notices 148 | stating that you changed the files and the date of any change. 149 | 150 | b) You must cause any work that you distribute or publish, that in 151 | whole or in part contains or is derived from the Program or any 152 | part thereof, to be licensed as a whole at no charge to all third 153 | parties under the terms of this License. 154 | 155 | c) If the modified program normally reads commands interactively 156 | when run, you must cause it, when started running for such 157 | interactive use in the most ordinary way, to print or display an 158 | announcement including an appropriate copyright notice and a 159 | notice that there is no warranty (or else, saying that you provide 160 | a warranty) and that users may redistribute the program under 161 | these conditions, and telling the user how to view a copy of this 162 | License. (Exception: if the Program itself is interactive but 163 | does not normally print such an announcement, your work based on 164 | the Program is not required to print an announcement.) 165 | 166 | These requirements apply to the modified work as a whole. If 167 | identifiable sections of that work are not derived from the Program, 168 | and can be reasonably considered independent and separate works in 169 | themselves, then this License, and its terms, do not apply to those 170 | sections when you distribute them as separate works. But when you 171 | distribute the same sections as part of a whole which is a work based 172 | on the Program, the distribution of the whole must be on the terms of 173 | this License, whose permissions for other licensees extend to the 174 | entire whole, and thus to each and every part regardless of who wrote it. 175 | 176 | Thus, it is not the intent of this section to claim rights or contest 177 | your rights to work written entirely by you; rather, the intent is to 178 | exercise the right to control the distribution of derivative or 179 | collective works based on the Program. 180 | 181 | In addition, mere aggregation of another work not based on the Program 182 | with the Program (or with a work based on the Program) on a volume of 183 | a storage or distribution medium does not bring the other work under 184 | the scope of this License. 185 | 186 | 3. You may copy and distribute the Program (or a work based on it, 187 | under Section 2) in object code or executable form under the terms of 188 | Sections 1 and 2 above provided that you also do one of the following: 189 | 190 | a) Accompany it with the complete corresponding machine-readable 191 | source code, which must be distributed under the terms of Sections 192 | 1 and 2 above on a medium customarily used for software interchange; or, 193 | 194 | b) Accompany it with a written offer, valid for at least three 195 | years, to give any third party, for a charge no more than your 196 | cost of physically performing source distribution, a complete 197 | machine-readable copy of the corresponding source code, to be 198 | distributed under the terms of Sections 1 and 2 above on a medium 199 | customarily used for software interchange; or, 200 | 201 | c) Accompany it with the information you received as to the offer 202 | to distribute corresponding source code. (This alternative is 203 | allowed only for noncommercial distribution and only if you 204 | received the program in object code or executable form with such 205 | an offer, in accord with Subsection b above.) 206 | 207 | The source code for a work means the preferred form of the work for 208 | making modifications to it. For an executable work, complete source 209 | code means all the source code for all modules it contains, plus any 210 | associated interface definition files, plus the scripts used to 211 | control compilation and installation of the executable. However, as a 212 | special exception, the source code distributed need not include 213 | anything that is normally distributed (in either source or binary 214 | form) with the major components (compiler, kernel, and so on) of the 215 | operating system on which the executable runs, unless that component 216 | itself accompanies the executable. 217 | 218 | If distribution of executable or object code is made by offering 219 | access to copy from a designated place, then offering equivalent 220 | access to copy the source code from the same place counts as 221 | distribution of the source code, even though third parties are not 222 | compelled to copy the source along with the object code. 223 | 224 | 4. You may not copy, modify, sublicense, or distribute the Program 225 | except as expressly provided under this License. Any attempt 226 | otherwise to copy, modify, sublicense or distribute the Program is 227 | void, and will automatically terminate your rights under this License. 228 | However, parties who have received copies, or rights, from you under 229 | this License will not have their licenses terminated so long as such 230 | parties remain in full compliance. 231 | 232 | 5. You are not required to accept this License, since you have not 233 | signed it. However, nothing else grants you permission to modify or 234 | distribute the Program or its derivative works. These actions are 235 | prohibited by law if you do not accept this License. Therefore, by 236 | modifying or distributing the Program (or any work based on the 237 | Program), you indicate your acceptance of this License to do so, and 238 | all its terms and conditions for copying, distributing or modifying 239 | the Program or works based on it. 240 | 241 | 6. Each time you redistribute the Program (or any work based on the 242 | Program), the recipient automatically receives a license from the 243 | original licensor to copy, distribute or modify the Program subject to 244 | these terms and conditions. You may not impose any further 245 | restrictions on the recipients' exercise of the rights granted herein. 246 | You are not responsible for enforcing compliance by third parties to 247 | this License. 248 | 249 | 7. If, as a consequence of a court judgment or allegation of patent 250 | infringement or for any other reason (not limited to patent issues), 251 | conditions are imposed on you (whether by court order, agreement or 252 | otherwise) that contradict the conditions of this License, they do not 253 | excuse you from the conditions of this License. If you cannot 254 | distribute so as to satisfy simultaneously your obligations under this 255 | License and any other pertinent obligations, then as a consequence you 256 | may not distribute the Program at all. For example, if a patent 257 | license would not permit royalty-free redistribution of the Program by 258 | all those who receive copies directly or indirectly through you, then 259 | the only way you could satisfy both it and this License would be to 260 | refrain entirely from distribution of the Program. 261 | 262 | If any portion of this section is held invalid or unenforceable under 263 | any particular circumstance, the balance of the section is intended to 264 | apply and the section as a whole is intended to apply in other 265 | circumstances. 266 | 267 | It is not the purpose of this section to induce you to infringe any 268 | patents or other property right claims or to contest validity of any 269 | such claims; this section has the sole purpose of protecting the 270 | integrity of the free software distribution system, which is 271 | implemented by public license practices. Many people have made 272 | generous contributions to the wide range of software distributed 273 | through that system in reliance on consistent application of that 274 | system; it is up to the author/donor to decide if he or she is willing 275 | to distribute software through any other system and a licensee cannot 276 | impose that choice. 277 | 278 | This section is intended to make thoroughly clear what is believed to 279 | be a consequence of the rest of this License. 280 | 281 | 8. If the distribution and/or use of the Program is restricted in 282 | certain countries either by patents or by copyrighted interfaces, the 283 | original copyright holder who places the Program under this License 284 | may add an explicit geographical distribution limitation excluding 285 | those countries, so that distribution is permitted only in or among 286 | countries not thus excluded. In such case, this License incorporates 287 | the limitation as if written in the body of this License. 288 | 289 | 9. The Free Software Foundation may publish revised and/or new versions 290 | of the General Public License from time to time. Such new versions will 291 | be similar in spirit to the present version, but may differ in detail to 292 | address new problems or concerns. 293 | 294 | Each version is given a distinguishing version number. If the Program 295 | specifies a version number of this License which applies to it and "any 296 | later version", you have the option of following the terms and conditions 297 | either of that version or of any later version published by the Free 298 | Software Foundation. If the Program does not specify a version number of 299 | this License, you may choose any version ever published by the Free Software 300 | Foundation. 301 | 302 | 10. If you wish to incorporate parts of the Program into other free 303 | programs whose distribution conditions are different, write to the author 304 | to ask for permission. For software which is copyrighted by the Free 305 | Software Foundation, write to the Free Software Foundation; we sometimes 306 | make exceptions for this. Our decision will be guided by the two goals 307 | of preserving the free status of all derivatives of our free software and 308 | of promoting the sharing and reuse of software generally. 309 | 310 | NO WARRANTY 311 | 312 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 313 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 314 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 315 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 316 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 317 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 318 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 319 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 320 | REPAIR OR CORRECTION. 321 | 322 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 323 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 324 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 325 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 326 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 327 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 328 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 329 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 330 | POSSIBILITY OF SUCH DAMAGES. 331 | 332 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var forge = {}; 2 | var aes = forge.aes = {}; 3 | var md = forge.md = {}; 4 | var pki = forge.pki = {}; 5 | var rsa = forge.pki.rsa = forge.rsa = {}; 6 | var util = forge.util = {}; 7 | 8 | /** 9 | * Expose `keypair`. 10 | */ 11 | 12 | module.exports = function (opts) { 13 | if (!opts) opts = {}; 14 | if (typeof opts.bits == 'undefined') opts.bits = 2048; 15 | var keypair = forge.rsa.generateKeyPair(opts); 16 | keypair = { 17 | public: fix(forge.pki.publicKeyToRSAPublicKeyPem(keypair.publicKey, 72)), 18 | private: fix(forge.pki.privateKeyToPem(keypair.privateKey, 72)) 19 | }; 20 | return keypair; 21 | }; 22 | 23 | function fix (str) { 24 | return str.replace(/\r/g, '') + '\n' 25 | } 26 | 27 | /** 28 | * util.fillString 29 | */ 30 | 31 | util.fillString = function(c, n) { 32 | var s = ''; 33 | while(n > 0) { 34 | if(n & 1) { 35 | s += c; 36 | } 37 | n >>>= 1; 38 | if(n > 0) { 39 | c += c; 40 | } 41 | } 42 | return s; 43 | }; 44 | 45 | /** 46 | * md.sha1 47 | */ 48 | 49 | var sha1 = forge.sha1 = forge.md.sha1 = {}; 50 | 51 | // sha-1 padding bytes not initialized yet 52 | var _padding = null; 53 | var _initialized = false; 54 | 55 | /** 56 | * Initializes the constant tables. 57 | */ 58 | var _init = function() { 59 | // create padding 60 | _padding = String.fromCharCode(128); 61 | _padding += forge.util.fillString(String.fromCharCode(0x00), 64); 62 | 63 | // now initialized 64 | _initialized = true; 65 | }; 66 | 67 | /** 68 | * Updates a SHA-1 state with the given byte buffer. 69 | * 70 | * @param s the SHA-1 state to update. 71 | * @param w the array to use to store words. 72 | * @param bytes the byte buffer to update with. 73 | */ 74 | var _update = function(s, w, bytes) { 75 | // consume 512 bit (64 byte) chunks 76 | var t, a, b, c, d, e, f, i; 77 | var len = bytes.length(); 78 | while(len >= 64) { 79 | // the w array will be populated with sixteen 32-bit big-endian words 80 | // and then extended into 80 32-bit words according to SHA-1 algorithm 81 | // and for 32-79 using Max Locktyukhin's optimization 82 | 83 | // initialize hash value for this chunk 84 | a = s.h0; 85 | b = s.h1; 86 | c = s.h2; 87 | d = s.h3; 88 | e = s.h4; 89 | 90 | // round 1 91 | for(i = 0; i < 16; ++i) { 92 | t = bytes.getInt32(); 93 | w[i] = t; 94 | f = d ^ (b & (c ^ d)); 95 | t = ((a << 5) | (a >>> 27)) + f + e + 0x5A827999 + t; 96 | e = d; 97 | d = c; 98 | c = (b << 30) | (b >>> 2); 99 | b = a; 100 | a = t; 101 | } 102 | for(; i < 20; ++i) { 103 | t = (w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16]); 104 | t = (t << 1) | (t >>> 31); 105 | w[i] = t; 106 | f = d ^ (b & (c ^ d)); 107 | t = ((a << 5) | (a >>> 27)) + f + e + 0x5A827999 + t; 108 | e = d; 109 | d = c; 110 | c = (b << 30) | (b >>> 2); 111 | b = a; 112 | a = t; 113 | } 114 | // round 2 115 | for(; i < 32; ++i) { 116 | t = (w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16]); 117 | t = (t << 1) | (t >>> 31); 118 | w[i] = t; 119 | f = b ^ c ^ d; 120 | t = ((a << 5) | (a >>> 27)) + f + e + 0x6ED9EBA1 + t; 121 | e = d; 122 | d = c; 123 | c = (b << 30) | (b >>> 2); 124 | b = a; 125 | a = t; 126 | } 127 | for(; i < 40; ++i) { 128 | t = (w[i - 6] ^ w[i - 16] ^ w[i - 28] ^ w[i - 32]); 129 | t = (t << 2) | (t >>> 30); 130 | w[i] = t; 131 | f = b ^ c ^ d; 132 | t = ((a << 5) | (a >>> 27)) + f + e + 0x6ED9EBA1 + t; 133 | e = d; 134 | d = c; 135 | c = (b << 30) | (b >>> 2); 136 | b = a; 137 | a = t; 138 | } 139 | // round 3 140 | for(; i < 60; ++i) { 141 | t = (w[i - 6] ^ w[i - 16] ^ w[i - 28] ^ w[i - 32]); 142 | t = (t << 2) | (t >>> 30); 143 | w[i] = t; 144 | f = (b & c) | (d & (b ^ c)); 145 | t = ((a << 5) | (a >>> 27)) + f + e + 0x8F1BBCDC + t; 146 | e = d; 147 | d = c; 148 | c = (b << 30) | (b >>> 2); 149 | b = a; 150 | a = t; 151 | } 152 | // round 4 153 | for(; i < 80; ++i) { 154 | t = (w[i - 6] ^ w[i - 16] ^ w[i - 28] ^ w[i - 32]); 155 | t = (t << 2) | (t >>> 30); 156 | w[i] = t; 157 | f = b ^ c ^ d; 158 | t = ((a << 5) | (a >>> 27)) + f + e + 0xCA62C1D6 + t; 159 | e = d; 160 | d = c; 161 | c = (b << 30) | (b >>> 2); 162 | b = a; 163 | a = t; 164 | } 165 | 166 | // update hash state 167 | s.h0 += a; 168 | s.h1 += b; 169 | s.h2 += c; 170 | s.h3 += d; 171 | s.h4 += e; 172 | 173 | len -= 64; 174 | } 175 | }; 176 | 177 | /** 178 | * Creates a SHA-1 message digest object. 179 | * 180 | * @return a message digest object. 181 | */ 182 | sha1.create = function() { 183 | // do initialization as necessary 184 | if(!_initialized) { 185 | _init(); 186 | } 187 | 188 | // SHA-1 state contains five 32-bit integers 189 | var _state = null; 190 | 191 | // input buffer 192 | var _input = forge.util.createBuffer(); 193 | 194 | // used for word storage 195 | var _w = new Array(80); 196 | 197 | // message digest object 198 | var md = { 199 | algorithm: 'sha1', 200 | blockLength: 64, 201 | digestLength: 20, 202 | // length of message so far (does not including padding) 203 | messageLength: 0 204 | }; 205 | 206 | /** 207 | * Starts the digest. 208 | */ 209 | md.start = function() { 210 | md.messageLength = 0; 211 | _input = forge.util.createBuffer(); 212 | _state = { 213 | h0: 0x67452301, 214 | h1: 0xEFCDAB89, 215 | h2: 0x98BADCFE, 216 | h3: 0x10325476, 217 | h4: 0xC3D2E1F0 218 | }; 219 | }; 220 | // start digest automatically for first time 221 | md.start(); 222 | 223 | /** 224 | * Updates the digest with the given message input. The given input can 225 | * treated as raw input (no encoding will be applied) or an encoding of 226 | * 'utf8' maybe given to encode the input using UTF-8. 227 | * 228 | * @param msg the message input to update with. 229 | * @param encoding the encoding to use (default: 'raw', other: 'utf8'). 230 | */ 231 | md.update = function(msg, encoding) { 232 | if(encoding === 'utf8') { 233 | msg = forge.util.encodeUtf8(msg); 234 | } 235 | 236 | // update message length 237 | md.messageLength += msg.length; 238 | 239 | // add bytes to input buffer 240 | _input.putBytes(msg); 241 | 242 | // process bytes 243 | _update(_state, _w, _input); 244 | 245 | // compact input buffer every 2K or if empty 246 | if(_input.read > 2048 || _input.length() === 0) { 247 | _input.compact(); 248 | } 249 | }; 250 | 251 | /** 252 | * Produces the digest. 253 | * 254 | * @return a byte buffer containing the digest value. 255 | */ 256 | md.digest = function() { 257 | /* Note: Here we copy the remaining bytes in the input buffer and 258 | add the appropriate SHA-1 padding. Then we do the final update 259 | on a copy of the state so that if the user wants to get 260 | intermediate digests they can do so. */ 261 | 262 | /* Determine the number of bytes that must be added to the message 263 | to ensure its length is congruent to 448 mod 512. In other words, 264 | a 64-bit integer that gives the length of the message will be 265 | appended to the message and whatever the length of the message is 266 | plus 64 bits must be a multiple of 512. So the length of the 267 | message must be congruent to 448 mod 512 because 512 - 64 = 448. 268 | 269 | In order to fill up the message length it must be filled with 270 | padding that begins with 1 bit followed by all 0 bits. Padding 271 | must *always* be present, so if the message length is already 272 | congruent to 448 mod 512, then 512 padding bits must be added. */ 273 | 274 | // 512 bits == 64 bytes, 448 bits == 56 bytes, 64 bits = 8 bytes 275 | // _padding starts with 1 byte with first bit is set in it which 276 | // is byte value 128, then there may be up to 63 other pad bytes 277 | var len = md.messageLength; 278 | var padBytes = forge.util.createBuffer(); 279 | padBytes.putBytes(_input.bytes()); 280 | padBytes.putBytes(_padding.substr(0, 64 - ((len + 8) % 64))); 281 | 282 | /* Now append length of the message. The length is appended in bits 283 | as a 64-bit number in big-endian order. Since we store the length 284 | in bytes, we must multiply it by 8 (or left shift by 3). So here 285 | store the high 3 bits in the low end of the first 32-bits of the 286 | 64-bit number and the lower 5 bits in the high end of the second 287 | 32-bits. */ 288 | padBytes.putInt32((len >>> 29) & 0xFF); 289 | padBytes.putInt32((len << 3) & 0xFFFFFFFF); 290 | var s2 = { 291 | h0: _state.h0, 292 | h1: _state.h1, 293 | h2: _state.h2, 294 | h3: _state.h3, 295 | h4: _state.h4 296 | }; 297 | _update(s2, _w, padBytes); 298 | var rval = forge.util.createBuffer(); 299 | rval.putInt32(s2.h0); 300 | rval.putInt32(s2.h1); 301 | rval.putInt32(s2.h2); 302 | rval.putInt32(s2.h3); 303 | rval.putInt32(s2.h4); 304 | return rval; 305 | }; 306 | 307 | return md; 308 | }; 309 | 310 | 311 | /** 312 | * util.ByteBuffer 313 | */ 314 | 315 | /** 316 | * Constructor for a byte buffer. 317 | * 318 | * @param b the bytes to wrap (as a UTF-8 string) (optional). 319 | */ 320 | util.ByteBuffer = function(b) { 321 | // the data in this buffer 322 | this.data = b || ''; 323 | // the pointer for reading from this buffer 324 | this.read = 0; 325 | }; 326 | 327 | /** 328 | * Gets the number of bytes in this buffer. 329 | * 330 | * @return the number of bytes in this buffer. 331 | */ 332 | util.ByteBuffer.prototype.length = function() { 333 | return this.data.length - this.read; 334 | }; 335 | 336 | /** 337 | * Gets whether or not this buffer is empty. 338 | * 339 | * @return true if this buffer is empty, false if not. 340 | */ 341 | util.ByteBuffer.prototype.isEmpty = function() { 342 | return (this.data.length - this.read) === 0; 343 | }; 344 | 345 | /** 346 | * Puts a byte in this buffer. 347 | * 348 | * @param b the byte to put. 349 | */ 350 | util.ByteBuffer.prototype.putByte = function(b) { 351 | this.data += String.fromCharCode(b); 352 | }; 353 | 354 | /** 355 | * Puts a byte in this buffer N times. 356 | * 357 | * @param b the byte to put. 358 | * @param n the number of bytes of value b to put. 359 | */ 360 | util.ByteBuffer.prototype.fillWithByte = function(b, n) { 361 | b = String.fromCharCode(b); 362 | var d = this.data; 363 | while(n > 0) { 364 | if(n & 1) { 365 | d += b; 366 | } 367 | n >>>= 1; 368 | if(n > 0) { 369 | b += b; 370 | } 371 | } 372 | this.data = d; 373 | }; 374 | 375 | /** 376 | * Puts bytes in this buffer. 377 | * 378 | * @param bytes the bytes (as a UTF-8 encoded string) to put. 379 | */ 380 | util.ByteBuffer.prototype.putBytes = function(bytes) { 381 | this.data += bytes; 382 | }; 383 | 384 | /** 385 | * Puts a UTF-16 encoded string into this buffer. 386 | * 387 | * @param str the string to put. 388 | */ 389 | util.ByteBuffer.prototype.putString = function(str) { 390 | this.data += util.encodeUtf8(str); 391 | }; 392 | 393 | /** 394 | * Puts a 16-bit integer in this buffer in big-endian order. 395 | * 396 | * @param i the 16-bit integer. 397 | */ 398 | util.ByteBuffer.prototype.putInt16 = function(i) { 399 | this.data += 400 | String.fromCharCode(i >> 8 & 0xFF) + 401 | String.fromCharCode(i & 0xFF); 402 | }; 403 | 404 | /** 405 | * Puts a 24-bit integer in this buffer in big-endian order. 406 | * 407 | * @param i the 24-bit integer. 408 | */ 409 | util.ByteBuffer.prototype.putInt24 = function(i) { 410 | this.data += 411 | String.fromCharCode(i >> 16 & 0xFF) + 412 | String.fromCharCode(i >> 8 & 0xFF) + 413 | String.fromCharCode(i & 0xFF); 414 | }; 415 | 416 | /** 417 | * Puts a 32-bit integer in this buffer in big-endian order. 418 | * 419 | * @param i the 32-bit integer. 420 | */ 421 | util.ByteBuffer.prototype.putInt32 = function(i) { 422 | this.data += 423 | String.fromCharCode(i >> 24 & 0xFF) + 424 | String.fromCharCode(i >> 16 & 0xFF) + 425 | String.fromCharCode(i >> 8 & 0xFF) + 426 | String.fromCharCode(i & 0xFF); 427 | }; 428 | 429 | /** 430 | * Puts a 16-bit integer in this buffer in little-endian order. 431 | * 432 | * @param i the 16-bit integer. 433 | */ 434 | util.ByteBuffer.prototype.putInt16Le = function(i) { 435 | this.data += 436 | String.fromCharCode(i & 0xFF) + 437 | String.fromCharCode(i >> 8 & 0xFF); 438 | }; 439 | 440 | /** 441 | * Puts a 24-bit integer in this buffer in little-endian order. 442 | * 443 | * @param i the 24-bit integer. 444 | */ 445 | util.ByteBuffer.prototype.putInt24Le = function(i) { 446 | this.data += 447 | String.fromCharCode(i & 0xFF) + 448 | String.fromCharCode(i >> 8 & 0xFF) + 449 | String.fromCharCode(i >> 16 & 0xFF); 450 | }; 451 | 452 | /** 453 | * Puts a 32-bit integer in this buffer in little-endian order. 454 | * 455 | * @param i the 32-bit integer. 456 | */ 457 | util.ByteBuffer.prototype.putInt32Le = function(i) { 458 | this.data += 459 | String.fromCharCode(i & 0xFF) + 460 | String.fromCharCode(i >> 8 & 0xFF) + 461 | String.fromCharCode(i >> 16 & 0xFF) + 462 | String.fromCharCode(i >> 24 & 0xFF); 463 | }; 464 | 465 | /** 466 | * Puts an n-bit integer in this buffer in big-endian order. 467 | * 468 | * @param i the n-bit integer. 469 | * @param n the number of bits in the integer. 470 | */ 471 | util.ByteBuffer.prototype.putInt = function(i, n) { 472 | do { 473 | n -= 8; 474 | this.data += String.fromCharCode((i >> n) & 0xFF); 475 | } 476 | while(n > 0); 477 | }; 478 | 479 | /** 480 | * Puts the given buffer into this buffer. 481 | * 482 | * @param buffer the buffer to put into this one. 483 | */ 484 | util.ByteBuffer.prototype.putBuffer = function(buffer) { 485 | this.data += buffer.getBytes(); 486 | }; 487 | 488 | /** 489 | * Gets a byte from this buffer and advances the read pointer by 1. 490 | * 491 | * @return the byte. 492 | */ 493 | util.ByteBuffer.prototype.getByte = function() { 494 | return this.data.charCodeAt(this.read++); 495 | }; 496 | 497 | /** 498 | * Gets a uint16 from this buffer in big-endian order and advances the read 499 | * pointer by 2. 500 | * 501 | * @return the uint16. 502 | */ 503 | util.ByteBuffer.prototype.getInt16 = function() { 504 | var rval = ( 505 | this.data.charCodeAt(this.read) << 8 ^ 506 | this.data.charCodeAt(this.read + 1)); 507 | this.read += 2; 508 | return rval; 509 | }; 510 | 511 | /** 512 | * Gets a uint24 from this buffer in big-endian order and advances the read 513 | * pointer by 3. 514 | * 515 | * @return the uint24. 516 | */ 517 | util.ByteBuffer.prototype.getInt24 = function() { 518 | var rval = ( 519 | this.data.charCodeAt(this.read) << 16 ^ 520 | this.data.charCodeAt(this.read + 1) << 8 ^ 521 | this.data.charCodeAt(this.read + 2)); 522 | this.read += 3; 523 | return rval; 524 | }; 525 | 526 | /** 527 | * Gets a uint32 from this buffer in big-endian order and advances the read 528 | * pointer by 4. 529 | * 530 | * @return the word. 531 | */ 532 | util.ByteBuffer.prototype.getInt32 = function() { 533 | var rval = ( 534 | this.data.charCodeAt(this.read) << 24 ^ 535 | this.data.charCodeAt(this.read + 1) << 16 ^ 536 | this.data.charCodeAt(this.read + 2) << 8 ^ 537 | this.data.charCodeAt(this.read + 3)); 538 | this.read += 4; 539 | return rval; 540 | }; 541 | 542 | /** 543 | * Gets a uint16 from this buffer in little-endian order and advances the read 544 | * pointer by 2. 545 | * 546 | * @return the uint16. 547 | */ 548 | util.ByteBuffer.prototype.getInt16Le = function() { 549 | var rval = ( 550 | this.data.charCodeAt(this.read) ^ 551 | this.data.charCodeAt(this.read + 1) << 8); 552 | this.read += 2; 553 | return rval; 554 | }; 555 | 556 | /** 557 | * Gets a uint24 from this buffer in little-endian order and advances the read 558 | * pointer by 3. 559 | * 560 | * @return the uint24. 561 | */ 562 | util.ByteBuffer.prototype.getInt24Le = function() { 563 | var rval = ( 564 | this.data.charCodeAt(this.read) ^ 565 | this.data.charCodeAt(this.read + 1) << 8 ^ 566 | this.data.charCodeAt(this.read + 2) << 16); 567 | this.read += 3; 568 | return rval; 569 | }; 570 | 571 | /** 572 | * Gets a uint32 from this buffer in little-endian order and advances the read 573 | * pointer by 4. 574 | * 575 | * @return the word. 576 | */ 577 | util.ByteBuffer.prototype.getInt32Le = function() { 578 | var rval = ( 579 | this.data.charCodeAt(this.read) ^ 580 | this.data.charCodeAt(this.read + 1) << 8 ^ 581 | this.data.charCodeAt(this.read + 2) << 16 ^ 582 | this.data.charCodeAt(this.read + 3) << 24); 583 | this.read += 4; 584 | return rval; 585 | }; 586 | 587 | /** 588 | * Gets an n-bit integer from this buffer in big-endian order and advances the 589 | * read pointer by n/8. 590 | * 591 | * @param n the number of bits in the integer. 592 | * 593 | * @return the integer. 594 | */ 595 | util.ByteBuffer.prototype.getInt = function(n) { 596 | var rval = 0; 597 | do { 598 | rval = (rval << n) + this.data.charCodeAt(this.read++); 599 | n -= 8; 600 | } 601 | while(n > 0); 602 | return rval; 603 | }; 604 | 605 | /** 606 | * Reads bytes out into a UTF-8 string and clears them from the buffer. 607 | * 608 | * @param count the number of bytes to read, undefined or null for all. 609 | * 610 | * @return a UTF-8 string of bytes. 611 | */ 612 | util.ByteBuffer.prototype.getBytes = function(count) { 613 | var rval; 614 | if(count) { 615 | // read count bytes 616 | count = Math.min(this.length(), count); 617 | rval = this.data.slice(this.read, this.read + count); 618 | this.read += count; 619 | } 620 | else if(count === 0) { 621 | rval = ''; 622 | } 623 | else { 624 | // read all bytes, optimize to only copy when needed 625 | rval = (this.read === 0) ? this.data : this.data.slice(this.read); 626 | this.clear(); 627 | } 628 | return rval; 629 | }; 630 | 631 | /** 632 | * Gets a UTF-8 encoded string of the bytes from this buffer without modifying 633 | * the read pointer. 634 | * 635 | * @param count the number of bytes to get, omit to get all. 636 | * 637 | * @return a string full of UTF-8 encoded characters. 638 | */ 639 | util.ByteBuffer.prototype.bytes = function(count) { 640 | return (typeof(count) === 'undefined' ? 641 | this.data.slice(this.read) : 642 | this.data.slice(this.read, this.read + count)); 643 | }; 644 | 645 | /** 646 | * Gets a byte at the given index without modifying the read pointer. 647 | * 648 | * @param i the byte index. 649 | * 650 | * @return the byte. 651 | */ 652 | util.ByteBuffer.prototype.at = function(i) { 653 | return this.data.charCodeAt(this.read + i); 654 | }; 655 | 656 | /** 657 | * Puts a byte at the given index without modifying the read pointer. 658 | * 659 | * @param i the byte index. 660 | * @param b the byte to put. 661 | */ 662 | util.ByteBuffer.prototype.setAt = function(i, b) { 663 | this.data = this.data.substr(0, this.read + i) + 664 | String.fromCharCode(b) + 665 | this.data.substr(this.read + i + 1); 666 | }; 667 | 668 | /** 669 | * Gets the last byte without modifying the read pointer. 670 | * 671 | * @return the last byte. 672 | */ 673 | util.ByteBuffer.prototype.last = function() { 674 | return this.data.charCodeAt(this.data.length - 1); 675 | }; 676 | 677 | /** 678 | * Creates a copy of this buffer. 679 | * 680 | * @return the copy. 681 | */ 682 | util.ByteBuffer.prototype.copy = function() { 683 | var c = util.createBuffer(this.data); 684 | c.read = this.read; 685 | return c; 686 | }; 687 | 688 | /** 689 | * Compacts this buffer. 690 | */ 691 | util.ByteBuffer.prototype.compact = function() { 692 | if(this.read > 0) { 693 | this.data = this.data.slice(this.read); 694 | this.read = 0; 695 | } 696 | }; 697 | 698 | /** 699 | * Clears this buffer. 700 | */ 701 | util.ByteBuffer.prototype.clear = function() { 702 | this.data = ''; 703 | this.read = 0; 704 | }; 705 | 706 | /** 707 | * Shortens this buffer by triming bytes off of the end of this buffer. 708 | * 709 | * @param count the number of bytes to trim off. 710 | */ 711 | util.ByteBuffer.prototype.truncate = function(count) { 712 | var len = Math.max(0, this.length() - count); 713 | this.data = this.data.substr(this.read, len); 714 | this.read = 0; 715 | }; 716 | 717 | /** 718 | * Converts this buffer to a hexadecimal string. 719 | * 720 | * @return a hexadecimal string. 721 | */ 722 | util.ByteBuffer.prototype.toHex = function() { 723 | var rval = ''; 724 | for(var i = this.read; i < this.data.length; ++i) { 725 | var b = this.data.charCodeAt(i); 726 | if(b < 16) { 727 | rval += '0'; 728 | } 729 | rval += b.toString(16); 730 | } 731 | return rval; 732 | }; 733 | 734 | /** 735 | * Converts this buffer to a UTF-16 string (standard JavaScript string). 736 | * 737 | * @return a UTF-16 string. 738 | */ 739 | util.ByteBuffer.prototype.toString = function() { 740 | return util.decodeUtf8(this.bytes()); 741 | }; 742 | /** 743 | * util.createBuffer 744 | */ 745 | 746 | util.createBuffer = function(input, encoding) { 747 | encoding = encoding || 'raw'; 748 | if(input !== undefined && encoding === 'utf8') { 749 | input = util.encodeUtf8(input); 750 | } 751 | return new util.ByteBuffer(input); 752 | }; 753 | 754 | /** 755 | * prng.create 756 | */ 757 | 758 | var prng = forge.prng = {}; 759 | 760 | var crypto; 761 | try { 762 | crypto = require('crypto'); 763 | } catch (_) {} 764 | 765 | prng.create = function(plugin) { 766 | var ctx = { 767 | plugin: plugin, 768 | key: null, 769 | seed: null, 770 | time: null, 771 | // number of reseeds so far 772 | reseeds: 0, 773 | // amount of data generated so far 774 | generated: 0 775 | }; 776 | 777 | // create 32 entropy pools (each is a message digest) 778 | var md = plugin.md; 779 | var pools = new Array(32); 780 | for(var i = 0; i < 32; ++i) { 781 | pools[i] = md.create(); 782 | } 783 | ctx.pools = pools; 784 | 785 | // entropy pools are written to cyclically, starting at index 0 786 | ctx.pool = 0; 787 | 788 | /** 789 | * Generates random bytes. The bytes may be generated synchronously or 790 | * asynchronously. Web workers must use the asynchronous interface or 791 | * else the behavior is undefined. 792 | * 793 | * @param count the number of random bytes to generate. 794 | * @param [callback(err, bytes)] called once the operation completes. 795 | * 796 | * @return count random bytes as a string. 797 | */ 798 | ctx.generate = function(count, callback) { 799 | // do synchronously 800 | if(!callback) { 801 | return ctx.generateSync(count); 802 | } 803 | 804 | // simple generator using counter-based CBC 805 | var cipher = ctx.plugin.cipher; 806 | var increment = ctx.plugin.increment; 807 | var formatKey = ctx.plugin.formatKey; 808 | var formatSeed = ctx.plugin.formatSeed; 809 | var b = forge.util.createBuffer(); 810 | 811 | generate(); 812 | 813 | function generate(err) { 814 | if(err) { 815 | return callback(err); 816 | } 817 | 818 | // sufficient bytes generated 819 | if(b.length() >= count) { 820 | return callback(null, b.getBytes(count)); 821 | } 822 | 823 | // if amount of data generated is greater than 1 MiB, trigger reseed 824 | if(ctx.generated >= 1048576) { 825 | // only do reseed at most every 100 ms 826 | var now = +new Date(); 827 | if(ctx.time === null || (now - ctx.time > 100)) { 828 | ctx.key = null; 829 | } 830 | } 831 | 832 | if(ctx.key === null) { 833 | return _reseed(generate); 834 | } 835 | 836 | // generate the random bytes 837 | var bytes = cipher(ctx.key, ctx.seed); 838 | ctx.generated += bytes.length; 839 | b.putBytes(bytes); 840 | 841 | // generate bytes for a new key and seed 842 | ctx.key = formatKey(cipher(ctx.key, increment(ctx.seed))); 843 | ctx.seed = formatSeed(cipher(ctx.key, ctx.seed)); 844 | 845 | forge.util.setImmediate(generate); 846 | } 847 | }; 848 | 849 | /** 850 | * Generates random bytes synchronously. 851 | * 852 | * @param count the number of random bytes to generate. 853 | * 854 | * @return count random bytes as a string. 855 | */ 856 | ctx.generateSync = function(count) { 857 | // simple generator using counter-based CBC 858 | var cipher = ctx.plugin.cipher; 859 | var increment = ctx.plugin.increment; 860 | var formatKey = ctx.plugin.formatKey; 861 | var formatSeed = ctx.plugin.formatSeed; 862 | var b = forge.util.createBuffer(); 863 | while(b.length() < count) { 864 | // if amount of data generated is greater than 1 MiB, trigger reseed 865 | if(ctx.generated >= 1048576) { 866 | // only do reseed at most every 100 ms 867 | var now = +new Date(); 868 | if(ctx.time === null || (now - ctx.time > 100)) { 869 | ctx.key = null; 870 | } 871 | } 872 | 873 | if(ctx.key === null) { 874 | _reseedSync(); 875 | } 876 | 877 | // generate the random bytes 878 | var bytes = cipher(ctx.key, ctx.seed); 879 | ctx.generated += bytes.length; 880 | b.putBytes(bytes); 881 | 882 | // generate bytes for a new key and seed 883 | ctx.key = formatKey(cipher(ctx.key, increment(ctx.seed))); 884 | ctx.seed = formatSeed(cipher(ctx.key, ctx.seed)); 885 | } 886 | 887 | return b.getBytes(count); 888 | }; 889 | 890 | /** 891 | * Private function that asynchronously reseeds a generator. 892 | * 893 | * @param callback(err) called once the operation completes. 894 | */ 895 | function _reseed(callback) { 896 | if(ctx.pools[0].messageLength >= 32) { 897 | _seed(); 898 | return callback(); 899 | } 900 | // not enough seed data... 901 | var needed = (32 - ctx.pools[0].messageLength) << 5; 902 | ctx.seedFile(needed, function(err, bytes) { 903 | if(err) { 904 | return callback(err); 905 | } 906 | ctx.collect(bytes); 907 | _seed(); 908 | callback(); 909 | }); 910 | } 911 | 912 | /** 913 | * Private function that synchronously reseeds a generator. 914 | */ 915 | function _reseedSync() { 916 | if(ctx.pools[0].messageLength >= 32) { 917 | return _seed(); 918 | } 919 | // not enough seed data... 920 | var needed = (32 - ctx.pools[0].messageLength) << 5; 921 | ctx.collect(ctx.seedFileSync(needed)); 922 | _seed(); 923 | } 924 | 925 | /** 926 | * Private function that seeds a generator once enough bytes are available. 927 | */ 928 | function _seed() { 929 | // create a SHA-1 message digest 930 | var md = forge.md.sha1.create(); 931 | 932 | // digest pool 0's entropy and restart it 933 | md.update(ctx.pools[0].digest().getBytes()); 934 | ctx.pools[0].start(); 935 | 936 | // digest the entropy of other pools whose index k meet the 937 | // condition '2^k mod n == 0' where n is the number of reseeds 938 | var k = 1; 939 | for(var i = 1; i < 32; ++i) { 940 | // prevent signed numbers from being used 941 | k = (k === 31) ? 0x80000000 : (k << 2); 942 | if(k % ctx.reseeds === 0) { 943 | md.update(ctx.pools[i].digest().getBytes()); 944 | ctx.pools[i].start(); 945 | } 946 | } 947 | 948 | // get digest for key bytes and iterate again for seed bytes 949 | var keyBytes = md.digest().getBytes(); 950 | md.start(); 951 | md.update(keyBytes); 952 | var seedBytes = md.digest().getBytes(); 953 | 954 | // update 955 | ctx.key = ctx.plugin.formatKey(keyBytes); 956 | ctx.seed = ctx.plugin.formatSeed(seedBytes); 957 | ++ctx.reseeds; 958 | ctx.generated = 0; 959 | ctx.time = +new Date(); 960 | } 961 | 962 | /** 963 | * The built-in default seedFile. This seedFile is used when entropy 964 | * is needed immediately. 965 | * 966 | * @param needed the number of bytes that are needed. 967 | * 968 | * @return the random bytes. 969 | */ 970 | function defaultSeedFile(needed) { 971 | // use window.crypto.getRandomValues strong source of entropy if 972 | // available 973 | var b = forge.util.createBuffer(); 974 | if(typeof window !== 'undefined' && 975 | window.crypto && window.crypto.getRandomValues) { 976 | var entropy = new Uint32Array(needed / 4); 977 | try { 978 | window.crypto.getRandomValues(entropy); 979 | for(var i = 0; i < entropy.length; ++i) { 980 | b.putInt32(entropy[i]); 981 | } 982 | } 983 | catch(e) { 984 | /* Mozilla claims getRandomValues can throw QuotaExceededError, so 985 | ignore errors. In this case, weak entropy will be added, but 986 | hopefully this never happens. 987 | https://developer.mozilla.org/en-US/docs/DOM/window.crypto.getRandomValues 988 | However I've never observed this exception --@evanj */ 989 | } 990 | } 991 | 992 | // be sad and add some weak random data 993 | if(b.length() < needed) { 994 | /* Draws from Park-Miller "minimal standard" 31 bit PRNG, 995 | implemented with David G. Carta's optimization: with 32 bit math 996 | and without division (Public Domain). */ 997 | var hi, lo, next; 998 | var seed = Math.floor(Math.random() * 0xFFFF); 999 | while(b.length() < needed) { 1000 | lo = 16807 * (seed & 0xFFFF); 1001 | hi = 16807 * (seed >> 16); 1002 | lo += (hi & 0x7FFF) << 16; 1003 | lo += hi >> 15; 1004 | lo = (lo & 0x7FFFFFFF) + (lo >> 31); 1005 | seed = lo & 0xFFFFFFFF; 1006 | 1007 | // consume lower 3 bytes of seed 1008 | for(var i = 0; i < 3; ++i) { 1009 | // throw in more pseudo random 1010 | next = seed >>> (i << 3); 1011 | next ^= Math.floor(Math.random() * 0xFF); 1012 | b.putByte(next & 0xFF); 1013 | } 1014 | } 1015 | } 1016 | 1017 | return b.getBytes(); 1018 | } 1019 | // initialize seed file APIs 1020 | if(crypto) { 1021 | // use nodejs async API 1022 | ctx.seedFile = function(needed, callback) { 1023 | crypto.randomBytes(needed, function(err, bytes) { 1024 | if(err) { 1025 | return callback(err); 1026 | } 1027 | callback(null, bytes.toString()); 1028 | }); 1029 | }; 1030 | // use nodejs sync API 1031 | ctx.seedFileSync = function(needed) { 1032 | return crypto.randomBytes(needed).toString(); 1033 | }; 1034 | } 1035 | else { 1036 | ctx.seedFile = function(needed, callback) { 1037 | try { 1038 | callback(null, defaultSeedFile(needed)); 1039 | } 1040 | catch(e) { 1041 | callback(e); 1042 | } 1043 | }; 1044 | ctx.seedFileSync = defaultSeedFile; 1045 | } 1046 | 1047 | /** 1048 | * Adds entropy to a prng ctx's accumulator. 1049 | * 1050 | * @param bytes the bytes of entropy as a string. 1051 | */ 1052 | ctx.collect = function(bytes) { 1053 | // iterate over pools distributing entropy cyclically 1054 | var count = bytes.length; 1055 | for(var i = 0; i < count; ++i) { 1056 | ctx.pools[ctx.pool].update(bytes.substr(i, 1)); 1057 | ctx.pool = (ctx.pool === 31) ? 0 : ctx.pool + 1; 1058 | } 1059 | }; 1060 | 1061 | /** 1062 | * Collects an integer of n bits. 1063 | * 1064 | * @param i the integer entropy. 1065 | * @param n the number of bits in the integer. 1066 | */ 1067 | ctx.collectInt = function(i, n) { 1068 | var bytes = ''; 1069 | for(var x = 0; x < n; x += 8) { 1070 | bytes += String.fromCharCode((i >> x) & 0xFF); 1071 | } 1072 | ctx.collect(bytes); 1073 | }; 1074 | 1075 | /** 1076 | * Registers a Web Worker to receive immediate entropy from the main thread. 1077 | * This method is required until Web Workers can access the native crypto 1078 | * API. This method should be called twice for each created worker, once in 1079 | * the main thread, and once in the worker itself. 1080 | * 1081 | * @param worker the worker to register. 1082 | */ 1083 | ctx.registerWorker = function(worker) { 1084 | // worker receives random bytes 1085 | if(worker === self) { 1086 | ctx.seedFile = function(needed, callback) { 1087 | function listener(e) { 1088 | var data = e.data; 1089 | if(data.forge && data.forge.prng) { 1090 | self.removeEventListener('message', listener); 1091 | callback(data.forge.prng.err, data.forge.prng.bytes); 1092 | } 1093 | } 1094 | self.addEventListener('message', listener); 1095 | self.postMessage({forge: {prng: {needed: needed}}}); 1096 | }; 1097 | } 1098 | // main thread sends random bytes upon request 1099 | else { 1100 | function listener(e) { 1101 | var data = e.data; 1102 | if(data.forge && data.forge.prng) { 1103 | ctx.seedFile(data.forge.prng.needed, function(err, bytes) { 1104 | worker.postMessage({forge: {prng: {err: err, bytes: bytes}}}); 1105 | }); 1106 | } 1107 | } 1108 | // TODO: do we need to remove the event listener when the worker dies? 1109 | worker.addEventListener('message', listener); 1110 | } 1111 | }; 1112 | 1113 | return ctx; 1114 | }; 1115 | 1116 | /** 1117 | * aes._expendKey 1118 | */ 1119 | 1120 | var init = false; // not yet initialized 1121 | var Nb = 4; // number of words comprising the state (AES = 4) 1122 | var sbox; // non-linear substitution table used in key expansion 1123 | var isbox; // inversion of sbox 1124 | var rcon; // round constant word array 1125 | var mix; // mix-columns table 1126 | var imix; // inverse mix-columns table 1127 | 1128 | var initialize = function() { 1129 | init = true; 1130 | 1131 | /* Populate the Rcon table. These are the values given by 1132 | [x^(i-1),{00},{00},{00}] where x^(i-1) are powers of x (and x = 0x02) 1133 | in the field of GF(2^8), where i starts at 1. 1134 | 1135 | rcon[0] = [0x00, 0x00, 0x00, 0x00] 1136 | rcon[1] = [0x01, 0x00, 0x00, 0x00] 2^(1-1) = 2^0 = 1 1137 | rcon[2] = [0x02, 0x00, 0x00, 0x00] 2^(2-1) = 2^1 = 2 1138 | ... 1139 | rcon[9] = [0x1B, 0x00, 0x00, 0x00] 2^(9-1) = 2^8 = 0x1B 1140 | rcon[10] = [0x36, 0x00, 0x00, 0x00] 2^(10-1) = 2^9 = 0x36 1141 | 1142 | We only store the first byte because it is the only one used. 1143 | */ 1144 | rcon = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36]; 1145 | 1146 | // compute xtime table which maps i onto GF(i, 0x02) 1147 | var xtime = new Array(256); 1148 | for(var i = 0; i < 128; ++i) { 1149 | xtime[i] = i << 1; 1150 | xtime[i + 128] = (i + 128) << 1 ^ 0x11B; 1151 | } 1152 | 1153 | // compute all other tables 1154 | sbox = new Array(256); 1155 | isbox = new Array(256); 1156 | mix = new Array(4); 1157 | imix = new Array(4); 1158 | for(var i = 0; i < 4; ++i) { 1159 | mix[i] = new Array(256); 1160 | imix[i] = new Array(256); 1161 | } 1162 | var e = 0, ei = 0, e2, e4, e8, sx, sx2, me, ime; 1163 | for(var i = 0; i < 256; ++i) { 1164 | /* We need to generate the SubBytes() sbox and isbox tables so that 1165 | we can perform byte substitutions. This requires us to traverse 1166 | all of the elements in GF, find their multiplicative inverses, 1167 | and apply to each the following affine transformation: 1168 | 1169 | bi' = bi ^ b(i + 4) mod 8 ^ b(i + 5) mod 8 ^ b(i + 6) mod 8 ^ 1170 | b(i + 7) mod 8 ^ ci 1171 | for 0 <= i < 8, where bi is the ith bit of the byte, and ci is the 1172 | ith bit of a byte c with the value {63} or {01100011}. 1173 | 1174 | It is possible to traverse every possible value in a Galois field 1175 | using what is referred to as a 'generator'. There are many 1176 | generators (128 out of 256): 3,5,6,9,11,82 to name a few. To fully 1177 | traverse GF we iterate 255 times, multiplying by our generator 1178 | each time. 1179 | 1180 | On each iteration we can determine the multiplicative inverse for 1181 | the current element. 1182 | 1183 | Suppose there is an element in GF 'e'. For a given generator 'g', 1184 | e = g^x. The multiplicative inverse of e is g^(255 - x). It turns 1185 | out that if use the inverse of a generator as another generator 1186 | it will produce all of the corresponding multiplicative inverses 1187 | at the same time. For this reason, we choose 5 as our inverse 1188 | generator because it only requires 2 multiplies and 1 add and its 1189 | inverse, 82, requires relatively few operations as well. 1190 | 1191 | In order to apply the affine transformation, the multiplicative 1192 | inverse 'ei' of 'e' can be repeatedly XOR'd (4 times) with a 1193 | bit-cycling of 'ei'. To do this 'ei' is first stored in 's' and 1194 | 'x'. Then 's' is left shifted and the high bit of 's' is made the 1195 | low bit. The resulting value is stored in 's'. Then 'x' is XOR'd 1196 | with 's' and stored in 'x'. On each subsequent iteration the same 1197 | operation is performed. When 4 iterations are complete, 'x' is 1198 | XOR'd with 'c' (0x63) and the transformed value is stored in 'x'. 1199 | For example: 1200 | 1201 | s = 01000001 1202 | x = 01000001 1203 | 1204 | iteration 1: s = 10000010, x ^= s 1205 | iteration 2: s = 00000101, x ^= s 1206 | iteration 3: s = 00001010, x ^= s 1207 | iteration 4: s = 00010100, x ^= s 1208 | x ^= 0x63 1209 | 1210 | This can be done with a loop where s = (s << 1) | (s >> 7). However, 1211 | it can also be done by using a single 16-bit (in this case 32-bit) 1212 | number 'sx'. Since XOR is an associative operation, we can set 'sx' 1213 | to 'ei' and then XOR it with 'sx' left-shifted 1,2,3, and 4 times. 1214 | The most significant bits will flow into the high 8 bit positions 1215 | and be correctly XOR'd with one another. All that remains will be 1216 | to cycle the high 8 bits by XOR'ing them all with the lower 8 bits 1217 | afterwards. 1218 | 1219 | At the same time we're populating sbox and isbox we can precompute 1220 | the multiplication we'll need to do to do MixColumns() later. 1221 | */ 1222 | 1223 | // apply affine transformation 1224 | sx = ei ^ (ei << 1) ^ (ei << 2) ^ (ei << 3) ^ (ei << 4); 1225 | sx = (sx >> 8) ^ (sx & 255) ^ 0x63; 1226 | 1227 | // update tables 1228 | sbox[e] = sx; 1229 | isbox[sx] = e; 1230 | 1231 | /* Mixing columns is done using matrix multiplication. The columns 1232 | that are to be mixed are each a single word in the current state. 1233 | The state has Nb columns (4 columns). Therefore each column is a 1234 | 4 byte word. So to mix the columns in a single column 'c' where 1235 | its rows are r0, r1, r2, and r3, we use the following matrix 1236 | multiplication: 1237 | 1238 | [2 3 1 1]*[r0,c]=[r'0,c] 1239 | [1 2 3 1] [r1,c] [r'1,c] 1240 | [1 1 2 3] [r2,c] [r'2,c] 1241 | [3 1 1 2] [r3,c] [r'3,c] 1242 | 1243 | r0, r1, r2, and r3 are each 1 byte of one of the words in the 1244 | state (a column). To do matrix multiplication for each mixed 1245 | column c' we multiply the corresponding row from the left matrix 1246 | with the corresponding column from the right matrix. In total, we 1247 | get 4 equations: 1248 | 1249 | r0,c' = 2*r0,c + 3*r1,c + 1*r2,c + 1*r3,c 1250 | r1,c' = 1*r0,c + 2*r1,c + 3*r2,c + 1*r3,c 1251 | r2,c' = 1*r0,c + 1*r1,c + 2*r2,c + 3*r3,c 1252 | r3,c' = 3*r0,c + 1*r1,c + 1*r2,c + 2*r3,c 1253 | 1254 | As usual, the multiplication is as previously defined and the 1255 | addition is XOR. In order to optimize mixing columns we can store 1256 | the multiplication results in tables. If you think of the whole 1257 | column as a word (it might help to visualize by mentally rotating 1258 | the equations above by counterclockwise 90 degrees) then you can 1259 | see that it would be useful to map the multiplications performed on 1260 | each byte (r0, r1, r2, r3) onto a word as well. For instance, we 1261 | could map 2*r0,1*r0,1*r0,3*r0 onto a word by storing 2*r0 in the 1262 | highest 8 bits and 3*r0 in the lowest 8 bits (with the other two 1263 | respectively in the middle). This means that a table can be 1264 | constructed that uses r0 as an index to the word. We can do the 1265 | same with r1, r2, and r3, creating a total of 4 tables. 1266 | 1267 | To construct a full c', we can just look up each byte of c in 1268 | their respective tables and XOR the results together. 1269 | 1270 | Also, to build each table we only have to calculate the word 1271 | for 2,1,1,3 for every byte ... which we can do on each iteration 1272 | of this loop since we will iterate over every byte. After we have 1273 | calculated 2,1,1,3 we can get the results for the other tables 1274 | by cycling the byte at the end to the beginning. For instance 1275 | we can take the result of table 2,1,1,3 and produce table 3,2,1,1 1276 | by moving the right most byte to the left most position just like 1277 | how you can imagine the 3 moved out of 2,1,1,3 and to the front 1278 | to produce 3,2,1,1. 1279 | 1280 | There is another optimization in that the same multiples of 1281 | the current element we need in order to advance our generator 1282 | to the next iteration can be reused in performing the 2,1,1,3 1283 | calculation. We also calculate the inverse mix column tables, 1284 | with e,9,d,b being the inverse of 2,1,1,3. 1285 | 1286 | When we're done, and we need to actually mix columns, the first 1287 | byte of each state word should be put through mix[0] (2,1,1,3), 1288 | the second through mix[1] (3,2,1,1) and so forth. Then they should 1289 | be XOR'd together to produce the fully mixed column. 1290 | */ 1291 | 1292 | // calculate mix and imix table values 1293 | sx2 = xtime[sx]; 1294 | e2 = xtime[e]; 1295 | e4 = xtime[e2]; 1296 | e8 = xtime[e4]; 1297 | me = 1298 | (sx2 << 24) ^ // 2 1299 | (sx << 16) ^ // 1 1300 | (sx << 8) ^ // 1 1301 | (sx ^ sx2); // 3 1302 | ime = 1303 | (e2 ^ e4 ^ e8) << 24 ^ // E (14) 1304 | (e ^ e8) << 16 ^ // 9 1305 | (e ^ e4 ^ e8) << 8 ^ // D (13) 1306 | (e ^ e2 ^ e8); // B (11) 1307 | // produce each of the mix tables by rotating the 2,1,1,3 value 1308 | for(var n = 0; n < 4; ++n) { 1309 | mix[n][e] = me; 1310 | imix[n][sx] = ime; 1311 | // cycle the right most byte to the left most position 1312 | // ie: 2,1,1,3 becomes 3,2,1,1 1313 | me = me << 24 | me >>> 8; 1314 | ime = ime << 24 | ime >>> 8; 1315 | } 1316 | 1317 | // get next element and inverse 1318 | if(e === 0) { 1319 | // 1 is the inverse of 1 1320 | e = ei = 1; 1321 | } 1322 | else { 1323 | // e = 2e + 2*2*2*(10e)) = multiply e by 82 (chosen generator) 1324 | // ei = ei + 2*2*ei = multiply ei by 5 (inverse generator) 1325 | e = e2 ^ xtime[xtime[xtime[e2 ^ e8]]]; 1326 | ei ^= xtime[xtime[ei]]; 1327 | } 1328 | } 1329 | }; 1330 | 1331 | /** 1332 | * Generates a key schedule using the AES key expansion algorithm. 1333 | * 1334 | * The AES algorithm takes the Cipher Key, K, and performs a Key Expansion 1335 | * routine to generate a key schedule. The Key Expansion generates a total 1336 | * of Nb*(Nr + 1) words: the algorithm requires an initial set of Nb words, 1337 | * and each of the Nr rounds requires Nb words of key data. The resulting 1338 | * key schedule consists of a linear array of 4-byte words, denoted [wi ], 1339 | * with i in the range 0 ≤ i < Nb(Nr + 1). 1340 | * 1341 | * KeyExpansion(byte key[4*Nk], word w[Nb*(Nr+1)], Nk) 1342 | * AES-128 (Nb=4, Nk=4, Nr=10) 1343 | * AES-192 (Nb=4, Nk=6, Nr=12) 1344 | * AES-256 (Nb=4, Nk=8, Nr=14) 1345 | * Note: Nr=Nk+6. 1346 | * 1347 | * Nb is the number of columns (32-bit words) comprising the State (or 1348 | * number of bytes in a block). For AES, Nb=4. 1349 | * 1350 | * @param key the key to schedule (as an array of 32-bit words). 1351 | * @param decrypt true to modify the key schedule to decrypt, false not to. 1352 | * 1353 | * @return the generated key schedule. 1354 | */ 1355 | var expandKey = function(key, decrypt) { 1356 | // copy the key's words to initialize the key schedule 1357 | var w = key.slice(0); 1358 | 1359 | /* RotWord() will rotate a word, moving the first byte to the last 1360 | byte's position (shifting the other bytes left). 1361 | 1362 | We will be getting the value of Rcon at i / Nk. 'i' will iterate 1363 | from Nk to (Nb * Nr+1). Nk = 4 (4 byte key), Nb = 4 (4 words in 1364 | a block), Nr = Nk + 6 (10). Therefore 'i' will iterate from 1365 | 4 to 44 (exclusive). Each time we iterate 4 times, i / Nk will 1366 | increase by 1. We use a counter iNk to keep track of this. 1367 | */ 1368 | 1369 | // go through the rounds expanding the key 1370 | var temp, iNk = 1; 1371 | var Nk = w.length; 1372 | var Nr1 = Nk + 6 + 1; 1373 | var end = Nb * Nr1; 1374 | for(var i = Nk; i < end; ++i) { 1375 | temp = w[i - 1]; 1376 | if(i % Nk === 0) { 1377 | // temp = SubWord(RotWord(temp)) ^ Rcon[i / Nk] 1378 | temp = 1379 | sbox[temp >>> 16 & 255] << 24 ^ 1380 | sbox[temp >>> 8 & 255] << 16 ^ 1381 | sbox[temp & 255] << 8 ^ 1382 | sbox[temp >>> 24] ^ (rcon[iNk] << 24); 1383 | iNk++; 1384 | } 1385 | else if(Nk > 6 && (i % Nk == 4)) { 1386 | // temp = SubWord(temp) 1387 | temp = 1388 | sbox[temp >>> 24] << 24 ^ 1389 | sbox[temp >>> 16 & 255] << 16 ^ 1390 | sbox[temp >>> 8 & 255] << 8 ^ 1391 | sbox[temp & 255]; 1392 | } 1393 | w[i] = w[i - Nk] ^ temp; 1394 | } 1395 | 1396 | /* When we are updating a cipher block we always use the code path for 1397 | encryption whether we are decrypting or not (to shorten code and 1398 | simplify the generation of look up tables). However, because there 1399 | are differences in the decryption algorithm, other than just swapping 1400 | in different look up tables, we must transform our key schedule to 1401 | account for these changes: 1402 | 1403 | 1. The decryption algorithm gets its key rounds in reverse order. 1404 | 2. The decryption algorithm adds the round key before mixing columns 1405 | instead of afterwards. 1406 | 1407 | We don't need to modify our key schedule to handle the first case, 1408 | we can just traverse the key schedule in reverse order when decrypting. 1409 | 1410 | The second case requires a little work. 1411 | 1412 | The tables we built for performing rounds will take an input and then 1413 | perform SubBytes() and MixColumns() or, for the decrypt version, 1414 | InvSubBytes() and InvMixColumns(). But the decrypt algorithm requires 1415 | us to AddRoundKey() before InvMixColumns(). This means we'll need to 1416 | apply some transformations to the round key to inverse-mix its columns 1417 | so they'll be correct for moving AddRoundKey() to after the state has 1418 | had its columns inverse-mixed. 1419 | 1420 | To inverse-mix the columns of the state when we're decrypting we use a 1421 | lookup table that will apply InvSubBytes() and InvMixColumns() at the 1422 | same time. However, the round key's bytes are not inverse-substituted 1423 | in the decryption algorithm. To get around this problem, we can first 1424 | substitute the bytes in the round key so that when we apply the 1425 | transformation via the InvSubBytes()+InvMixColumns() table, it will 1426 | undo our substitution leaving us with the original value that we 1427 | want -- and then inverse-mix that value. 1428 | 1429 | This change will correctly alter our key schedule so that we can XOR 1430 | each round key with our already transformed decryption state. This 1431 | allows us to use the same code path as the encryption algorithm. 1432 | 1433 | We make one more change to the decryption key. Since the decryption 1434 | algorithm runs in reverse from the encryption algorithm, we reverse 1435 | the order of the round keys to avoid having to iterate over the key 1436 | schedule backwards when running the encryption algorithm later in 1437 | decryption mode. In addition to reversing the order of the round keys, 1438 | we also swap each round key's 2nd and 4th rows. See the comments 1439 | section where rounds are performed for more details about why this is 1440 | done. These changes are done inline with the other substitution 1441 | described above. 1442 | */ 1443 | if(decrypt) { 1444 | var tmp; 1445 | var m0 = imix[0]; 1446 | var m1 = imix[1]; 1447 | var m2 = imix[2]; 1448 | var m3 = imix[3]; 1449 | var wnew = w.slice(0); 1450 | var end = w.length; 1451 | for(var i = 0, wi = end - Nb; i < end; i += Nb, wi -= Nb) { 1452 | // do not sub the first or last round key (round keys are Nb 1453 | // words) as no column mixing is performed before they are added, 1454 | // but do change the key order 1455 | if(i === 0 || i === (end - Nb)) { 1456 | wnew[i] = w[wi]; 1457 | wnew[i + 1] = w[wi + 3]; 1458 | wnew[i + 2] = w[wi + 2]; 1459 | wnew[i + 3] = w[wi + 1]; 1460 | } 1461 | else { 1462 | // substitute each round key byte because the inverse-mix 1463 | // table will inverse-substitute it (effectively cancel the 1464 | // substitution because round key bytes aren't sub'd in 1465 | // decryption mode) and swap indexes 3 and 1 1466 | for(var n = 0; n < Nb; ++n) { 1467 | tmp = w[wi + n]; 1468 | wnew[i + (3&-n)] = 1469 | m0[sbox[tmp >>> 24]] ^ 1470 | m1[sbox[tmp >>> 16 & 255]] ^ 1471 | m2[sbox[tmp >>> 8 & 255]] ^ 1472 | m3[sbox[tmp & 255]]; 1473 | } 1474 | } 1475 | } 1476 | w = wnew; 1477 | } 1478 | 1479 | return w; 1480 | }; 1481 | 1482 | 1483 | forge.aes._expandKey = function(key, decrypt) { 1484 | if(!init) { 1485 | initialize(); 1486 | } 1487 | return expandKey(key, decrypt); 1488 | }; 1489 | 1490 | /** 1491 | * aes._updateBlock 1492 | */ 1493 | 1494 | var _updateBlock = function(w, input, output, decrypt) { 1495 | /* 1496 | Cipher(byte in[4*Nb], byte out[4*Nb], word w[Nb*(Nr+1)]) 1497 | begin 1498 | byte state[4,Nb] 1499 | state = in 1500 | AddRoundKey(state, w[0, Nb-1]) 1501 | for round = 1 step 1 to Nr–1 1502 | SubBytes(state) 1503 | ShiftRows(state) 1504 | MixColumns(state) 1505 | AddRoundKey(state, w[round*Nb, (round+1)*Nb-1]) 1506 | end for 1507 | SubBytes(state) 1508 | ShiftRows(state) 1509 | AddRoundKey(state, w[Nr*Nb, (Nr+1)*Nb-1]) 1510 | out = state 1511 | end 1512 | 1513 | InvCipher(byte in[4*Nb], byte out[4*Nb], word w[Nb*(Nr+1)]) 1514 | begin 1515 | byte state[4,Nb] 1516 | state = in 1517 | AddRoundKey(state, w[Nr*Nb, (Nr+1)*Nb-1]) 1518 | for round = Nr-1 step -1 downto 1 1519 | InvShiftRows(state) 1520 | InvSubBytes(state) 1521 | AddRoundKey(state, w[round*Nb, (round+1)*Nb-1]) 1522 | InvMixColumns(state) 1523 | end for 1524 | InvShiftRows(state) 1525 | InvSubBytes(state) 1526 | AddRoundKey(state, w[0, Nb-1]) 1527 | out = state 1528 | end 1529 | */ 1530 | 1531 | // Encrypt: AddRoundKey(state, w[0, Nb-1]) 1532 | // Decrypt: AddRoundKey(state, w[Nr*Nb, (Nr+1)*Nb-1]) 1533 | var Nr = w.length / 4 - 1; 1534 | var m0, m1, m2, m3, sub; 1535 | if(decrypt) { 1536 | m0 = imix[0]; 1537 | m1 = imix[1]; 1538 | m2 = imix[2]; 1539 | m3 = imix[3]; 1540 | sub = isbox; 1541 | } 1542 | else { 1543 | m0 = mix[0]; 1544 | m1 = mix[1]; 1545 | m2 = mix[2]; 1546 | m3 = mix[3]; 1547 | sub = sbox; 1548 | } 1549 | var a, b, c, d, a2, b2, c2; 1550 | a = input[0] ^ w[0]; 1551 | b = input[decrypt ? 3 : 1] ^ w[1]; 1552 | c = input[2] ^ w[2]; 1553 | d = input[decrypt ? 1 : 3] ^ w[3]; 1554 | var i = 3; 1555 | 1556 | /* In order to share code we follow the encryption algorithm when both 1557 | encrypting and decrypting. To account for the changes required in the 1558 | decryption algorithm, we use different lookup tables when decrypting 1559 | and use a modified key schedule to account for the difference in the 1560 | order of transformations applied when performing rounds. We also get 1561 | key rounds in reverse order (relative to encryption). */ 1562 | for(var round = 1; round < Nr; ++round) { 1563 | /* As described above, we'll be using table lookups to perform the 1564 | column mixing. Each column is stored as a word in the state (the 1565 | array 'input' has one column as a word at each index). In order to 1566 | mix a column, we perform these transformations on each row in c, 1567 | which is 1 byte in each word. The new column for c0 is c'0: 1568 | 1569 | m0 m1 m2 m3 1570 | r0,c'0 = 2*r0,c0 + 3*r1,c0 + 1*r2,c0 + 1*r3,c0 1571 | r1,c'0 = 1*r0,c0 + 2*r1,c0 + 3*r2,c0 + 1*r3,c0 1572 | r2,c'0 = 1*r0,c0 + 1*r1,c0 + 2*r2,c0 + 3*r3,c0 1573 | r3,c'0 = 3*r0,c0 + 1*r1,c0 + 1*r2,c0 + 2*r3,c0 1574 | 1575 | So using mix tables where c0 is a word with r0 being its upper 1576 | 8 bits and r3 being its lower 8 bits: 1577 | 1578 | m0[c0 >> 24] will yield this word: [2*r0,1*r0,1*r0,3*r0] 1579 | ... 1580 | m3[c0 & 255] will yield this word: [1*r3,1*r3,3*r3,2*r3] 1581 | 1582 | Therefore to mix the columns in each word in the state we 1583 | do the following (& 255 omitted for brevity): 1584 | c'0,r0 = m0[c0 >> 24] ^ m1[c1 >> 16] ^ m2[c2 >> 8] ^ m3[c3] 1585 | c'0,r1 = m0[c0 >> 24] ^ m1[c1 >> 16] ^ m2[c2 >> 8] ^ m3[c3] 1586 | c'0,r2 = m0[c0 >> 24] ^ m1[c1 >> 16] ^ m2[c2 >> 8] ^ m3[c3] 1587 | c'0,r3 = m0[c0 >> 24] ^ m1[c1 >> 16] ^ m2[c2 >> 8] ^ m3[c3] 1588 | 1589 | However, before mixing, the algorithm requires us to perform 1590 | ShiftRows(). The ShiftRows() transformation cyclically shifts the 1591 | last 3 rows of the state over different offsets. The first row 1592 | (r = 0) is not shifted. 1593 | 1594 | s'_r,c = s_r,(c + shift(r, Nb) mod Nb 1595 | for 0 < r < 4 and 0 <= c < Nb and 1596 | shift(1, 4) = 1 1597 | shift(2, 4) = 2 1598 | shift(3, 4) = 3. 1599 | 1600 | This causes the first byte in r = 1 to be moved to the end of 1601 | the row, the first 2 bytes in r = 2 to be moved to the end of 1602 | the row, the first 3 bytes in r = 3 to be moved to the end of 1603 | the row: 1604 | 1605 | r1: [c0 c1 c2 c3] => [c1 c2 c3 c0] 1606 | r2: [c0 c1 c2 c3] [c2 c3 c0 c1] 1607 | r3: [c0 c1 c2 c3] [c3 c0 c1 c2] 1608 | 1609 | We can make these substitutions inline with our column mixing to 1610 | generate an updated set of equations to produce each word in the 1611 | state (note the columns have changed positions): 1612 | 1613 | c0 c1 c2 c3 => c0 c1 c2 c3 1614 | c0 c1 c2 c3 c1 c2 c3 c0 (cycled 1 byte) 1615 | c0 c1 c2 c3 c2 c3 c0 c1 (cycled 2 bytes) 1616 | c0 c1 c2 c3 c3 c0 c1 c2 (cycled 3 bytes) 1617 | 1618 | Therefore: 1619 | 1620 | c'0 = 2*r0,c0 + 3*r1,c1 + 1*r2,c2 + 1*r3,c3 1621 | c'0 = 1*r0,c0 + 2*r1,c1 + 3*r2,c2 + 1*r3,c3 1622 | c'0 = 1*r0,c0 + 1*r1,c1 + 2*r2,c2 + 3*r3,c3 1623 | c'0 = 3*r0,c0 + 1*r1,c1 + 1*r2,c2 + 2*r3,c3 1624 | 1625 | c'1 = 2*r0,c1 + 3*r1,c2 + 1*r2,c3 + 1*r3,c0 1626 | c'1 = 1*r0,c1 + 2*r1,c2 + 3*r2,c3 + 1*r3,c0 1627 | c'1 = 1*r0,c1 + 1*r1,c2 + 2*r2,c3 + 3*r3,c0 1628 | c'1 = 3*r0,c1 + 1*r1,c2 + 1*r2,c3 + 2*r3,c0 1629 | 1630 | ... and so forth for c'2 and c'3. The important distinction is 1631 | that the columns are cycling, with c0 being used with the m0 1632 | map when calculating c0, but c1 being used with the m0 map when 1633 | calculating c1 ... and so forth. 1634 | 1635 | When performing the inverse we transform the mirror image and 1636 | skip the bottom row, instead of the top one, and move upwards: 1637 | 1638 | c3 c2 c1 c0 => c0 c3 c2 c1 (cycled 3 bytes) *same as encryption 1639 | c3 c2 c1 c0 c1 c0 c3 c2 (cycled 2 bytes) 1640 | c3 c2 c1 c0 c2 c1 c0 c3 (cycled 1 byte) *same as encryption 1641 | c3 c2 c1 c0 c3 c2 c1 c0 1642 | 1643 | If you compare the resulting matrices for ShiftRows()+MixColumns() 1644 | and for InvShiftRows()+InvMixColumns() the 2nd and 4th columns are 1645 | different (in encrypt mode vs. decrypt mode). So in order to use 1646 | the same code to handle both encryption and decryption, we will 1647 | need to do some mapping. 1648 | 1649 | If in encryption mode we let a=c0, b=c1, c=c2, d=c3, and r be 1650 | a row number in the state, then the resulting matrix in encryption 1651 | mode for applying the above transformations would be: 1652 | 1653 | r1: a b c d 1654 | r2: b c d a 1655 | r3: c d a b 1656 | r4: d a b c 1657 | 1658 | If we did the same in decryption mode we would get: 1659 | 1660 | r1: a d c b 1661 | r2: b a d c 1662 | r3: c b a d 1663 | r4: d c b a 1664 | 1665 | If instead we swap d and b (set b=c3 and d=c1), then we get: 1666 | 1667 | r1: a b c d 1668 | r2: d a b c 1669 | r3: c d a b 1670 | r4: b c d a 1671 | 1672 | Now the 1st and 3rd rows are the same as the encryption matrix. All 1673 | we need to do then to make the mapping exactly the same is to swap 1674 | the 2nd and 4th rows when in decryption mode. To do this without 1675 | having to do it on each iteration, we swapped the 2nd and 4th rows 1676 | in the decryption key schedule. We also have to do the swap above 1677 | when we first pull in the input and when we set the final output. */ 1678 | a2 = 1679 | m0[a >>> 24] ^ 1680 | m1[b >>> 16 & 255] ^ 1681 | m2[c >>> 8 & 255] ^ 1682 | m3[d & 255] ^ w[++i]; 1683 | b2 = 1684 | m0[b >>> 24] ^ 1685 | m1[c >>> 16 & 255] ^ 1686 | m2[d >>> 8 & 255] ^ 1687 | m3[a & 255] ^ w[++i]; 1688 | c2 = 1689 | m0[c >>> 24] ^ 1690 | m1[d >>> 16 & 255] ^ 1691 | m2[a >>> 8 & 255] ^ 1692 | m3[b & 255] ^ w[++i]; 1693 | d = 1694 | m0[d >>> 24] ^ 1695 | m1[a >>> 16 & 255] ^ 1696 | m2[b >>> 8 & 255] ^ 1697 | m3[c & 255] ^ w[++i]; 1698 | a = a2; 1699 | b = b2; 1700 | c = c2; 1701 | } 1702 | 1703 | /* 1704 | Encrypt: 1705 | SubBytes(state) 1706 | ShiftRows(state) 1707 | AddRoundKey(state, w[Nr*Nb, (Nr+1)*Nb-1]) 1708 | 1709 | Decrypt: 1710 | InvShiftRows(state) 1711 | InvSubBytes(state) 1712 | AddRoundKey(state, w[0, Nb-1]) 1713 | */ 1714 | // Note: rows are shifted inline 1715 | output[0] = 1716 | (sub[a >>> 24] << 24) ^ 1717 | (sub[b >>> 16 & 255] << 16) ^ 1718 | (sub[c >>> 8 & 255] << 8) ^ 1719 | (sub[d & 255]) ^ w[++i]; 1720 | output[decrypt ? 3 : 1] = 1721 | (sub[b >>> 24] << 24) ^ 1722 | (sub[c >>> 16 & 255] << 16) ^ 1723 | (sub[d >>> 8 & 255] << 8) ^ 1724 | (sub[a & 255]) ^ w[++i]; 1725 | output[2] = 1726 | (sub[c >>> 24] << 24) ^ 1727 | (sub[d >>> 16 & 255] << 16) ^ 1728 | (sub[a >>> 8 & 255] << 8) ^ 1729 | (sub[b & 255]) ^ w[++i]; 1730 | output[decrypt ? 1 : 3] = 1731 | (sub[d >>> 24] << 24) ^ 1732 | (sub[a >>> 16 & 255] << 16) ^ 1733 | (sub[b >>> 8 & 255] << 8) ^ 1734 | (sub[c & 255]) ^ w[++i]; 1735 | }; 1736 | 1737 | 1738 | forge.aes._updateBlock = _updateBlock; 1739 | 1740 | /** 1741 | * random.generate 1742 | */ 1743 | 1744 | // the default prng plugin, uses AES-128 1745 | var prng_aes = {}; 1746 | var _prng_aes_output = new Array(4); 1747 | var _prng_aes_buffer = forge.util.createBuffer(); 1748 | prng_aes.formatKey = function(key) { 1749 | // convert the key into 32-bit integers 1750 | var tmp = forge.util.createBuffer(key); 1751 | key = new Array(4); 1752 | key[0] = tmp.getInt32(); 1753 | key[1] = tmp.getInt32(); 1754 | key[2] = tmp.getInt32(); 1755 | key[3] = tmp.getInt32(); 1756 | 1757 | // return the expanded key 1758 | return forge.aes._expandKey(key, false); 1759 | }; 1760 | prng_aes.formatSeed = function(seed) { 1761 | // convert seed into 32-bit integers 1762 | var tmp = forge.util.createBuffer(seed); 1763 | seed = new Array(4); 1764 | seed[0] = tmp.getInt32(); 1765 | seed[1] = tmp.getInt32(); 1766 | seed[2] = tmp.getInt32(); 1767 | seed[3] = tmp.getInt32(); 1768 | return seed; 1769 | }; 1770 | prng_aes.cipher = function(key, seed) { 1771 | forge.aes._updateBlock(key, seed, _prng_aes_output, false); 1772 | _prng_aes_buffer.putInt32(_prng_aes_output[0]); 1773 | _prng_aes_buffer.putInt32(_prng_aes_output[1]); 1774 | _prng_aes_buffer.putInt32(_prng_aes_output[2]); 1775 | _prng_aes_buffer.putInt32(_prng_aes_output[3]); 1776 | return _prng_aes_buffer.getBytes(); 1777 | }; 1778 | prng_aes.increment = function(seed) { 1779 | // FIXME: do we care about carry or signed issues? 1780 | ++seed[3]; 1781 | return seed; 1782 | }; 1783 | prng_aes.md = forge.md.sha1; 1784 | 1785 | // create default prng context 1786 | var _ctx = forge.prng.create(prng_aes); 1787 | 1788 | // add other sources of entropy only if window.crypto.getRandomValues is not 1789 | // available -- otherwise this source will be automatically used by the prng 1790 | 1791 | if (typeof window == 'undefined' || !window.crypto || !window.crypto.getRandomValues) { 1792 | // if this is a web worker, do not use weak entropy, instead register to 1793 | // receive strong entropy asynchronously from the main thread 1794 | if(typeof window === 'undefined' || window.document === undefined) { 1795 | // FIXME: 1796 | } 1797 | 1798 | // get load time entropy 1799 | _ctx.collectInt(+new Date(), 32); 1800 | 1801 | // add some entropy from navigator object 1802 | if(typeof(navigator) !== 'undefined') { 1803 | var _navBytes = ''; 1804 | for(var key in navigator) { 1805 | try { 1806 | if(typeof(navigator[key]) == 'string') { 1807 | _navBytes += navigator[key]; 1808 | } 1809 | } 1810 | catch(e) { 1811 | /* Some navigator keys might not be accessible, e.g. the geolocation 1812 | attribute throws an exception if touched in Mozilla chrome:// 1813 | context. 1814 | 1815 | Silently ignore this and just don't use this as a source of 1816 | entropy. */ 1817 | } 1818 | } 1819 | _ctx.collect(_navBytes); 1820 | _navBytes = null; 1821 | } 1822 | } 1823 | 1824 | forge.random = _ctx; 1825 | 1826 | /** 1827 | * random.getBytes 1828 | */ 1829 | 1830 | forge.random.getBytes = function(count, callback) { 1831 | return forge.random.generate(count, callback); 1832 | }; 1833 | 1834 | /** 1835 | * pki 1836 | * @author Dave Longley 1837 | * @author Stefan Siegl 1838 | * 1839 | * Copyright (c) 2010-2013 Digital Bazaar, Inc. 1840 | * Copyright (c) 2012 Stefan Siegl 1841 | */ 1842 | 1843 | /** 1844 | * pki.rsa.createKeyPairGenerationState 1845 | */ 1846 | 1847 | forge.pki.rsa.createKeyPairGenerationState = function(bits, e) { 1848 | // set default bits 1849 | if(typeof(bits) === 'string') { 1850 | bits = parseInt(bits, 10); 1851 | } 1852 | bits = bits || 1024; 1853 | 1854 | // create prng with api that matches BigInteger secure random 1855 | var rng = { 1856 | // x is an array to fill with bytes 1857 | nextBytes: function(x) { 1858 | var b = forge.random.getBytes(x.length); 1859 | for(var i = 0; i < x.length; ++i) { 1860 | x[i] = b.charCodeAt(i); 1861 | } 1862 | } 1863 | }; 1864 | 1865 | var rval = { 1866 | state: 0, 1867 | bits: bits, 1868 | rng: rng, 1869 | eInt: e || 65537, 1870 | e: new BigInteger(null), 1871 | p: null, 1872 | q: null, 1873 | qBits: bits >> 1, 1874 | pBits: bits - (bits >> 1), 1875 | pqState: 0, 1876 | num: null, 1877 | keys: null 1878 | }; 1879 | rval.e.fromInt(rval.eInt); 1880 | 1881 | return rval; 1882 | }; 1883 | 1884 | /** 1885 | * jsbn.BigInteger 1886 | */ 1887 | 1888 | var dbits; 1889 | 1890 | // JavaScript engine analysis 1891 | var canary = 0xdeadbeefcafe; 1892 | var j_lm = ((canary&0xffffff)==0xefcafe); 1893 | 1894 | // (public) Constructor 1895 | function BigInteger(a,b,c) { 1896 | this.data = []; 1897 | if(a != null) 1898 | if("number" == typeof a) this.fromNumber(a,b,c); 1899 | else if(b == null && "string" != typeof a) this.fromString(a,256); 1900 | else this.fromString(a,b); 1901 | } 1902 | 1903 | // return new, unset BigInteger 1904 | function nbi() { return new BigInteger(null); } 1905 | 1906 | // am: Compute w_j += (x*this_i), propagate carries, 1907 | // c is initial carry, returns final carry. 1908 | // c < 3*dvalue, x < 2*dvalue, this_i < dvalue 1909 | // We need to select the fastest one that works in this environment. 1910 | 1911 | // am1: use a single mult and divide to get the high bits, 1912 | // max digit bits should be 26 because 1913 | // max internal value = 2*dvalue^2-2*dvalue (< 2^53) 1914 | function am1(i,x,w,j,c,n) { 1915 | while(--n >= 0) { 1916 | var v = x*this.data[i++]+w.data[j]+c; 1917 | c = Math.floor(v/0x4000000); 1918 | w.data[j++] = v&0x3ffffff; 1919 | } 1920 | return c; 1921 | } 1922 | // am2 avoids a big mult-and-extract completely. 1923 | // Max digit bits should be <= 30 because we do bitwise ops 1924 | // on values up to 2*hdvalue^2-hdvalue-1 (< 2^31) 1925 | function am2(i,x,w,j,c,n) { 1926 | var xl = x&0x7fff, xh = x>>15; 1927 | while(--n >= 0) { 1928 | var l = this.data[i]&0x7fff; 1929 | var h = this.data[i++]>>15; 1930 | var m = xh*l+h*xl; 1931 | l = xl*l+((m&0x7fff)<<15)+w.data[j]+(c&0x3fffffff); 1932 | c = (l>>>30)+(m>>>15)+xh*h+(c>>>30); 1933 | w.data[j++] = l&0x3fffffff; 1934 | } 1935 | return c; 1936 | } 1937 | // Alternately, set max digit bits to 28 since some 1938 | // browsers slow down when dealing with 32-bit numbers. 1939 | function am3(i,x,w,j,c,n) { 1940 | var xl = x&0x3fff, xh = x>>14; 1941 | while(--n >= 0) { 1942 | var l = this.data[i]&0x3fff; 1943 | var h = this.data[i++]>>14; 1944 | var m = xh*l+h*xl; 1945 | l = xl*l+((m&0x3fff)<<14)+w.data[j]+c; 1946 | c = (l>>28)+(m>>14)+xh*h; 1947 | w.data[j++] = l&0xfffffff; 1948 | } 1949 | return c; 1950 | } 1951 | 1952 | // node.js (no browser) 1953 | if(typeof(navigator) === 'undefined') 1954 | { 1955 | BigInteger.prototype.am = am3; 1956 | dbits = 28; 1957 | } 1958 | else if(j_lm && (navigator.appName == "Microsoft Internet Explorer")) { 1959 | BigInteger.prototype.am = am2; 1960 | dbits = 30; 1961 | } 1962 | else if(j_lm && (navigator.appName != "Netscape")) { 1963 | BigInteger.prototype.am = am1; 1964 | dbits = 26; 1965 | } 1966 | else { // Mozilla/Netscape seems to prefer am3 1967 | BigInteger.prototype.am = am3; 1968 | dbits = 28; 1969 | } 1970 | 1971 | BigInteger.prototype.DB = dbits; 1972 | BigInteger.prototype.DM = ((1<= 0; --i) r.data[i] = this.data[i]; 2000 | r.t = this.t; 2001 | r.s = this.s; 2002 | } 2003 | 2004 | // (protected) set from integer value x, -DV <= x < DV 2005 | function bnpFromInt(x) { 2006 | this.t = 1; 2007 | this.s = (x<0)?-1:0; 2008 | if(x > 0) this.data[0] = x; 2009 | else if(x < -1) this.data[0] = x+DV; 2010 | else this.t = 0; 2011 | } 2012 | 2013 | // return bigint initialized to value 2014 | function nbv(i) { var r = nbi(); r.fromInt(i); return r; } 2015 | 2016 | // (protected) set from string and radix 2017 | function bnpFromString(s,b) { 2018 | var k; 2019 | if(b == 16) k = 4; 2020 | else if(b == 8) k = 3; 2021 | else if(b == 256) k = 8; // byte array 2022 | else if(b == 2) k = 1; 2023 | else if(b == 32) k = 5; 2024 | else if(b == 4) k = 2; 2025 | else { this.fromRadix(s,b); return; } 2026 | this.t = 0; 2027 | this.s = 0; 2028 | var i = s.length, mi = false, sh = 0; 2029 | while(--i >= 0) { 2030 | var x = (k==8)?s[i]&0xff:intAt(s,i); 2031 | if(x < 0) { 2032 | if(s.charAt(i) == "-") mi = true; 2033 | continue; 2034 | } 2035 | mi = false; 2036 | if(sh == 0) 2037 | this.data[this.t++] = x; 2038 | else if(sh+k > this.DB) { 2039 | this.data[this.t-1] |= (x&((1<<(this.DB-sh))-1))<>(this.DB-sh)); 2041 | } 2042 | else 2043 | this.data[this.t-1] |= x<= this.DB) sh -= this.DB; 2046 | } 2047 | if(k == 8 && (s[0]&0x80) != 0) { 2048 | this.s = -1; 2049 | if(sh > 0) this.data[this.t-1] |= ((1<<(this.DB-sh))-1)< 0 && this.data[this.t-1] == c) --this.t; 2059 | } 2060 | 2061 | // (public) return string representation in given radix 2062 | function bnToString(b) { 2063 | if(this.s < 0) return "-"+this.negate().toString(b); 2064 | var k; 2065 | if(b == 16) k = 4; 2066 | else if(b == 8) k = 3; 2067 | else if(b == 2) k = 1; 2068 | else if(b == 32) k = 5; 2069 | else if(b == 4) k = 2; 2070 | else return this.toRadix(b); 2071 | var km = (1< 0) { 2074 | if(p < this.DB && (d = this.data[i]>>p) > 0) { m = true; r = int2char(d); } 2075 | while(i >= 0) { 2076 | if(p < k) { 2077 | d = (this.data[i]&((1<>(p+=this.DB-k); 2079 | } 2080 | else { 2081 | d = (this.data[i]>>(p-=k))&km; 2082 | if(p <= 0) { p += this.DB; --i; } 2083 | } 2084 | if(d > 0) m = true; 2085 | if(m) r += int2char(d); 2086 | } 2087 | } 2088 | return m?r:"0"; 2089 | } 2090 | 2091 | // (public) -this 2092 | function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; } 2093 | 2094 | // (public) |this| 2095 | function bnAbs() { return (this.s<0)?this.negate():this; } 2096 | 2097 | // (public) return + if this > a, - if this < a, 0 if equal 2098 | function bnCompareTo(a) { 2099 | var r = this.s-a.s; 2100 | if(r != 0) return r; 2101 | var i = this.t; 2102 | r = i-a.t; 2103 | if(r != 0) return (this.s<0)?-r:r; 2104 | while(--i >= 0) if((r=this.data[i]-a.data[i]) != 0) return r; 2105 | return 0; 2106 | } 2107 | 2108 | // returns bit length of the integer x 2109 | function nbits(x) { 2110 | var r = 1, t; 2111 | if((t=x>>>16) != 0) { x = t; r += 16; } 2112 | if((t=x>>8) != 0) { x = t; r += 8; } 2113 | if((t=x>>4) != 0) { x = t; r += 4; } 2114 | if((t=x>>2) != 0) { x = t; r += 2; } 2115 | if((t=x>>1) != 0) { x = t; r += 1; } 2116 | return r; 2117 | } 2118 | 2119 | // (public) return the number of bits in "this" 2120 | function bnBitLength() { 2121 | if(this.t <= 0) return 0; 2122 | return this.DB*(this.t-1)+nbits(this.data[this.t-1]^(this.s&this.DM)); 2123 | } 2124 | 2125 | // (protected) r = this << n*DB 2126 | function bnpDLShiftTo(n,r) { 2127 | var i; 2128 | for(i = this.t-1; i >= 0; --i) r.data[i+n] = this.data[i]; 2129 | for(i = n-1; i >= 0; --i) r.data[i] = 0; 2130 | r.t = this.t+n; 2131 | r.s = this.s; 2132 | } 2133 | 2134 | // (protected) r = this >> n*DB 2135 | function bnpDRShiftTo(n,r) { 2136 | for(var i = n; i < this.t; ++i) r.data[i-n] = this.data[i]; 2137 | r.t = Math.max(this.t-n,0); 2138 | r.s = this.s; 2139 | } 2140 | 2141 | // (protected) r = this << n 2142 | function bnpLShiftTo(n,r) { 2143 | var bs = n%this.DB; 2144 | var cbs = this.DB-bs; 2145 | var bm = (1<= 0; --i) { 2148 | r.data[i+ds+1] = (this.data[i]>>cbs)|c; 2149 | c = (this.data[i]&bm)<= 0; --i) r.data[i] = 0; 2152 | r.data[ds] = c; 2153 | r.t = this.t+ds+1; 2154 | r.s = this.s; 2155 | r.clamp(); 2156 | } 2157 | 2158 | // (protected) r = this >> n 2159 | function bnpRShiftTo(n,r) { 2160 | r.s = this.s; 2161 | var ds = Math.floor(n/this.DB); 2162 | if(ds >= this.t) { r.t = 0; return; } 2163 | var bs = n%this.DB; 2164 | var cbs = this.DB-bs; 2165 | var bm = (1<>bs; 2167 | for(var i = ds+1; i < this.t; ++i) { 2168 | r.data[i-ds-1] |= (this.data[i]&bm)<>bs; 2170 | } 2171 | if(bs > 0) r.data[this.t-ds-1] |= (this.s&bm)<>= this.DB; 2183 | } 2184 | if(a.t < this.t) { 2185 | c -= a.s; 2186 | while(i < this.t) { 2187 | c += this.data[i]; 2188 | r.data[i++] = c&this.DM; 2189 | c >>= this.DB; 2190 | } 2191 | c += this.s; 2192 | } 2193 | else { 2194 | c += this.s; 2195 | while(i < a.t) { 2196 | c -= a.data[i]; 2197 | r.data[i++] = c&this.DM; 2198 | c >>= this.DB; 2199 | } 2200 | c -= a.s; 2201 | } 2202 | r.s = (c<0)?-1:0; 2203 | if(c < -1) r.data[i++] = this.DV+c; 2204 | else if(c > 0) r.data[i++] = c; 2205 | r.t = i; 2206 | r.clamp(); 2207 | } 2208 | 2209 | // (protected) r = this * a, r != this,a (HAC 14.12) 2210 | // "this" should be the larger one if appropriate. 2211 | function bnpMultiplyTo(a,r) { 2212 | var x = this.abs(), y = a.abs(); 2213 | var i = x.t; 2214 | r.t = i+y.t; 2215 | while(--i >= 0) r.data[i] = 0; 2216 | for(i = 0; i < y.t; ++i) r.data[i+x.t] = x.am(0,y.data[i],r,i,0,x.t); 2217 | r.s = 0; 2218 | r.clamp(); 2219 | if(this.s != a.s) BigInteger.ZERO.subTo(r,r); 2220 | } 2221 | 2222 | // (protected) r = this^2, r != this (HAC 14.16) 2223 | function bnpSquareTo(r) { 2224 | var x = this.abs(); 2225 | var i = r.t = 2*x.t; 2226 | while(--i >= 0) r.data[i] = 0; 2227 | for(i = 0; i < x.t-1; ++i) { 2228 | var c = x.am(i,x.data[i],r,2*i,0,1); 2229 | if((r.data[i+x.t]+=x.am(i+1,2*x.data[i],r,2*i+1,c,x.t-i-1)) >= x.DV) { 2230 | r.data[i+x.t] -= x.DV; 2231 | r.data[i+x.t+1] = 1; 2232 | } 2233 | } 2234 | if(r.t > 0) r.data[r.t-1] += x.am(i,x.data[i],r,2*i,0,1); 2235 | r.s = 0; 2236 | r.clamp(); 2237 | } 2238 | 2239 | // (protected) divide this by m, quotient and remainder to q, r (HAC 14.20) 2240 | // r != q, this != m. q or r may be null. 2241 | function bnpDivRemTo(m,q,r) { 2242 | var pm = m.abs(); 2243 | if(pm.t <= 0) return; 2244 | var pt = this.abs(); 2245 | if(pt.t < pm.t) { 2246 | if(q != null) q.fromInt(0); 2247 | if(r != null) this.copyTo(r); 2248 | return; 2249 | } 2250 | if(r == null) r = nbi(); 2251 | var y = nbi(), ts = this.s, ms = m.s; 2252 | var nsh = this.DB-nbits(pm.data[pm.t-1]); // normalize modulus 2253 | if(nsh > 0) { pm.lShiftTo(nsh,y); pt.lShiftTo(nsh,r); } 2254 | else { pm.copyTo(y); pt.copyTo(r); } 2255 | var ys = y.t; 2256 | var y0 = y.data[ys-1]; 2257 | if(y0 == 0) return; 2258 | var yt = y0*(1<1)?y.data[ys-2]>>this.F2:0); 2259 | var d1 = this.FV/yt, d2 = (1<= 0) { 2263 | r.data[r.t++] = 1; 2264 | r.subTo(t,r); 2265 | } 2266 | BigInteger.ONE.dlShiftTo(ys,t); 2267 | t.subTo(y,y); // "negative" y so we can replace sub with am later 2268 | while(y.t < ys) y.data[y.t++] = 0; 2269 | while(--j >= 0) { 2270 | // Estimate quotient digit 2271 | var qd = (r.data[--i]==y0)?this.DM:Math.floor(r.data[i]*d1+(r.data[i-1]+e)*d2); 2272 | if((r.data[i]+=y.am(0,qd,r,j,0,ys)) < qd) { // Try it out 2273 | y.dlShiftTo(j,t); 2274 | r.subTo(t,r); 2275 | while(r.data[i] < --qd) r.subTo(t,r); 2276 | } 2277 | } 2278 | if(q != null) { 2279 | r.drShiftTo(ys,q); 2280 | if(ts != ms) BigInteger.ZERO.subTo(q,q); 2281 | } 2282 | r.t = ys; 2283 | r.clamp(); 2284 | if(nsh > 0) r.rShiftTo(nsh,r); // Denormalize remainder 2285 | if(ts < 0) BigInteger.ZERO.subTo(r,r); 2286 | } 2287 | 2288 | // (public) this mod a 2289 | function bnMod(a) { 2290 | var r = nbi(); 2291 | this.abs().divRemTo(a,null,r); 2292 | if(this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r,r); 2293 | return r; 2294 | } 2295 | 2296 | // Modular reduction using "classic" algorithm 2297 | function Classic(m) { this.m = m; } 2298 | function cConvert(x) { 2299 | if(x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m); 2300 | else return x; 2301 | } 2302 | function cRevert(x) { return x; } 2303 | function cReduce(x) { x.divRemTo(this.m,null,x); } 2304 | function cMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } 2305 | function cSqrTo(x,r) { x.squareTo(r); this.reduce(r); } 2306 | 2307 | Classic.prototype.convert = cConvert; 2308 | Classic.prototype.revert = cRevert; 2309 | Classic.prototype.reduce = cReduce; 2310 | Classic.prototype.mulTo = cMulTo; 2311 | Classic.prototype.sqrTo = cSqrTo; 2312 | 2313 | // (protected) return "-1/this % 2^DB"; useful for Mont. reduction 2314 | // justification: 2315 | // xy == 1 (mod m) 2316 | // xy = 1+km 2317 | // xy(2-xy) = (1+km)(1-km) 2318 | // x[y(2-xy)] = 1-k^2m^2 2319 | // x[y(2-xy)] == 1 (mod m^2) 2320 | // if y is 1/x mod m, then y(2-xy) is 1/x mod m^2 2321 | // should reduce x and y(2-xy) by m^2 at each step to keep size bounded. 2322 | // JS multiply "overflows" differently from C/C++, so care is needed here. 2323 | function bnpInvDigit() { 2324 | if(this.t < 1) return 0; 2325 | var x = this.data[0]; 2326 | if((x&1) == 0) return 0; 2327 | var y = x&3; // y == 1/x mod 2^2 2328 | y = (y*(2-(x&0xf)*y))&0xf; // y == 1/x mod 2^4 2329 | y = (y*(2-(x&0xff)*y))&0xff; // y == 1/x mod 2^8 2330 | y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff; // y == 1/x mod 2^16 2331 | // last step - calculate inverse mod DV directly; 2332 | // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints 2333 | y = (y*(2-x*y%this.DV))%this.DV; // y == 1/x mod 2^dbits 2334 | // we really want the negative inverse, and -DV < y < DV 2335 | return (y>0)?this.DV-y:-y; 2336 | } 2337 | 2338 | // Montgomery reduction 2339 | function Montgomery(m) { 2340 | this.m = m; 2341 | this.mp = m.invDigit(); 2342 | this.mpl = this.mp&0x7fff; 2343 | this.mph = this.mp>>15; 2344 | this.um = (1<<(m.DB-15))-1; 2345 | this.mt2 = 2*m.t; 2346 | } 2347 | 2348 | // xR mod m 2349 | function montConvert(x) { 2350 | var r = nbi(); 2351 | x.abs().dlShiftTo(this.m.t,r); 2352 | r.divRemTo(this.m,null,r); 2353 | if(x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r,r); 2354 | return r; 2355 | } 2356 | 2357 | // x/R mod m 2358 | function montRevert(x) { 2359 | var r = nbi(); 2360 | x.copyTo(r); 2361 | this.reduce(r); 2362 | return r; 2363 | } 2364 | 2365 | // x = x/R mod m (HAC 14.32) 2366 | function montReduce(x) { 2367 | while(x.t <= this.mt2) // pad x so am has enough room later 2368 | x.data[x.t++] = 0; 2369 | for(var i = 0; i < this.m.t; ++i) { 2370 | // faster way of calculating u0 = x.data[i]*mp mod DV 2371 | var j = x.data[i]&0x7fff; 2372 | var u0 = (j*this.mpl+(((j*this.mph+(x.data[i]>>15)*this.mpl)&this.um)<<15))&x.DM; 2373 | // use am to combine the multiply-shift-add into one call 2374 | j = i+this.m.t; 2375 | x.data[j] += this.m.am(0,u0,x,i,0,this.m.t); 2376 | // propagate carry 2377 | while(x.data[j] >= x.DV) { x.data[j] -= x.DV; x.data[++j]++; } 2378 | } 2379 | x.clamp(); 2380 | x.drShiftTo(this.m.t,x); 2381 | if(x.compareTo(this.m) >= 0) x.subTo(this.m,x); 2382 | } 2383 | 2384 | // r = "x^2/R mod m"; x != r 2385 | function montSqrTo(x,r) { x.squareTo(r); this.reduce(r); } 2386 | 2387 | // r = "xy/R mod m"; x,y != r 2388 | function montMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } 2389 | 2390 | Montgomery.prototype.convert = montConvert; 2391 | Montgomery.prototype.revert = montRevert; 2392 | Montgomery.prototype.reduce = montReduce; 2393 | Montgomery.prototype.mulTo = montMulTo; 2394 | Montgomery.prototype.sqrTo = montSqrTo; 2395 | 2396 | // (protected) true iff this is even 2397 | function bnpIsEven() { return ((this.t>0)?(this.data[0]&1):this.s) == 0; } 2398 | 2399 | // (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79) 2400 | function bnpExp(e,z) { 2401 | if(e > 0xffffffff || e < 1) return BigInteger.ONE; 2402 | var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e)-1; 2403 | g.copyTo(r); 2404 | while(--i >= 0) { 2405 | z.sqrTo(r,r2); 2406 | if((e&(1< 0) z.mulTo(r2,g,r); 2407 | else { var t = r; r = r2; r2 = t; } 2408 | } 2409 | return z.revert(r); 2410 | } 2411 | 2412 | // (public) this^e % m, 0 <= e < 2^32 2413 | function bnModPowInt(e,m) { 2414 | var z; 2415 | if(e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m); 2416 | return this.exp(e,z); 2417 | } 2418 | 2419 | // protected 2420 | BigInteger.prototype.copyTo = bnpCopyTo; 2421 | BigInteger.prototype.fromInt = bnpFromInt; 2422 | BigInteger.prototype.fromString = bnpFromString; 2423 | BigInteger.prototype.clamp = bnpClamp; 2424 | BigInteger.prototype.dlShiftTo = bnpDLShiftTo; 2425 | BigInteger.prototype.drShiftTo = bnpDRShiftTo; 2426 | BigInteger.prototype.lShiftTo = bnpLShiftTo; 2427 | BigInteger.prototype.rShiftTo = bnpRShiftTo; 2428 | BigInteger.prototype.subTo = bnpSubTo; 2429 | BigInteger.prototype.multiplyTo = bnpMultiplyTo; 2430 | BigInteger.prototype.squareTo = bnpSquareTo; 2431 | BigInteger.prototype.divRemTo = bnpDivRemTo; 2432 | BigInteger.prototype.invDigit = bnpInvDigit; 2433 | BigInteger.prototype.isEven = bnpIsEven; 2434 | BigInteger.prototype.exp = bnpExp; 2435 | 2436 | // public 2437 | BigInteger.prototype.toString = bnToString; 2438 | BigInteger.prototype.negate = bnNegate; 2439 | BigInteger.prototype.abs = bnAbs; 2440 | BigInteger.prototype.compareTo = bnCompareTo; 2441 | BigInteger.prototype.bitLength = bnBitLength; 2442 | BigInteger.prototype.mod = bnMod; 2443 | BigInteger.prototype.modPowInt = bnModPowInt; 2444 | 2445 | // "constants" 2446 | BigInteger.ZERO = nbv(0); 2447 | BigInteger.ONE = nbv(1); 2448 | 2449 | // jsbn2 lib 2450 | 2451 | //Copyright (c) 2005-2009 Tom Wu 2452 | //All Rights Reserved. 2453 | //See "LICENSE" for details (See jsbn.js for LICENSE). 2454 | 2455 | //Extended JavaScript BN functions, required for RSA private ops. 2456 | 2457 | //Version 1.1: new BigInteger("0", 10) returns "proper" zero 2458 | 2459 | //(public) 2460 | function bnClone() { var r = nbi(); this.copyTo(r); return r; } 2461 | 2462 | //(public) return value as integer 2463 | function bnIntValue() { 2464 | if(this.s < 0) { 2465 | if(this.t == 1) return this.data[0]-this.DV; 2466 | else if(this.t == 0) return -1; 2467 | } 2468 | else if(this.t == 1) return this.data[0]; 2469 | else if(this.t == 0) return 0; 2470 | // assumes 16 < DB < 32 2471 | return ((this.data[1]&((1<<(32-this.DB))-1))<>24; } 2476 | 2477 | //(public) return value as short (assumes DB>=16) 2478 | function bnShortValue() { return (this.t==0)?this.s:(this.data[0]<<16)>>16; } 2479 | 2480 | //(protected) return x s.t. r^x < DV 2481 | function bnpChunkSize(r) { return Math.floor(Math.LN2*this.DB/Math.log(r)); } 2482 | 2483 | //(public) 0 if this == 0, 1 if this > 0 2484 | function bnSigNum() { 2485 | if(this.s < 0) return -1; 2486 | else if(this.t <= 0 || (this.t == 1 && this.data[0] <= 0)) return 0; 2487 | else return 1; 2488 | } 2489 | 2490 | //(protected) convert to radix string 2491 | function bnpToRadix(b) { 2492 | if(b == null) b = 10; 2493 | if(this.signum() == 0 || b < 2 || b > 36) return "0"; 2494 | var cs = this.chunkSize(b); 2495 | var a = Math.pow(b,cs); 2496 | var d = nbv(a), y = nbi(), z = nbi(), r = ""; 2497 | this.divRemTo(d,y,z); 2498 | while(y.signum() > 0) { 2499 | r = (a+z.intValue()).toString(b).substr(1) + r; 2500 | y.divRemTo(d,y,z); 2501 | } 2502 | return z.intValue().toString(b) + r; 2503 | } 2504 | 2505 | //(protected) convert from radix string 2506 | function bnpFromRadix(s,b) { 2507 | this.fromInt(0); 2508 | if(b == null) b = 10; 2509 | var cs = this.chunkSize(b); 2510 | var d = Math.pow(b,cs), mi = false, j = 0, w = 0; 2511 | for(var i = 0; i < s.length; ++i) { 2512 | var x = intAt(s,i); 2513 | if(x < 0) { 2514 | if(s.charAt(i) == "-" && this.signum() == 0) mi = true; 2515 | continue; 2516 | } 2517 | w = b*w+x; 2518 | if(++j >= cs) { 2519 | this.dMultiply(d); 2520 | this.dAddOffset(w,0); 2521 | j = 0; 2522 | w = 0; 2523 | } 2524 | } 2525 | if(j > 0) { 2526 | this.dMultiply(Math.pow(b,j)); 2527 | this.dAddOffset(w,0); 2528 | } 2529 | if(mi) BigInteger.ZERO.subTo(this,this); 2530 | } 2531 | 2532 | //(protected) alternate constructor 2533 | function bnpFromNumber(a,b,c) { 2534 | if("number" == typeof b) { 2535 | // new BigInteger(int,int,RNG) 2536 | if(a < 2) this.fromInt(1); 2537 | else { 2538 | this.fromNumber(a,c); 2539 | if(!this.testBit(a-1)) // force MSB set 2540 | this.bitwiseTo(BigInteger.ONE.shiftLeft(a-1),op_or,this); 2541 | if(this.isEven()) this.dAddOffset(1,0); // force odd 2542 | while(!this.isProbablePrime(b)) { 2543 | this.dAddOffset(2,0); 2544 | if(this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a-1),this); 2545 | } 2546 | } 2547 | } 2548 | else { 2549 | // new BigInteger(int,RNG) 2550 | var x = new Array(), t = a&7; 2551 | x.length = (a>>3)+1; 2552 | b.nextBytes(x); 2553 | if(t > 0) x[0] &= ((1< 0) { 2564 | if(p < this.DB && (d = this.data[i]>>p) != (this.s&this.DM)>>p) 2565 | r[k++] = d|(this.s<<(this.DB-p)); 2566 | while(i >= 0) { 2567 | if(p < 8) { 2568 | d = (this.data[i]&((1<>(p+=this.DB-8); 2570 | } 2571 | else { 2572 | d = (this.data[i]>>(p-=8))&0xff; 2573 | if(p <= 0) { p += this.DB; --i; } 2574 | } 2575 | if((d&0x80) != 0) d |= -256; 2576 | if(k == 0 && (this.s&0x80) != (d&0x80)) ++k; 2577 | if(k > 0 || d != this.s) r[k++] = d; 2578 | } 2579 | } 2580 | return r; 2581 | } 2582 | 2583 | function bnEquals(a) { return(this.compareTo(a)==0); } 2584 | function bnMin(a) { return(this.compareTo(a)<0)?this:a; } 2585 | function bnMax(a) { return(this.compareTo(a)>0)?this:a; } 2586 | 2587 | //(protected) r = this op a (bitwise) 2588 | function bnpBitwiseTo(a,op,r) { 2589 | var i, f, m = Math.min(a.t,this.t); 2590 | for(i = 0; i < m; ++i) r.data[i] = op(this.data[i],a.data[i]); 2591 | if(a.t < this.t) { 2592 | f = a.s&this.DM; 2593 | for(i = m; i < this.t; ++i) r.data[i] = op(this.data[i],f); 2594 | r.t = this.t; 2595 | } 2596 | else { 2597 | f = this.s&this.DM; 2598 | for(i = m; i < a.t; ++i) r.data[i] = op(f,a.data[i]); 2599 | r.t = a.t; 2600 | } 2601 | r.s = op(this.s,a.s); 2602 | r.clamp(); 2603 | } 2604 | 2605 | //(public) this & a 2606 | function op_and(x,y) { return x&y; } 2607 | function bnAnd(a) { var r = nbi(); this.bitwiseTo(a,op_and,r); return r; } 2608 | 2609 | //(public) this | a 2610 | function op_or(x,y) { return x|y; } 2611 | function bnOr(a) { var r = nbi(); this.bitwiseTo(a,op_or,r); return r; } 2612 | 2613 | //(public) this ^ a 2614 | function op_xor(x,y) { return x^y; } 2615 | function bnXor(a) { var r = nbi(); this.bitwiseTo(a,op_xor,r); return r; } 2616 | 2617 | //(public) this & ~a 2618 | function op_andnot(x,y) { return x&~y; } 2619 | function bnAndNot(a) { var r = nbi(); this.bitwiseTo(a,op_andnot,r); return r; } 2620 | 2621 | //(public) ~this 2622 | function bnNot() { 2623 | var r = nbi(); 2624 | for(var i = 0; i < this.t; ++i) r.data[i] = this.DM&~this.data[i]; 2625 | r.t = this.t; 2626 | r.s = ~this.s; 2627 | return r; 2628 | } 2629 | 2630 | //(public) this << n 2631 | function bnShiftLeft(n) { 2632 | var r = nbi(); 2633 | if(n < 0) this.rShiftTo(-n,r); else this.lShiftTo(n,r); 2634 | return r; 2635 | } 2636 | 2637 | //(public) this >> n 2638 | function bnShiftRight(n) { 2639 | var r = nbi(); 2640 | if(n < 0) this.lShiftTo(-n,r); else this.rShiftTo(n,r); 2641 | return r; 2642 | } 2643 | 2644 | //return index of lowest 1-bit in x, x < 2^31 2645 | function lbit(x) { 2646 | if(x == 0) return -1; 2647 | var r = 0; 2648 | if((x&0xffff) == 0) { x >>= 16; r += 16; } 2649 | if((x&0xff) == 0) { x >>= 8; r += 8; } 2650 | if((x&0xf) == 0) { x >>= 4; r += 4; } 2651 | if((x&3) == 0) { x >>= 2; r += 2; } 2652 | if((x&1) == 0) ++r; 2653 | return r; 2654 | } 2655 | 2656 | //(public) returns index of lowest 1-bit (or -1 if none) 2657 | function bnGetLowestSetBit() { 2658 | for(var i = 0; i < this.t; ++i) 2659 | if(this.data[i] != 0) return i*this.DB+lbit(this.data[i]); 2660 | if(this.s < 0) return this.t*this.DB; 2661 | return -1; 2662 | } 2663 | 2664 | //return number of 1 bits in x 2665 | function cbit(x) { 2666 | var r = 0; 2667 | while(x != 0) { x &= x-1; ++r; } 2668 | return r; 2669 | } 2670 | 2671 | //(public) return number of set bits 2672 | function bnBitCount() { 2673 | var r = 0, x = this.s&this.DM; 2674 | for(var i = 0; i < this.t; ++i) r += cbit(this.data[i]^x); 2675 | return r; 2676 | } 2677 | 2678 | //(public) true iff nth bit is set 2679 | function bnTestBit(n) { 2680 | var j = Math.floor(n/this.DB); 2681 | if(j >= this.t) return(this.s!=0); 2682 | return((this.data[j]&(1<<(n%this.DB)))!=0); 2683 | } 2684 | 2685 | //(protected) this op (1<>= this.DB; 2708 | } 2709 | if(a.t < this.t) { 2710 | c += a.s; 2711 | while(i < this.t) { 2712 | c += this.data[i]; 2713 | r.data[i++] = c&this.DM; 2714 | c >>= this.DB; 2715 | } 2716 | c += this.s; 2717 | } 2718 | else { 2719 | c += this.s; 2720 | while(i < a.t) { 2721 | c += a.data[i]; 2722 | r.data[i++] = c&this.DM; 2723 | c >>= this.DB; 2724 | } 2725 | c += a.s; 2726 | } 2727 | r.s = (c<0)?-1:0; 2728 | if(c > 0) r.data[i++] = c; 2729 | else if(c < -1) r.data[i++] = this.DV+c; 2730 | r.t = i; 2731 | r.clamp(); 2732 | } 2733 | 2734 | //(public) this + a 2735 | function bnAdd(a) { var r = nbi(); this.addTo(a,r); return r; } 2736 | 2737 | //(public) this - a 2738 | function bnSubtract(a) { var r = nbi(); this.subTo(a,r); return r; } 2739 | 2740 | //(public) this * a 2741 | function bnMultiply(a) { var r = nbi(); this.multiplyTo(a,r); return r; } 2742 | 2743 | //(public) this / a 2744 | function bnDivide(a) { var r = nbi(); this.divRemTo(a,r,null); return r; } 2745 | 2746 | //(public) this % a 2747 | function bnRemainder(a) { var r = nbi(); this.divRemTo(a,null,r); return r; } 2748 | 2749 | //(public) [this/a,this%a] 2750 | function bnDivideAndRemainder(a) { 2751 | var q = nbi(), r = nbi(); 2752 | this.divRemTo(a,q,r); 2753 | return new Array(q,r); 2754 | } 2755 | 2756 | //(protected) this *= n, this >= 0, 1 < n < DV 2757 | function bnpDMultiply(n) { 2758 | this.data[this.t] = this.am(0,n-1,this,0,0,this.t); 2759 | ++this.t; 2760 | this.clamp(); 2761 | } 2762 | 2763 | //(protected) this += n << w words, this >= 0 2764 | function bnpDAddOffset(n,w) { 2765 | if(n == 0) return; 2766 | while(this.t <= w) this.data[this.t++] = 0; 2767 | this.data[w] += n; 2768 | while(this.data[w] >= this.DV) { 2769 | this.data[w] -= this.DV; 2770 | if(++w >= this.t) this.data[this.t++] = 0; 2771 | ++this.data[w]; 2772 | } 2773 | } 2774 | 2775 | //A "null" reducer 2776 | function NullExp() {} 2777 | function nNop(x) { return x; } 2778 | function nMulTo(x,y,r) { x.multiplyTo(y,r); } 2779 | function nSqrTo(x,r) { x.squareTo(r); } 2780 | 2781 | NullExp.prototype.convert = nNop; 2782 | NullExp.prototype.revert = nNop; 2783 | NullExp.prototype.mulTo = nMulTo; 2784 | NullExp.prototype.sqrTo = nSqrTo; 2785 | 2786 | //(public) this^e 2787 | function bnPow(e) { return this.exp(e,new NullExp()); } 2788 | 2789 | //(protected) r = lower n words of "this * a", a.t <= n 2790 | //"this" should be the larger one if appropriate. 2791 | function bnpMultiplyLowerTo(a,n,r) { 2792 | var i = Math.min(this.t+a.t,n); 2793 | r.s = 0; // assumes a,this >= 0 2794 | r.t = i; 2795 | while(i > 0) r.data[--i] = 0; 2796 | var j; 2797 | for(j = r.t-this.t; i < j; ++i) r.data[i+this.t] = this.am(0,a.data[i],r,i,0,this.t); 2798 | for(j = Math.min(a.t,n); i < j; ++i) this.am(0,a.data[i],r,i,0,n-i); 2799 | r.clamp(); 2800 | } 2801 | 2802 | //(protected) r = "this * a" without lower n words, n > 0 2803 | //"this" should be the larger one if appropriate. 2804 | function bnpMultiplyUpperTo(a,n,r) { 2805 | --n; 2806 | var i = r.t = this.t+a.t-n; 2807 | r.s = 0; // assumes a,this >= 0 2808 | while(--i >= 0) r.data[i] = 0; 2809 | for(i = Math.max(n-this.t,0); i < a.t; ++i) 2810 | r.data[this.t+i-n] = this.am(n-i,a.data[i],r,0,0,this.t+i-n); 2811 | r.clamp(); 2812 | r.drShiftTo(1,r); 2813 | } 2814 | 2815 | //Barrett modular reduction 2816 | function Barrett(m) { 2817 | // setup Barrett 2818 | this.r2 = nbi(); 2819 | this.q3 = nbi(); 2820 | BigInteger.ONE.dlShiftTo(2*m.t,this.r2); 2821 | this.mu = this.r2.divide(m); 2822 | this.m = m; 2823 | } 2824 | 2825 | function barrettConvert(x) { 2826 | if(x.s < 0 || x.t > 2*this.m.t) return x.mod(this.m); 2827 | else if(x.compareTo(this.m) < 0) return x; 2828 | else { var r = nbi(); x.copyTo(r); this.reduce(r); return r; } 2829 | } 2830 | 2831 | function barrettRevert(x) { return x; } 2832 | 2833 | //x = x mod m (HAC 14.42) 2834 | function barrettReduce(x) { 2835 | x.drShiftTo(this.m.t-1,this.r2); 2836 | if(x.t > this.m.t+1) { x.t = this.m.t+1; x.clamp(); } 2837 | this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3); 2838 | this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2); 2839 | while(x.compareTo(this.r2) < 0) x.dAddOffset(1,this.m.t+1); 2840 | x.subTo(this.r2,x); 2841 | while(x.compareTo(this.m) >= 0) x.subTo(this.m,x); 2842 | } 2843 | 2844 | //r = x^2 mod m; x != r 2845 | function barrettSqrTo(x,r) { x.squareTo(r); this.reduce(r); } 2846 | 2847 | //r = x*y mod m; x,y != r 2848 | function barrettMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } 2849 | 2850 | Barrett.prototype.convert = barrettConvert; 2851 | Barrett.prototype.revert = barrettRevert; 2852 | Barrett.prototype.reduce = barrettReduce; 2853 | Barrett.prototype.mulTo = barrettMulTo; 2854 | Barrett.prototype.sqrTo = barrettSqrTo; 2855 | 2856 | //(public) this^e % m (HAC 14.85) 2857 | function bnModPow(e,m) { 2858 | var i = e.bitLength(), k, r = nbv(1), z; 2859 | if(i <= 0) return r; 2860 | else if(i < 18) k = 1; 2861 | else if(i < 48) k = 3; 2862 | else if(i < 144) k = 4; 2863 | else if(i < 768) k = 5; 2864 | else k = 6; 2865 | if(i < 8) 2866 | z = new Classic(m); 2867 | else if(m.isEven()) 2868 | z = new Barrett(m); 2869 | else 2870 | z = new Montgomery(m); 2871 | 2872 | // precomputation 2873 | var g = new Array(), n = 3, k1 = k-1, km = (1< 1) { 2876 | var g2 = nbi(); 2877 | z.sqrTo(g[1],g2); 2878 | while(n <= km) { 2879 | g[n] = nbi(); 2880 | z.mulTo(g2,g[n-2],g[n]); 2881 | n += 2; 2882 | } 2883 | } 2884 | 2885 | var j = e.t-1, w, is1 = true, r2 = nbi(), t; 2886 | i = nbits(e.data[j])-1; 2887 | while(j >= 0) { 2888 | if(i >= k1) w = (e.data[j]>>(i-k1))&km; 2889 | else { 2890 | w = (e.data[j]&((1<<(i+1))-1))<<(k1-i); 2891 | if(j > 0) w |= e.data[j-1]>>(this.DB+i-k1); 2892 | } 2893 | 2894 | n = k; 2895 | while((w&1) == 0) { w >>= 1; --n; } 2896 | if((i -= n) < 0) { i += this.DB; --j; } 2897 | if(is1) { // ret == 1, don't bother squaring or multiplying it 2898 | g[w].copyTo(r); 2899 | is1 = false; 2900 | } 2901 | else { 2902 | while(n > 1) { z.sqrTo(r,r2); z.sqrTo(r2,r); n -= 2; } 2903 | if(n > 0) z.sqrTo(r,r2); else { t = r; r = r2; r2 = t; } 2904 | z.mulTo(r2,g[w],r); 2905 | } 2906 | 2907 | while(j >= 0 && (e.data[j]&(1< 0) { 2924 | x.rShiftTo(g,x); 2925 | y.rShiftTo(g,y); 2926 | } 2927 | while(x.signum() > 0) { 2928 | if((i = x.getLowestSetBit()) > 0) x.rShiftTo(i,x); 2929 | if((i = y.getLowestSetBit()) > 0) y.rShiftTo(i,y); 2930 | if(x.compareTo(y) >= 0) { 2931 | x.subTo(y,x); 2932 | x.rShiftTo(1,x); 2933 | } 2934 | else { 2935 | y.subTo(x,y); 2936 | y.rShiftTo(1,y); 2937 | } 2938 | } 2939 | if(g > 0) y.lShiftTo(g,y); 2940 | return y; 2941 | } 2942 | 2943 | //(protected) this % n, n < 2^26 2944 | function bnpModInt(n) { 2945 | if(n <= 0) return 0; 2946 | var d = this.DV%n, r = (this.s<0)?n-1:0; 2947 | if(this.t > 0) 2948 | if(d == 0) r = this.data[0]%n; 2949 | else for(var i = this.t-1; i >= 0; --i) r = (d*r+this.data[i])%n; 2950 | return r; 2951 | } 2952 | 2953 | //(public) 1/this % m (HAC 14.61) 2954 | function bnModInverse(m) { 2955 | var ac = m.isEven(); 2956 | if((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO; 2957 | var u = m.clone(), v = this.clone(); 2958 | var a = nbv(1), b = nbv(0), c = nbv(0), d = nbv(1); 2959 | while(u.signum() != 0) { 2960 | while(u.isEven()) { 2961 | u.rShiftTo(1,u); 2962 | if(ac) { 2963 | if(!a.isEven() || !b.isEven()) { a.addTo(this,a); b.subTo(m,b); } 2964 | a.rShiftTo(1,a); 2965 | } 2966 | else if(!b.isEven()) b.subTo(m,b); 2967 | b.rShiftTo(1,b); 2968 | } 2969 | while(v.isEven()) { 2970 | v.rShiftTo(1,v); 2971 | if(ac) { 2972 | if(!c.isEven() || !d.isEven()) { c.addTo(this,c); d.subTo(m,d); } 2973 | c.rShiftTo(1,c); 2974 | } 2975 | else if(!d.isEven()) d.subTo(m,d); 2976 | d.rShiftTo(1,d); 2977 | } 2978 | if(u.compareTo(v) >= 0) { 2979 | u.subTo(v,u); 2980 | if(ac) a.subTo(c,a); 2981 | b.subTo(d,b); 2982 | } 2983 | else { 2984 | v.subTo(u,v); 2985 | if(ac) c.subTo(a,c); 2986 | d.subTo(b,d); 2987 | } 2988 | } 2989 | if(v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO; 2990 | if(d.compareTo(m) >= 0) return d.subtract(m); 2991 | if(d.signum() < 0) d.addTo(m,d); else return d; 2992 | if(d.signum() < 0) return d.add(m); else return d; 2993 | } 2994 | 2995 | var lowprimes = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509]; 2996 | var lplim = (1<<26)/lowprimes[lowprimes.length-1]; 2997 | 2998 | //(public) test primality with certainty >= 1-.5^t 2999 | function bnIsProbablePrime(t) { 3000 | var i, x = this.abs(); 3001 | if(x.t == 1 && x.data[0] <= lowprimes[lowprimes.length-1]) { 3002 | for(i = 0; i < lowprimes.length; ++i) 3003 | if(x.data[0] == lowprimes[i]) return true; 3004 | return false; 3005 | } 3006 | if(x.isEven()) return false; 3007 | i = 1; 3008 | while(i < lowprimes.length) { 3009 | var m = lowprimes[i], j = i+1; 3010 | while(j < lowprimes.length && m < lplim) m *= lowprimes[j++]; 3011 | m = x.modInt(m); 3012 | while(i < j) if(m%lowprimes[i++] == 0) return false; 3013 | } 3014 | return x.millerRabin(t); 3015 | } 3016 | 3017 | //(protected) true if probably prime (HAC 4.24, Miller-Rabin) 3018 | function bnpMillerRabin(t) { 3019 | var n1 = this.subtract(BigInteger.ONE); 3020 | var k = n1.getLowestSetBit(); 3021 | if(k <= 0) return false; 3022 | var r = n1.shiftRight(k); 3023 | t = (t+1)>>1; 3024 | if(t > lowprimes.length) t = lowprimes.length; 3025 | var a = nbi(); 3026 | for(var i = 0; i < t; ++i) { 3027 | a.fromInt(lowprimes[i]); 3028 | var y = a.modPow(r,this); 3029 | if(y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) { 3030 | var j = 1; 3031 | while(j++ < k && y.compareTo(n1) != 0) { 3032 | y = y.modPowInt(2,this); 3033 | if(y.compareTo(BigInteger.ONE) == 0) return false; 3034 | } 3035 | if(y.compareTo(n1) != 0) return false; 3036 | } 3037 | } 3038 | return true; 3039 | } 3040 | 3041 | //protected 3042 | BigInteger.prototype.chunkSize = bnpChunkSize; 3043 | BigInteger.prototype.toRadix = bnpToRadix; 3044 | BigInteger.prototype.fromRadix = bnpFromRadix; 3045 | BigInteger.prototype.fromNumber = bnpFromNumber; 3046 | BigInteger.prototype.bitwiseTo = bnpBitwiseTo; 3047 | BigInteger.prototype.changeBit = bnpChangeBit; 3048 | BigInteger.prototype.addTo = bnpAddTo; 3049 | BigInteger.prototype.dMultiply = bnpDMultiply; 3050 | BigInteger.prototype.dAddOffset = bnpDAddOffset; 3051 | BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo; 3052 | BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo; 3053 | BigInteger.prototype.modInt = bnpModInt; 3054 | BigInteger.prototype.millerRabin = bnpMillerRabin; 3055 | 3056 | //public 3057 | BigInteger.prototype.clone = bnClone; 3058 | BigInteger.prototype.intValue = bnIntValue; 3059 | BigInteger.prototype.byteValue = bnByteValue; 3060 | BigInteger.prototype.shortValue = bnShortValue; 3061 | BigInteger.prototype.signum = bnSigNum; 3062 | BigInteger.prototype.toByteArray = bnToByteArray; 3063 | BigInteger.prototype.equals = bnEquals; 3064 | BigInteger.prototype.min = bnMin; 3065 | BigInteger.prototype.max = bnMax; 3066 | BigInteger.prototype.and = bnAnd; 3067 | BigInteger.prototype.or = bnOr; 3068 | BigInteger.prototype.xor = bnXor; 3069 | BigInteger.prototype.andNot = bnAndNot; 3070 | BigInteger.prototype.not = bnNot; 3071 | BigInteger.prototype.shiftLeft = bnShiftLeft; 3072 | BigInteger.prototype.shiftRight = bnShiftRight; 3073 | BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit; 3074 | BigInteger.prototype.bitCount = bnBitCount; 3075 | BigInteger.prototype.testBit = bnTestBit; 3076 | BigInteger.prototype.setBit = bnSetBit; 3077 | BigInteger.prototype.clearBit = bnClearBit; 3078 | BigInteger.prototype.flipBit = bnFlipBit; 3079 | BigInteger.prototype.add = bnAdd; 3080 | BigInteger.prototype.subtract = bnSubtract; 3081 | BigInteger.prototype.multiply = bnMultiply; 3082 | BigInteger.prototype.divide = bnDivide; 3083 | BigInteger.prototype.remainder = bnRemainder; 3084 | BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder; 3085 | BigInteger.prototype.modPow = bnModPow; 3086 | BigInteger.prototype.modInverse = bnModInverse; 3087 | BigInteger.prototype.pow = bnPow; 3088 | BigInteger.prototype.gcd = bnGCD; 3089 | BigInteger.prototype.isProbablePrime = bnIsProbablePrime; 3090 | 3091 | //BigInteger interfaces not implemented in jsbn: 3092 | 3093 | //BigInteger(int signum, byte[] magnitude) 3094 | //double doubleValue() 3095 | //float floatValue() 3096 | //int hashCode() 3097 | //long longValue() 3098 | //static BigInteger valueOf(long val) 3099 | 3100 | forge.jsbn = forge.jsbn || {}; 3101 | forge.jsbn.BigInteger = BigInteger; 3102 | 3103 | /** 3104 | * util.setImmediate 3105 | */ 3106 | 3107 | /* Utilities API */ 3108 | var util = forge.util = forge.util || {}; 3109 | 3110 | // define setImmediate and nextTick 3111 | if(typeof process === 'undefined' || !process.nextTick) { 3112 | if(typeof setImmediate === 'function') { 3113 | util.setImmediate = setImmediate; 3114 | util.nextTick = function(callback) { 3115 | return setImmediate(callback); 3116 | }; 3117 | } 3118 | else { 3119 | util.setImmediate = function(callback) { 3120 | setTimeout(callback, 0); 3121 | }; 3122 | util.nextTick = util.setImmediate; 3123 | } 3124 | } 3125 | else { 3126 | util.nextTick = process.nextTick; 3127 | if(typeof setImmediate === 'function') { 3128 | util.setImmediate = setImmediate; 3129 | } 3130 | else { 3131 | util.setImmediate = util.nextTick; 3132 | } 3133 | } 3134 | 3135 | // _modPow 3136 | 3137 | var _modPow = function(x, key, pub) { 3138 | var y; 3139 | 3140 | if(pub) { 3141 | y = x.modPow(key.e, key.n); 3142 | } 3143 | else { 3144 | // pre-compute dP, dQ, and qInv if necessary 3145 | if(!key.dP) { 3146 | key.dP = key.d.mod(key.p.subtract(BigInteger.ONE)); 3147 | } 3148 | if(!key.dQ) { 3149 | key.dQ = key.d.mod(key.q.subtract(BigInteger.ONE)); 3150 | } 3151 | if(!key.qInv) { 3152 | key.qInv = key.q.modInverse(key.p); 3153 | } 3154 | 3155 | /* Chinese remainder theorem (CRT) states: 3156 | 3157 | Suppose n1, n2, ..., nk are positive integers which are pairwise 3158 | coprime (n1 and n2 have no common factors other than 1). For any 3159 | integers x1, x2, ..., xk there exists an integer x solving the 3160 | system of simultaneous congruences (where ~= means modularly 3161 | congruent so a ~= b mod n means a mod n = b mod n): 3162 | 3163 | x ~= x1 mod n1 3164 | x ~= x2 mod n2 3165 | ... 3166 | x ~= xk mod nk 3167 | 3168 | This system of congruences has a single simultaneous solution x 3169 | between 0 and n - 1. Furthermore, each xk solution and x itself 3170 | is congruent modulo the product n = n1*n2*...*nk. 3171 | So x1 mod n = x2 mod n = xk mod n = x mod n. 3172 | 3173 | The single simultaneous solution x can be solved with the following 3174 | equation: 3175 | 3176 | x = sum(xi*ri*si) mod n where ri = n/ni and si = ri^-1 mod ni. 3177 | 3178 | Where x is less than n, xi = x mod ni. 3179 | 3180 | For RSA we are only concerned with k = 2. The modulus n = pq, where 3181 | p and q are coprime. The RSA decryption algorithm is: 3182 | 3183 | y = x^d mod n 3184 | 3185 | Given the above: 3186 | 3187 | x1 = x^d mod p 3188 | r1 = n/p = q 3189 | s1 = q^-1 mod p 3190 | x2 = x^d mod q 3191 | r2 = n/q = p 3192 | s2 = p^-1 mod q 3193 | 3194 | So y = (x1r1s1 + x2r2s2) mod n 3195 | = ((x^d mod p)q(q^-1 mod p) + (x^d mod q)p(p^-1 mod q)) mod n 3196 | 3197 | According to Fermat's Little Theorem, if the modulus P is prime, 3198 | for any integer A not evenly divisible by P, A^(P-1) ~= 1 mod P. 3199 | Since A is not divisible by P it follows that if: 3200 | N ~= M mod (P - 1), then A^N mod P = A^M mod P. Therefore: 3201 | 3202 | A^N mod P = A^(M mod (P - 1)) mod P. (The latter takes less effort 3203 | to calculate). In order to calculate x^d mod p more quickly the 3204 | exponent d mod (p - 1) is stored in the RSA private key (the same 3205 | is done for x^d mod q). These values are referred to as dP and dQ 3206 | respectively. Therefore we now have: 3207 | 3208 | y = ((x^dP mod p)q(q^-1 mod p) + (x^dQ mod q)p(p^-1 mod q)) mod n 3209 | 3210 | Since we'll be reducing x^dP by modulo p (same for q) we can also 3211 | reduce x by p (and q respectively) before hand. Therefore, let 3212 | 3213 | xp = ((x mod p)^dP mod p), and 3214 | xq = ((x mod q)^dQ mod q), yielding: 3215 | 3216 | y = (xp*q*(q^-1 mod p) + xq*p*(p^-1 mod q)) mod n 3217 | 3218 | This can be further reduced to a simple algorithm that only 3219 | requires 1 inverse (the q inverse is used) to be used and stored. 3220 | The algorithm is called Garner's algorithm. If qInv is the 3221 | inverse of q, we simply calculate: 3222 | 3223 | y = (qInv*(xp - xq) mod p) * q + xq 3224 | 3225 | However, there are two further complications. First, we need to 3226 | ensure that xp > xq to prevent signed BigIntegers from being used 3227 | so we add p until this is true (since we will be mod'ing with 3228 | p anyway). Then, there is a known timing attack on algorithms 3229 | using the CRT. To mitigate this risk, "cryptographic blinding" 3230 | should be used (*Not yet implemented*). This requires simply 3231 | generating a random number r between 0 and n-1 and its inverse 3232 | and multiplying x by r^e before calculating y and then multiplying 3233 | y by r^-1 afterwards. 3234 | */ 3235 | 3236 | // TODO: do cryptographic blinding 3237 | 3238 | // calculate xp and xq 3239 | var xp = x.mod(key.p).modPow(key.dP, key.p); 3240 | var xq = x.mod(key.q).modPow(key.dQ, key.q); 3241 | 3242 | // xp must be larger than xq to avoid signed bit usage 3243 | while(xp.compareTo(xq) < 0) { 3244 | xp = xp.add(key.p); 3245 | } 3246 | 3247 | // do last step 3248 | y = xp.subtract(xq) 3249 | .multiply(key.qInv).mod(key.p) 3250 | .multiply(key.q).add(xq); 3251 | } 3252 | 3253 | return y; 3254 | }; 3255 | 3256 | /** 3257 | * util.encodeUtf8 3258 | */ 3259 | 3260 | util.encodeUtf8 = function(str) { 3261 | return unescape(encodeURIComponent(str)); 3262 | }; 3263 | 3264 | /** 3265 | * util.decodeUtf8 3266 | */ 3267 | 3268 | util.decodeUtf8 = function(str) { 3269 | return decodeURIComponent(escape(str)); 3270 | }; 3271 | 3272 | 3273 | /** 3274 | * Creates a buffer that stores bytes. A value may be given to put into the 3275 | * buffer that is either a string of bytes or a UTF-16 string that will 3276 | * be encoded using UTF-8 (to do the latter, specify 'utf8' as the encoding). 3277 | * 3278 | * @param [input] the bytes to wrap (as a string) or a UTF-16 string to encode 3279 | * as UTF-8. 3280 | * @param [encoding] (default: 'raw', other: 'utf8'). 3281 | */ 3282 | util.createBuffer = function(input, encoding) { 3283 | encoding = encoding || 'raw'; 3284 | if(input !== undefined && encoding === 'utf8') { 3285 | input = util.encodeUtf8(input); 3286 | } 3287 | return new util.ByteBuffer(input); 3288 | }; 3289 | 3290 | /** 3291 | * util.hexToBytes 3292 | */ 3293 | 3294 | util.hexToBytes = function(hex) { 3295 | var rval = ''; 3296 | var i = 0; 3297 | if(hex.length & 1 == 1) { 3298 | // odd number of characters, convert first character alone 3299 | i = 1; 3300 | rval += String.fromCharCode(parseInt(hex[0], 16)); 3301 | } 3302 | // convert 2 characters (1 byte) at a time 3303 | for(; i < hex.length; i += 2) { 3304 | rval += String.fromCharCode(parseInt(hex.substr(i, 2), 16)); 3305 | } 3306 | return rval; 3307 | }; 3308 | 3309 | /** 3310 | * pki.rsa.decrypt 3311 | */ 3312 | 3313 | pki.rsa.decrypt = function(ed, key, pub, ml) { 3314 | // get the length of the modulus in bytes 3315 | var k = Math.ceil(key.n.bitLength() / 8); 3316 | 3317 | // error if the length of the encrypted data ED is not k 3318 | if(ed.length != k) { 3319 | throw { 3320 | message: 'Encrypted message length is invalid.', 3321 | length: ed.length, 3322 | expected: k 3323 | }; 3324 | } 3325 | 3326 | // convert encrypted data into a big integer 3327 | // FIXME: hex conversion inefficient, get BigInteger w/byte strings 3328 | var y = new BigInteger(forge.util.createBuffer(ed).toHex(), 16); 3329 | 3330 | // do RSA decryption 3331 | var x = _modPow(y, key, pub); 3332 | 3333 | // create the encryption block, if x is shorter in bytes than k, then 3334 | // prepend zero bytes to fill up eb 3335 | // FIXME: hex conversion inefficient, get BigInteger w/byte strings 3336 | var xhex = x.toString(16); 3337 | var eb = forge.util.createBuffer(); 3338 | var zeros = k - Math.ceil(xhex.length / 2); 3339 | while(zeros > 0) { 3340 | eb.putByte(0x00); 3341 | --zeros; 3342 | } 3343 | eb.putBytes(forge.util.hexToBytes(xhex)); 3344 | 3345 | if(ml !== false) { 3346 | /* It is an error if any of the following conditions occurs: 3347 | 3348 | 1. The encryption block EB cannot be parsed unambiguously. 3349 | 2. The padding string PS consists of fewer than eight octets 3350 | or is inconsisent with the block type BT. 3351 | 3. The decryption process is a public-key operation and the block 3352 | type BT is not 00 or 01, or the decryption process is a 3353 | private-key operation and the block type is not 02. 3354 | */ 3355 | 3356 | // parse the encryption block 3357 | var first = eb.getByte(); 3358 | var bt = eb.getByte(); 3359 | if(first !== 0x00 || 3360 | (pub && bt !== 0x00 && bt !== 0x01) || 3361 | (!pub && bt != 0x02) || 3362 | (pub && bt === 0x00 && typeof(ml) === 'undefined')) { 3363 | throw { 3364 | message: 'Encryption block is invalid.' 3365 | }; 3366 | } 3367 | 3368 | var padNum = 0; 3369 | if(bt === 0x00) { 3370 | // check all padding bytes for 0x00 3371 | padNum = k - 3 - ml; 3372 | for(var i = 0; i < padNum; ++i) { 3373 | if(eb.getByte() !== 0x00) { 3374 | throw { 3375 | message: 'Encryption block is invalid.' 3376 | }; 3377 | } 3378 | } 3379 | } 3380 | else if(bt === 0x01) { 3381 | // find the first byte that isn't 0xFF, should be after all padding 3382 | padNum = 0; 3383 | while(eb.length() > 1) { 3384 | if(eb.getByte() !== 0xFF) { 3385 | --eb.read; 3386 | break; 3387 | } 3388 | ++padNum; 3389 | } 3390 | } 3391 | else if(bt === 0x02) { 3392 | // look for 0x00 byte 3393 | padNum = 0; 3394 | while(eb.length() > 1) { 3395 | if(eb.getByte() === 0x00) { 3396 | --eb.read; 3397 | break; 3398 | } 3399 | ++padNum; 3400 | } 3401 | } 3402 | 3403 | // zero must be 0x00 and padNum must be (k - 3 - message length) 3404 | var zero = eb.getByte(); 3405 | if(zero !== 0x00 || padNum !== (k - 3 - eb.length())) { 3406 | throw { 3407 | message: 'Encryption block is invalid.' 3408 | }; 3409 | } 3410 | } 3411 | 3412 | // return message 3413 | return eb.getBytes(); 3414 | }; 3415 | 3416 | /** 3417 | * pki.rsa.encrypt 3418 | */ 3419 | 3420 | pki.rsa.encrypt = function(m, key, bt) { 3421 | var pub = bt; 3422 | var eb = forge.util.createBuffer(); 3423 | 3424 | // get the length of the modulus in bytes 3425 | var k = Math.ceil(key.n.bitLength() / 8); 3426 | 3427 | if(bt !== false && bt !== true) { 3428 | /* use PKCS#1 v1.5 padding */ 3429 | if(m.length > (k - 11)) { 3430 | throw { 3431 | message: 'Message is too long to encrypt.', 3432 | length: m.length, 3433 | max: (k - 11) 3434 | }; 3435 | } 3436 | 3437 | /* A block type BT, a padding string PS, and the data D shall be 3438 | formatted into an octet string EB, the encryption block: 3439 | 3440 | EB = 00 || BT || PS || 00 || D 3441 | 3442 | The block type BT shall be a single octet indicating the structure of 3443 | the encryption block. For this version of the document it shall have 3444 | value 00, 01, or 02. For a private-key operation, the block type 3445 | shall be 00 or 01. For a public-key operation, it shall be 02. 3446 | 3447 | The padding string PS shall consist of k-3-||D|| octets. For block 3448 | type 00, the octets shall have value 00; for block type 01, they 3449 | shall have value FF; and for block type 02, they shall be 3450 | pseudorandomly generated and nonzero. This makes the length of the 3451 | encryption block EB equal to k. */ 3452 | 3453 | // build the encryption block 3454 | eb.putByte(0x00); 3455 | eb.putByte(bt); 3456 | 3457 | // create the padding, get key type 3458 | var padNum = k - 3 - m.length; 3459 | var padByte; 3460 | if(bt === 0x00 || bt === 0x01) { 3461 | pub = false; 3462 | padByte = (bt === 0x00) ? 0x00 : 0xFF; 3463 | for(var i = 0; i < padNum; ++i) { 3464 | eb.putByte(padByte); 3465 | } 3466 | } 3467 | else { 3468 | pub = true; 3469 | for(var i = 0; i < padNum; ++i) { 3470 | padByte = Math.floor(Math.random() * 255) + 1; 3471 | eb.putByte(padByte); 3472 | } 3473 | } 3474 | 3475 | // zero followed by message 3476 | eb.putByte(0x00); 3477 | } 3478 | 3479 | eb.putBytes(m); 3480 | 3481 | // load encryption block as big integer 'x' 3482 | // FIXME: hex conversion inefficient, get BigInteger w/byte strings 3483 | var x = new BigInteger(eb.toHex(), 16); 3484 | 3485 | // do RSA encryption 3486 | var y = _modPow(x, key, pub); 3487 | 3488 | // convert y into the encrypted data byte string, if y is shorter in 3489 | // bytes than k, then prepend zero bytes to fill up ed 3490 | // FIXME: hex conversion inefficient, get BigInteger w/byte strings 3491 | var yhex = y.toString(16); 3492 | var ed = forge.util.createBuffer(); 3493 | var zeros = k - Math.ceil(yhex.length / 2); 3494 | while(zeros > 0) { 3495 | ed.putByte(0x00); 3496 | --zeros; 3497 | } 3498 | ed.putBytes(forge.util.hexToBytes(yhex)); 3499 | return ed.getBytes(); 3500 | }; 3501 | 3502 | /** 3503 | * pki.rsa.setPrivateKey 3504 | */ 3505 | 3506 | pki.rsa.setPrivateKey = function(n, e, d, p, q, dP, dQ, qInv) { 3507 | var key = { 3508 | n: n, 3509 | e: e, 3510 | d: d, 3511 | p: p, 3512 | q: q, 3513 | dP: dP, 3514 | dQ: dQ, 3515 | qInv: qInv 3516 | }; 3517 | 3518 | /** 3519 | * Decrypts the given data with this private key. 3520 | * 3521 | * @param data the byte string to decrypt. 3522 | * 3523 | * @return the decrypted byte string. 3524 | */ 3525 | key.decrypt = function(data) { 3526 | return pki.rsa.decrypt(data, key, false); 3527 | }; 3528 | 3529 | /** 3530 | * Signs the given digest, producing a signature. 3531 | * 3532 | * PKCS#1 supports multiple (currently two) signature schemes: 3533 | * RSASSA-PKCS1-v1_5 and RSASSA-PSS. 3534 | * 3535 | * By default this implementation uses the "old scheme", i.e. 3536 | * RSASSA-PKCS1-v1_5. In order to generate a PSS signature, provide 3537 | * an instance of Forge PSS object as scheme parameter. 3538 | * 3539 | * @param md the message digest object with the hash to sign. 3540 | * @param scheme signature scheme to use, undefined for PKCS#1 v1.5 3541 | * padding style. 3542 | * @return the signature as a byte string. 3543 | */ 3544 | key.sign = function(md, scheme) { 3545 | var bt = false; /* private key operation */ 3546 | 3547 | if(scheme === undefined) { 3548 | scheme = { encode: emsaPkcs1v15encode }; 3549 | bt = 0x01; 3550 | } 3551 | 3552 | var d = scheme.encode(md, key.n.bitLength()); 3553 | return pki.rsa.encrypt(d, key, bt); 3554 | }; 3555 | 3556 | return key; 3557 | }; 3558 | 3559 | /** 3560 | * _getValueLength 3561 | */ 3562 | 3563 | var _getValueLength = function(b) { 3564 | var b2 = b.getByte(); 3565 | if(b2 == 0x80) { 3566 | return undefined; 3567 | } 3568 | 3569 | // see if the length is "short form" or "long form" (bit 8 set) 3570 | var length; 3571 | var longForm = b2 & 0x80; 3572 | if(!longForm) { 3573 | // length is just the first byte 3574 | length = b2; 3575 | } 3576 | else { 3577 | // the number of bytes the length is specified in bits 7 through 1 3578 | // and each length byte is in big-endian base-256 3579 | length = b.getInt((b2 & 0x7F) << 3); 3580 | } 3581 | return length; 3582 | }; 3583 | 3584 | /** 3585 | * asn1 3586 | */ 3587 | 3588 | /** 3589 | * asn1.Type 3590 | */ 3591 | 3592 | var asn1 = forge.asn1 = forge.asn1 || {}; 3593 | asn1.Type = { 3594 | NONE: 0, 3595 | BOOLEAN: 1, 3596 | INTEGER: 2, 3597 | BITSTRING: 3, 3598 | OCTETSTRING: 4, 3599 | NULL: 5, 3600 | OID: 6, 3601 | ODESC: 7, 3602 | EXTERNAL: 8, 3603 | REAL: 9, 3604 | ENUMERATED: 10, 3605 | EMBEDDED: 11, 3606 | UTF8: 12, 3607 | ROID: 13, 3608 | SEQUENCE: 16, 3609 | SET: 17, 3610 | PRINTABLESTRING: 19, 3611 | IA5STRING: 22, 3612 | UTCTIME: 23, 3613 | GENERALIZEDTIME: 24, 3614 | BMPSTRING: 30 3615 | }; 3616 | 3617 | /** 3618 | * asn1.Class 3619 | */ 3620 | 3621 | asn1.Class = { 3622 | UNIVERSAL: 0x00, 3623 | APPLICATION: 0x40, 3624 | CONTEXT_SPECIFIC: 0x80, 3625 | PRIVATE: 0xC0 3626 | }; 3627 | 3628 | /** 3629 | * asn1.create 3630 | */ 3631 | 3632 | asn1.create = function(tagClass, type, constructed, value) { 3633 | /* An asn1 object has a tagClass, a type, a constructed flag, and a 3634 | value. The value's type depends on the constructed flag. If 3635 | constructed, it will contain a list of other asn1 objects. If not, 3636 | it will contain the ASN.1 value as an array of bytes formatted 3637 | according to the ASN.1 data type. */ 3638 | 3639 | // remove undefined values 3640 | if(value.constructor == Array) { 3641 | var tmp = []; 3642 | for(var i = 0; i < value.length; ++i) { 3643 | if(value[i] !== undefined) { 3644 | tmp.push(value[i]); 3645 | } 3646 | } 3647 | value = tmp; 3648 | } 3649 | 3650 | return { 3651 | tagClass: tagClass, 3652 | type: type, 3653 | constructed: constructed, 3654 | composed: constructed || (value.constructor == Array), 3655 | value: value 3656 | }; 3657 | }; 3658 | 3659 | /** 3660 | * asn1.fromDer 3661 | */ 3662 | 3663 | asn1.fromDer = function(bytes) { 3664 | // wrap in buffer if needed 3665 | if(bytes.constructor == String) { 3666 | bytes = forge.util.createBuffer(bytes); 3667 | } 3668 | 3669 | // minimum length for ASN.1 DER structure is 2 3670 | if(bytes.length() < 2) { 3671 | throw { 3672 | message: 'Too few bytes to parse DER.', 3673 | bytes: bytes.length() 3674 | }; 3675 | } 3676 | 3677 | // get the first byte 3678 | var b1 = bytes.getByte(); 3679 | 3680 | // get the tag class 3681 | var tagClass = (b1 & 0xC0); 3682 | 3683 | // get the type (bits 1-5) 3684 | var type = b1 & 0x1F; 3685 | 3686 | // get the value length 3687 | var length = _getValueLength(bytes); 3688 | 3689 | // ensure there are enough bytes to get the value 3690 | if(bytes.length() < length) { 3691 | throw { 3692 | message: 'Too few bytes to read ASN.1 value.', 3693 | detail: bytes.length() + ' < ' + length 3694 | }; 3695 | } 3696 | 3697 | // prepare to get value 3698 | var value; 3699 | 3700 | // constructed flag is bit 6 (32 = 0x20) of the first byte 3701 | var constructed = ((b1 & 0x20) == 0x20); 3702 | 3703 | // determine if the value is composed of other ASN.1 objects (if its 3704 | // constructed it will be and if its a BITSTRING it may be) 3705 | var composed = constructed; 3706 | if(!composed && tagClass === asn1.Class.UNIVERSAL && 3707 | type === asn1.Type.BITSTRING && length > 1) { 3708 | /* The first octet gives the number of bits by which the length of the 3709 | bit string is less than the next multiple of eight (this is called 3710 | the "number of unused bits"). 3711 | 3712 | The second and following octets give the value of the bit string 3713 | converted to an octet string. */ 3714 | // if there are no unused bits, maybe the bitstring holds ASN.1 objs 3715 | var read = bytes.read; 3716 | var unused = bytes.getByte(); 3717 | if(unused === 0) { 3718 | // if the first byte indicates UNIVERSAL or CONTEXT_SPECIFIC, 3719 | // and the length is valid, assume we've got an ASN.1 object 3720 | b1 = bytes.getByte(); 3721 | var tc = (b1 & 0xC0); 3722 | if(tc === asn1.Class.UNIVERSAL || 3723 | tc === asn1.Class.CONTEXT_SPECIFIC) { 3724 | try { 3725 | var len = _getValueLength(bytes); 3726 | composed = (len === length - (bytes.read - read)); 3727 | if(composed) { 3728 | // adjust read/length to account for unused bits byte 3729 | ++read; 3730 | --length; 3731 | } 3732 | } 3733 | catch(ex) {} 3734 | } 3735 | } 3736 | // restore read pointer 3737 | bytes.read = read; 3738 | } 3739 | 3740 | if(composed) { 3741 | // parse child asn1 objects from the value 3742 | value = []; 3743 | if(length === undefined) { 3744 | // asn1 object of indefinite length, read until end tag 3745 | for(;;) { 3746 | if(bytes.bytes(2) === String.fromCharCode(0, 0)) { 3747 | bytes.getBytes(2); 3748 | break; 3749 | } 3750 | value.push(asn1.fromDer(bytes)); 3751 | } 3752 | } 3753 | else { 3754 | // parsing asn1 object of definite length 3755 | var start = bytes.length(); 3756 | while(length > 0) { 3757 | value.push(asn1.fromDer(bytes)); 3758 | length -= start - bytes.length(); 3759 | start = bytes.length(); 3760 | } 3761 | } 3762 | } 3763 | // asn1 not composed, get raw value 3764 | else { 3765 | // TODO: do DER to OID conversion and vice-versa in .toDer? 3766 | 3767 | if(length === undefined) { 3768 | throw { 3769 | message: 'Non-constructed ASN.1 object of indefinite length.' 3770 | }; 3771 | } 3772 | 3773 | if(type === asn1.Type.BMPSTRING) { 3774 | value = ''; 3775 | for(var i = 0; i < length; i += 2) { 3776 | value += String.fromCharCode(bytes.getInt16()); 3777 | } 3778 | } 3779 | else { 3780 | value = bytes.getBytes(length); 3781 | } 3782 | } 3783 | 3784 | // create and return asn1 object 3785 | return asn1.create(tagClass, type, constructed, value); 3786 | }; 3787 | 3788 | /** 3789 | * asn1.toDer 3790 | */ 3791 | 3792 | asn1.toDer = function(obj) { 3793 | var bytes = forge.util.createBuffer(); 3794 | 3795 | // build the first byte 3796 | var b1 = obj.tagClass | obj.type; 3797 | 3798 | // for storing the ASN.1 value 3799 | var value = forge.util.createBuffer(); 3800 | 3801 | // if composed, use each child asn1 object's DER bytes as value 3802 | if(obj.composed) { 3803 | // turn on 6th bit (0x20 = 32) to indicate asn1 is constructed 3804 | // from other asn1 objects 3805 | if(obj.constructed) { 3806 | b1 |= 0x20; 3807 | } 3808 | // if type is a bit string, add unused bits of 0x00 3809 | else { 3810 | value.putByte(0x00); 3811 | } 3812 | 3813 | // add all of the child DER bytes together 3814 | for(var i = 0; i < obj.value.length; ++i) { 3815 | if(obj.value[i] !== undefined) { 3816 | value.putBuffer(asn1.toDer(obj.value[i])); 3817 | } 3818 | } 3819 | } 3820 | // use asn1.value directly 3821 | else { 3822 | if(obj.type === asn1.Type.BMPSTRING) { 3823 | for(var i = 0; i < obj.value.length; ++i) { 3824 | value.putInt16(obj.value.charCodeAt(i)); 3825 | } 3826 | } 3827 | else { 3828 | value.putBytes(obj.value); 3829 | } 3830 | } 3831 | 3832 | // add tag byte 3833 | bytes.putByte(b1); 3834 | 3835 | // use "short form" encoding 3836 | if(value.length() <= 127) { 3837 | // one byte describes the length 3838 | // bit 8 = 0 and bits 7-1 = length 3839 | bytes.putByte(value.length() & 0x7F); 3840 | } 3841 | // use "long form" encoding 3842 | else { 3843 | // 2 to 127 bytes describe the length 3844 | // first byte: bit 8 = 1 and bits 7-1 = # of additional bytes 3845 | // other bytes: length in base 256, big-endian 3846 | var len = value.length(); 3847 | var lenBytes = ''; 3848 | do { 3849 | lenBytes += String.fromCharCode(len & 0xFF); 3850 | len = len >>> 8; 3851 | } 3852 | while(len > 0); 3853 | 3854 | // set first byte to # bytes used to store the length and turn on 3855 | // bit 8 to indicate long-form length is used 3856 | bytes.putByte(lenBytes.length | 0x80); 3857 | 3858 | // concatenate length bytes in reverse since they were generated 3859 | // little endian and we need big endian 3860 | for(var i = lenBytes.length - 1; i >= 0; --i) { 3861 | bytes.putByte(lenBytes.charCodeAt(i)); 3862 | } 3863 | } 3864 | 3865 | // concatenate value bytes 3866 | bytes.putBuffer(value); 3867 | return bytes; 3868 | }; 3869 | 3870 | /** 3871 | * pki.rsa.setPublicKey 3872 | */ 3873 | 3874 | pki.rsa.setPublicKey = function(n, e) { 3875 | var key = { 3876 | n: n, 3877 | e: e 3878 | }; 3879 | 3880 | /** 3881 | * Encrypts the given data with this public key. 3882 | * 3883 | * @param data the byte string to encrypt. 3884 | * 3885 | * @return the encrypted byte string. 3886 | */ 3887 | key.encrypt = function(data) { 3888 | return pki.rsa.encrypt(data, key, 0x02); 3889 | }; 3890 | 3891 | /** 3892 | * Verifies the given signature against the given digest. 3893 | * 3894 | * PKCS#1 supports multiple (currently two) signature schemes: 3895 | * RSASSA-PKCS1-v1_5 and RSASSA-PSS. 3896 | * 3897 | * By default this implementation uses the "old scheme", i.e. 3898 | * RSASSA-PKCS1-v1_5, in which case once RSA-decrypted, the 3899 | * signature is an OCTET STRING that holds a DigestInfo. 3900 | * 3901 | * DigestInfo ::= SEQUENCE { 3902 | * digestAlgorithm DigestAlgorithmIdentifier, 3903 | * digest Digest 3904 | * } 3905 | * DigestAlgorithmIdentifier ::= AlgorithmIdentifier 3906 | * Digest ::= OCTET STRING 3907 | * 3908 | * To perform PSS signature verification, provide an instance 3909 | * of Forge PSS object as scheme parameter. 3910 | * 3911 | * @param digest the message digest hash to compare against the signature. 3912 | * @param signature the signature to verify. 3913 | * @param scheme signature scheme to use, undefined for PKCS#1 v1.5 3914 | * padding style. 3915 | * @return true if the signature was verified, false if not. 3916 | */ 3917 | key.verify = function(digest, signature, scheme) { 3918 | // do rsa decryption 3919 | var ml = scheme === undefined ? undefined : false; 3920 | var d = pki.rsa.decrypt(signature, key, true, ml); 3921 | 3922 | if(scheme === undefined) { 3923 | // d is ASN.1 BER-encoded DigestInfo 3924 | var obj = asn1.fromDer(d); 3925 | 3926 | // compare the given digest to the decrypted one 3927 | return digest === obj.value[1].value; 3928 | } 3929 | else { 3930 | return scheme.verify(digest, d, key.n.bitLength()); 3931 | } 3932 | }; 3933 | 3934 | return key; 3935 | }; 3936 | 3937 | /** 3938 | * pki.rsa.stepKeyPairGenerationState 3939 | */ 3940 | 3941 | var GCD_30_DELTA = [6, 4, 2, 4, 2, 4, 6, 2]; 3942 | 3943 | pki.rsa.stepKeyPairGenerationState = function(state, n) { 3944 | // do key generation (based on Tom Wu's rsa.js, see jsbn.js license) 3945 | // with some minor optimizations and designed to run in steps 3946 | 3947 | // local state vars 3948 | var THIRTY = new BigInteger(null); 3949 | THIRTY.fromInt(30); 3950 | var deltaIdx = 0; 3951 | var op_or = function(x,y) { return x|y; }; 3952 | 3953 | // keep stepping until time limit is reached or done 3954 | var t1 = +new Date(); 3955 | var t2; 3956 | var total = 0; 3957 | while(state.keys === null && (n <= 0 || total < n)) { 3958 | // generate p or q 3959 | if(state.state === 0) { 3960 | /* Note: All primes are of the form: 3961 | 3962 | 30k+i, for i < 30 and gcd(30, i)=1, where there are 8 values for i 3963 | 3964 | When we generate a random number, we always align it at 30k + 1. Each 3965 | time the number is determined not to be prime we add to get to the 3966 | next 'i', eg: if the number was at 30k + 1 we add 6. */ 3967 | var bits = (state.p === null) ? state.pBits : state.qBits; 3968 | var bits1 = bits - 1; 3969 | 3970 | // get a random number 3971 | if(state.pqState === 0) { 3972 | state.num = new BigInteger(bits, state.rng); 3973 | // force MSB set 3974 | if(!state.num.testBit(bits1)) { 3975 | state.num.bitwiseTo( 3976 | BigInteger.ONE.shiftLeft(bits1), op_or, state.num); 3977 | } 3978 | // align number on 30k+1 boundary 3979 | state.num.dAddOffset(31 - state.num.mod(THIRTY).byteValue(), 0); 3980 | deltaIdx = 0; 3981 | 3982 | ++state.pqState; 3983 | } 3984 | // try to make the number a prime 3985 | else if(state.pqState === 1) { 3986 | // overflow, try again 3987 | if(state.num.bitLength() > bits) { 3988 | state.pqState = 0; 3989 | } 3990 | // do primality test 3991 | else if(state.num.isProbablePrime(1)) { 3992 | ++state.pqState; 3993 | } 3994 | else { 3995 | // get next potential prime 3996 | state.num.dAddOffset(GCD_30_DELTA[deltaIdx++ % 8], 0); 3997 | } 3998 | } 3999 | // ensure number is coprime with e 4000 | else if(state.pqState === 2) { 4001 | state.pqState = 4002 | (state.num.subtract(BigInteger.ONE).gcd(state.e) 4003 | .compareTo(BigInteger.ONE) === 0) ? 3 : 0; 4004 | } 4005 | // ensure number is a probable prime 4006 | else if(state.pqState === 3) { 4007 | state.pqState = 0; 4008 | if(state.num.isProbablePrime(10)) { 4009 | if(state.p === null) { 4010 | state.p = state.num; 4011 | } 4012 | else { 4013 | state.q = state.num; 4014 | } 4015 | 4016 | // advance state if both p and q are ready 4017 | if(state.p !== null && state.q !== null) { 4018 | ++state.state; 4019 | } 4020 | } 4021 | state.num = null; 4022 | } 4023 | } 4024 | // ensure p is larger than q (swap them if not) 4025 | else if(state.state === 1) { 4026 | if(state.p.compareTo(state.q) < 0) { 4027 | state.num = state.p; 4028 | state.p = state.q; 4029 | state.q = state.num; 4030 | } 4031 | ++state.state; 4032 | } 4033 | // compute phi: (p - 1)(q - 1) (Euler's totient function) 4034 | else if(state.state === 2) { 4035 | state.p1 = state.p.subtract(BigInteger.ONE); 4036 | state.q1 = state.q.subtract(BigInteger.ONE); 4037 | state.phi = state.p1.multiply(state.q1); 4038 | ++state.state; 4039 | } 4040 | // ensure e and phi are coprime 4041 | else if(state.state === 3) { 4042 | if(state.phi.gcd(state.e).compareTo(BigInteger.ONE) === 0) { 4043 | // phi and e are coprime, advance 4044 | ++state.state; 4045 | } 4046 | else { 4047 | // phi and e aren't coprime, so generate a new p and q 4048 | state.p = null; 4049 | state.q = null; 4050 | state.state = 0; 4051 | } 4052 | } 4053 | // create n, ensure n is has the right number of bits 4054 | else if(state.state === 4) { 4055 | state.n = state.p.multiply(state.q); 4056 | 4057 | // ensure n is right number of bits 4058 | if(state.n.bitLength() === state.bits) { 4059 | // success, advance 4060 | ++state.state; 4061 | } 4062 | else { 4063 | // failed, get new q 4064 | state.q = null; 4065 | state.state = 0; 4066 | } 4067 | } 4068 | // set keys 4069 | else if(state.state === 5) { 4070 | var d = state.e.modInverse(state.phi); 4071 | state.keys = { 4072 | privateKey: forge.pki.rsa.setPrivateKey( 4073 | state.n, state.e, d, state.p, state.q, 4074 | d.mod(state.p1), d.mod(state.q1), 4075 | state.q.modInverse(state.p)), 4076 | publicKey: forge.pki.rsa.setPublicKey(state.n, state.e) 4077 | }; 4078 | } 4079 | 4080 | // update timing 4081 | t2 = +new Date(); 4082 | total += t2 - t1; 4083 | t1 = t2; 4084 | } 4085 | 4086 | return state.keys !== null; 4087 | }; 4088 | 4089 | /** 4090 | * _generateKeyPair 4091 | */ 4092 | 4093 | function _generateKeyPair(state, options, callback) { 4094 | if(typeof options === 'function') { 4095 | callback = options; 4096 | options = {}; 4097 | } 4098 | 4099 | // web workers unavailable, use setImmediate 4100 | if(false || typeof(Worker) === 'undefined') { 4101 | function step() { 4102 | // 10 ms gives 5ms of leeway for other calculations before dropping 4103 | // below 60fps (1000/60 == 16.67), but in reality, the number will 4104 | // likely be higher due to an 'atomic' big int modPow 4105 | if(forge.pki.rsa.stepKeyPairGenerationState(state, 10)) { 4106 | return callback(null, state.keys); 4107 | } 4108 | forge.util.setImmediate(step); 4109 | } 4110 | return step(); 4111 | } 4112 | 4113 | // use web workers to generate keys 4114 | var numWorkers = options.workers || 2; 4115 | var workLoad = options.workLoad || 100; 4116 | var range = workLoad * 30/8; 4117 | var workerScript = options.workerScript || 'forge/prime.worker.js'; 4118 | var THIRTY = new BigInteger(null); 4119 | THIRTY.fromInt(30); 4120 | var op_or = function(x,y) { return x|y; }; 4121 | generate(); 4122 | 4123 | function generate() { 4124 | // find p and then q (done in series to simplify setting worker number) 4125 | getPrime(state.pBits, function(err, num) { 4126 | if(err) { 4127 | return callback(err); 4128 | } 4129 | state.p = num; 4130 | getPrime(state.qBits, finish); 4131 | }); 4132 | } 4133 | 4134 | // implement prime number generation using web workers 4135 | function getPrime(bits, callback) { 4136 | // TODO: consider optimizing by starting workers outside getPrime() ... 4137 | // note that in order to clean up they will have to be made internally 4138 | // asynchronous which may actually be slower 4139 | 4140 | // start workers immediately 4141 | var workers = []; 4142 | for(var i = 0; i < numWorkers; ++i) { 4143 | // FIXME: fix path or use blob URLs 4144 | workers[i] = new Worker(workerScript); 4145 | } 4146 | var running = numWorkers; 4147 | 4148 | // initialize random number 4149 | var num = generateRandom(); 4150 | 4151 | // listen for requests from workers and assign ranges to find prime 4152 | for(var i = 0; i < numWorkers; ++i) { 4153 | workers[i].addEventListener('message', workerMessage); 4154 | } 4155 | 4156 | /* Note: The distribution of random numbers is unknown. Therefore, each 4157 | web worker is continuously allocated a range of numbers to check for a 4158 | random number until one is found. 4159 | 4160 | Every 30 numbers will be checked just 8 times, because prime numbers 4161 | have the form: 4162 | 4163 | 30k+i, for i < 30 and gcd(30, i)=1 (there are 8 values of i for this) 4164 | 4165 | Therefore, if we want a web worker to run N checks before asking for 4166 | a new range of numbers, each range must contain N*30/8 numbers. 4167 | 4168 | For 100 checks (workLoad), this is a range of 375. */ 4169 | 4170 | function generateRandom() { 4171 | var bits1 = bits - 1; 4172 | var num = new BigInteger(bits, state.rng); 4173 | // force MSB set 4174 | if(!num.testBit(bits1)) { 4175 | num.bitwiseTo(BigInteger.ONE.shiftLeft(bits1), op_or, num); 4176 | } 4177 | // align number on 30k+1 boundary 4178 | num.dAddOffset(31 - num.mod(THIRTY).byteValue(), 0); 4179 | return num; 4180 | } 4181 | 4182 | var found = false; 4183 | function workerMessage(e) { 4184 | // ignore message, prime already found 4185 | if(found) { 4186 | return; 4187 | } 4188 | 4189 | --running; 4190 | var data = e.data; 4191 | if(data.found) { 4192 | // terminate all workers 4193 | for(var i = 0; i < workers.length; ++i) { 4194 | workers[i].terminate(); 4195 | } 4196 | found = true; 4197 | return callback(null, new BigInteger(data.prime, 16)); 4198 | } 4199 | 4200 | // overflow, regenerate prime 4201 | if(num.bitLength() > bits) { 4202 | num = generateRandom(); 4203 | } 4204 | 4205 | // assign new range to check 4206 | var hex = num.toString(16); 4207 | 4208 | // start prime search 4209 | e.target.postMessage({ 4210 | e: state.eInt, 4211 | hex: hex, 4212 | workLoad: workLoad 4213 | }); 4214 | 4215 | num.dAddOffset(range, 0); 4216 | } 4217 | } 4218 | 4219 | function finish(err, num) { 4220 | // set q 4221 | state.q = num; 4222 | 4223 | // ensure p is larger than q (swap them if not) 4224 | if(state.p.compareTo(state.q) < 0) { 4225 | var tmp = state.p; 4226 | state.p = state.q; 4227 | state.q = tmp; 4228 | } 4229 | 4230 | // compute phi: (p - 1)(q - 1) (Euler's totient function) 4231 | state.p1 = state.p.subtract(BigInteger.ONE); 4232 | state.q1 = state.q.subtract(BigInteger.ONE); 4233 | state.phi = state.p1.multiply(state.q1); 4234 | 4235 | // ensure e and phi are coprime 4236 | if(state.phi.gcd(state.e).compareTo(BigInteger.ONE) !== 0) { 4237 | // phi and e aren't coprime, so generate a new p and q 4238 | state.p = state.q = null; 4239 | generate(); 4240 | return; 4241 | } 4242 | 4243 | // create n, ensure n is has the right number of bits 4244 | state.n = state.p.multiply(state.q); 4245 | if(state.n.bitLength() !== state.bits) { 4246 | // failed, get new q 4247 | state.q = null; 4248 | getPrime(state.qBits, finish); 4249 | return; 4250 | } 4251 | 4252 | // set keys 4253 | var d = state.e.modInverse(state.phi); 4254 | state.keys = { 4255 | privateKey: forge.pki.rsa.setPrivateKey( 4256 | state.n, state.e, d, state.p, state.q, 4257 | d.mod(state.p1), d.mod(state.q1), 4258 | state.q.modInverse(state.p)), 4259 | publicKey: forge.pki.rsa.setPublicKey(state.n, state.e) 4260 | }; 4261 | 4262 | callback(null, state.keys); 4263 | } 4264 | } 4265 | 4266 | /** 4267 | * pki.rsa.generateKeyPair 4268 | */ 4269 | 4270 | pki.rsa.generateKeyPair = function(bits, e, options, callback) { 4271 | // (bits), (options), (callback) 4272 | if(arguments.length === 1) { 4273 | if(typeof bits === 'object') { 4274 | options = bits; 4275 | bits = undefined; 4276 | } 4277 | else if(typeof bits === 'function') { 4278 | callback = bits; 4279 | bits = undefined; 4280 | } 4281 | } 4282 | // (bits, options), (bits, callback), (options, callback) 4283 | else if(arguments.length === 2) { 4284 | if(typeof bits === 'number') { 4285 | if(typeof e === 'function') { 4286 | callback = e; 4287 | } 4288 | else { 4289 | options = e; 4290 | } 4291 | } 4292 | else { 4293 | options = bits; 4294 | callback = e; 4295 | bits = undefined; 4296 | } 4297 | e = undefined; 4298 | } 4299 | // (bits, e, options), (bits, e, callback), (bits, options, callback) 4300 | else if(arguments.length === 3) { 4301 | if(typeof e === 'number') { 4302 | if(typeof options === 'function') { 4303 | callback = options; 4304 | options = undefined; 4305 | } 4306 | } 4307 | else { 4308 | callback = options; 4309 | options = e; 4310 | e = undefined; 4311 | } 4312 | } 4313 | options = options || {}; 4314 | if(bits === undefined) { 4315 | bits = options.bits || 1024; 4316 | } 4317 | if(e === undefined) { 4318 | e = options.e || 0x10001; 4319 | } 4320 | var state = pki.rsa.createKeyPairGenerationState(bits, e); 4321 | if(!callback) { 4322 | pki.rsa.stepKeyPairGenerationState(state, 0); 4323 | return state.keys; 4324 | } 4325 | _generateKeyPair(state, options, callback); 4326 | }; 4327 | 4328 | /** 4329 | * _bnToBytes 4330 | */ 4331 | 4332 | var _bnToBytes = function(b) { 4333 | // prepend 0x00 if first byte >= 0x80 4334 | var hex = b.toString(16); 4335 | if(hex[0] >= '8') { 4336 | hex = '00' + hex; 4337 | } 4338 | return forge.util.hexToBytes(hex); 4339 | }; 4340 | 4341 | /** 4342 | * pki.publicKeyToRSAPublicKey 4343 | */ 4344 | 4345 | pki.publicKeyToRSAPublicKey = function(key) { 4346 | // RSAPublicKey 4347 | return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ 4348 | // modulus (n) 4349 | asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, 4350 | _bnToBytes(key.n)), 4351 | // publicExponent (e) 4352 | asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, 4353 | _bnToBytes(key.e)) 4354 | ]); 4355 | }; 4356 | 4357 | /** 4358 | * util.encode64 4359 | */ 4360 | 4361 | var _base64 = 4362 | 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; 4363 | 4364 | util.encode64 = function(input, maxline) { 4365 | var line = ''; 4366 | var output = ''; 4367 | var chr1, chr2, chr3; 4368 | var i = 0; 4369 | while(i < input.length) { 4370 | chr1 = input.charCodeAt(i++); 4371 | chr2 = input.charCodeAt(i++); 4372 | chr3 = input.charCodeAt(i++); 4373 | 4374 | // encode 4 character group 4375 | line += _base64.charAt(chr1 >> 2); 4376 | line += _base64.charAt(((chr1 & 3) << 4) | (chr2 >> 4)); 4377 | if(isNaN(chr2)) { 4378 | line += '=='; 4379 | } 4380 | else { 4381 | line += _base64.charAt(((chr2 & 15) << 2) | (chr3 >> 6)); 4382 | line += isNaN(chr3) ? '=' : _base64.charAt(chr3 & 63); 4383 | } 4384 | 4385 | if(maxline && line.length > maxline) { 4386 | output += line.substr(0, maxline) + '\r\n'; 4387 | line = line.substr(maxline); 4388 | } 4389 | } 4390 | output += line; 4391 | 4392 | return output; 4393 | }; 4394 | 4395 | /** 4396 | * pki.publicKeyToRSAPublicKeyPem 4397 | */ 4398 | 4399 | pki.publicKeyToRSAPublicKeyPem = function(key, maxline) { 4400 | // convert to ASN.1, then DER, then base64-encode 4401 | var out = asn1.toDer(pki.publicKeyToRSAPublicKey(key)); 4402 | out = forge.util.encode64(out.getBytes(), maxline || 64); 4403 | return ( 4404 | '-----BEGIN RSA PUBLIC KEY-----\r\n' + 4405 | out + 4406 | '\r\n-----END RSA PUBLIC KEY-----'); 4407 | }; 4408 | 4409 | /** 4410 | * pki.privateKeyToAsn1 4411 | */ 4412 | 4413 | pki.privateKeyToAsn1 = pki.privateKeyToRSAPrivateKey = function(key) { 4414 | // RSAPrivateKey 4415 | return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ 4416 | // version (0 = only 2 primes, 1 multiple primes) 4417 | asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, 4418 | String.fromCharCode(0x00)), 4419 | // modulus (n) 4420 | asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, 4421 | _bnToBytes(key.n)), 4422 | // publicExponent (e) 4423 | asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, 4424 | _bnToBytes(key.e)), 4425 | // privateExponent (d) 4426 | asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, 4427 | _bnToBytes(key.d)), 4428 | // privateKeyPrime1 (p) 4429 | asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, 4430 | _bnToBytes(key.p)), 4431 | // privateKeyPrime2 (q) 4432 | asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, 4433 | _bnToBytes(key.q)), 4434 | // privateKeyExponent1 (dP) 4435 | asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, 4436 | _bnToBytes(key.dP)), 4437 | // privateKeyExponent2 (dQ) 4438 | asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, 4439 | _bnToBytes(key.dQ)), 4440 | // coefficient (qInv) 4441 | asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, 4442 | _bnToBytes(key.qInv)) 4443 | ]); 4444 | }; 4445 | 4446 | /** 4447 | * pki.privateKeyToPem 4448 | */ 4449 | 4450 | pki.privateKeyToPem = function(key, maxline) { 4451 | // convert to ASN.1, then DER, then base64-encode 4452 | var out = asn1.toDer(pki.privateKeyToAsn1(key)); 4453 | out = forge.util.encode64(out.getBytes(), maxline || 64); 4454 | return ( 4455 | '-----BEGIN RSA PRIVATE KEY-----\r\n' + 4456 | out + 4457 | '\r\n-----END RSA PRIVATE KEY-----'); 4458 | }; 4459 | --------------------------------------------------------------------------------