From a7f2e0ca01582cb3e909d26c01ce7d7a6eadfd06 Mon Sep 17 00:00:00 2001 From: Mauve Date: Tue, 8 Sep 2026 17:20:27 +0800 Subject: [PATCH] first commit --- .hbuilderx/launch.json | 38 + App.vue | 661 ++ api/approvalApi.js | 9 + api/bookingApi.js | 11 + api/commonApi.js | 6 + api/configApi.js | 12 + api/mgmApi.js | 3 + api/notification.js | 9 + api/ssoApi.js | 4 + api/todoApi.js | 8 + booking/bookingConfirm/bookingConfirm.vue | 1885 +++++ booking/bookingDetail/bookingDetail.vue | 2080 +++++ booking/bookingGroup/bookingGroup.vue | 195 + booking/bookingRecord/bookingRecord.vue | 579 ++ booking/multipleDate/multipleDate.vue | 389 + booking/newBooking/newBooking.vue | 1636 ++++ booking/newWaitlist/newWaitlist.vue | 655 ++ booking/submitBooking/submitBooking.vue | 1994 +++++ common/cfgSettingCrypto.js | 187 + common/config.js | 39 + common/fixedCoordinateConverter.js | 324 + common/mapping.js | 41 + common/request.js | 201 + common/stringUtils.js | 160 + components/header/header.vue | 112 + components/p-checkbox/p-checkbox.vue | 78 + .../playerInfoForBooking.vue | 20 + .../simple-watermark/simple-watermark.vue | 122 + index.html | 20 + locale/en.json | 323 + locale/index.js | 7 + locale/zh-Hant.json | 259 + main.js | 122 + manifest.json | 166 + .../ios/NetworkUtils.framework/Info.plist | Bin 0 -> 756 bytes .../ios/NetworkUtils.framework/NetworkUtils | Bin 0 -> 69216 bytes nativeplugins/NetworkUtils/package.json | 18 + node_modules/.package-lock.json | 14 + node_modules/@noble/ciphers/LICENSE | 22 + node_modules/@noble/ciphers/README.md | 607 ++ node_modules/@noble/ciphers/_arx.d.ts | 145 + node_modules/@noble/ciphers/_arx.d.ts.map | 1 + node_modules/@noble/ciphers/_arx.js | 369 + node_modules/@noble/ciphers/_arx.js.map | 1 + node_modules/@noble/ciphers/_poly1305.d.ts | 73 + .../@noble/ciphers/_poly1305.d.ts.map | 1 + node_modules/@noble/ciphers/_poly1305.js | 364 + node_modules/@noble/ciphers/_poly1305.js.map | 1 + node_modules/@noble/ciphers/_polyval.d.ts | 121 + node_modules/@noble/ciphers/_polyval.d.ts.map | 1 + node_modules/@noble/ciphers/_polyval.js | 330 + node_modules/@noble/ciphers/_polyval.js.map | 1 + node_modules/@noble/ciphers/aes.d.ts | 462 ++ node_modules/@noble/ciphers/aes.d.ts.map | 1 + node_modules/@noble/ciphers/aes.js | 1765 +++++ node_modules/@noble/ciphers/aes.js.map | 1 + node_modules/@noble/ciphers/chacha.d.ts | 249 + node_modules/@noble/ciphers/chacha.d.ts.map | 1 + node_modules/@noble/ciphers/chacha.js | 575 ++ node_modules/@noble/ciphers/chacha.js.map | 1 + node_modules/@noble/ciphers/ff1.d.ts | 40 + node_modules/@noble/ciphers/ff1.d.ts.map | 1 + node_modules/@noble/ciphers/ff1.js | 204 + node_modules/@noble/ciphers/ff1.js.map | 1 + node_modules/@noble/ciphers/index.d.ts | 2 + node_modules/@noble/ciphers/index.d.ts.map | 1 + node_modules/@noble/ciphers/index.js | 27 + node_modules/@noble/ciphers/index.js.map | 1 + node_modules/@noble/ciphers/package.json | 85 + node_modules/@noble/ciphers/salsa.d.ts | 115 + node_modules/@noble/ciphers/salsa.d.ts.map | 1 + node_modules/@noble/ciphers/salsa.js | 371 + node_modules/@noble/ciphers/salsa.js.map | 1 + node_modules/@noble/ciphers/src/_arx.ts | 499 ++ node_modules/@noble/ciphers/src/_poly1305.ts | 399 + node_modules/@noble/ciphers/src/_polyval.ts | 381 + node_modules/@noble/ciphers/src/aes.ts | 2018 +++++ node_modules/@noble/ciphers/src/chacha.ts | 579 ++ node_modules/@noble/ciphers/src/ff1.ts | 221 + node_modules/@noble/ciphers/src/index.ts | 25 + node_modules/@noble/ciphers/src/salsa.ts | 374 + node_modules/@noble/ciphers/src/utils.ts | 1191 +++ node_modules/@noble/ciphers/src/webcrypto.ts | 226 + node_modules/@noble/ciphers/utils.d.ts | 717 ++ node_modules/@noble/ciphers/utils.d.ts.map | 1 + node_modules/@noble/ciphers/utils.js | 807 ++ node_modules/@noble/ciphers/utils.js.map | 1 + node_modules/@noble/ciphers/webcrypto.d.ts | 89 + .../@noble/ciphers/webcrypto.d.ts.map | 1 + node_modules/@noble/ciphers/webcrypto.js | 167 + node_modules/@noble/ciphers/webcrypto.js.map | 1 + node_modules/@noble/hashes/LICENSE | 21 + node_modules/@noble/hashes/README.md | 563 ++ node_modules/@noble/hashes/_blake.d.ts | 21 + node_modules/@noble/hashes/_blake.d.ts.map | 1 + node_modules/@noble/hashes/_blake.js | 52 + node_modules/@noble/hashes/_blake.js.map | 1 + node_modules/@noble/hashes/_md.d.ts | 99 + node_modules/@noble/hashes/_md.d.ts.map | 1 + node_modules/@noble/hashes/_md.js | 202 + node_modules/@noble/hashes/_md.js.map | 1 + node_modules/@noble/hashes/_u64.d.ts | 63 + node_modules/@noble/hashes/_u64.d.ts.map | 1 + node_modules/@noble/hashes/_u64.js | 84 + node_modules/@noble/hashes/_u64.js.map | 1 + node_modules/@noble/hashes/argon2.d.ts | 112 + node_modules/@noble/hashes/argon2.d.ts.map | 1 + node_modules/@noble/hashes/argon2.js | 517 ++ node_modules/@noble/hashes/argon2.js.map | 1 + node_modules/@noble/hashes/blake1.d.ts | 156 + node_modules/@noble/hashes/blake1.d.ts.map | 1 + node_modules/@noble/hashes/blake1.js | 560 ++ node_modules/@noble/hashes/blake1.js.map | 1 + node_modules/@noble/hashes/blake2.d.ts | 184 + node_modules/@noble/hashes/blake2.d.ts.map | 1 + node_modules/@noble/hashes/blake2.js | 501 ++ node_modules/@noble/hashes/blake2.js.map | 1 + node_modules/@noble/hashes/blake3.d.ts | 68 + node_modules/@noble/hashes/blake3.d.ts.map | 1 + node_modules/@noble/hashes/blake3.js | 284 + node_modules/@noble/hashes/blake3.js.map | 1 + node_modules/@noble/hashes/eskdf.d.ts | 92 + node_modules/@noble/hashes/eskdf.d.ts.map | 1 + node_modules/@noble/hashes/eskdf.js | 218 + node_modules/@noble/hashes/eskdf.js.map | 1 + node_modules/@noble/hashes/hkdf.d.ts | 64 + node_modules/@noble/hashes/hkdf.d.ts.map | 1 + node_modules/@noble/hashes/hkdf.js | 120 + node_modules/@noble/hashes/hkdf.js.map | 1 + node_modules/@noble/hashes/hmac.d.ts | 47 + node_modules/@noble/hashes/hmac.d.ts.map | 1 + node_modules/@noble/hashes/hmac.js | 93 + node_modules/@noble/hashes/hmac.js.map | 1 + node_modules/@noble/hashes/index.d.ts | 2 + node_modules/@noble/hashes/index.d.ts.map | 1 + node_modules/@noble/hashes/index.js | 35 + node_modules/@noble/hashes/index.js.map | 1 + node_modules/@noble/hashes/legacy.d.ts | 102 + node_modules/@noble/hashes/legacy.d.ts.map | 1 + node_modules/@noble/hashes/legacy.js | 327 + node_modules/@noble/hashes/legacy.js.map | 1 + node_modules/@noble/hashes/package.json | 97 + node_modules/@noble/hashes/pbkdf2.d.ts | 56 + node_modules/@noble/hashes/pbkdf2.d.ts.map | 1 + node_modules/@noble/hashes/pbkdf2.js | 135 + node_modules/@noble/hashes/pbkdf2.js.map | 1 + node_modules/@noble/hashes/scrypt.d.ts | 65 + node_modules/@noble/hashes/scrypt.d.ts.map | 1 + node_modules/@noble/hashes/scrypt.js | 257 + node_modules/@noble/hashes/scrypt.js.map | 1 + node_modules/@noble/hashes/sha2.d.ts | 249 + node_modules/@noble/hashes/sha2.d.ts.map | 1 + node_modules/@noble/hashes/sha2.js | 458 ++ node_modules/@noble/hashes/sha2.js.map | 1 + node_modules/@noble/hashes/sha3-addons.d.ts | 461 ++ .../@noble/hashes/sha3-addons.d.ts.map | 1 + node_modules/@noble/hashes/sha3-addons.js | 783 ++ node_modules/@noble/hashes/sha3-addons.js.map | 1 + node_modules/@noble/hashes/sha3.d.ts | 199 + node_modules/@noble/hashes/sha3.d.ts.map | 1 + node_modules/@noble/hashes/sha3.js | 431 ++ node_modules/@noble/hashes/sha3.js.map | 1 + node_modules/@noble/hashes/src/_blake.ts | 57 + node_modules/@noble/hashes/src/_md.ts | 222 + node_modules/@noble/hashes/src/_u64.ts | 117 + node_modules/@noble/hashes/src/argon2.ts | 667 ++ node_modules/@noble/hashes/src/blake1.ts | 614 ++ node_modules/@noble/hashes/src/blake2.ts | 582 ++ node_modules/@noble/hashes/src/blake3.ts | 317 + node_modules/@noble/hashes/src/eskdf.ts | 259 + node_modules/@noble/hashes/src/hkdf.ts | 133 + node_modules/@noble/hashes/src/hmac.ts | 126 + node_modules/@noble/hashes/src/index.ts | 33 + node_modules/@noble/hashes/src/legacy.ts | 339 + node_modules/@noble/hashes/src/pbkdf2.ts | 175 + node_modules/@noble/hashes/src/scrypt.ts | 315 + node_modules/@noble/hashes/src/sha2.ts | 530 ++ node_modules/@noble/hashes/src/sha3-addons.ts | 983 +++ node_modules/@noble/hashes/src/sha3.ts | 485 ++ node_modules/@noble/hashes/src/utils.ts | 848 +++ node_modules/@noble/hashes/src/webcrypto.ts | 239 + node_modules/@noble/hashes/utils.d.ts | 519 ++ node_modules/@noble/hashes/utils.d.ts.map | 1 + node_modules/@noble/hashes/utils.js | 578 ++ node_modules/@noble/hashes/utils.js.map | 1 + node_modules/@noble/hashes/webcrypto.d.ts | 120 + node_modules/@noble/hashes/webcrypto.d.ts.map | 1 + node_modules/@noble/hashes/webcrypto.js | 165 + node_modules/@noble/hashes/webcrypto.js.map | 1 + node_modules/crypto-js/CONTRIBUTING.md | 28 + node_modules/crypto-js/LICENSE | 24 + node_modules/crypto-js/README.md | 275 + node_modules/crypto-js/aes.js | 234 + node_modules/crypto-js/blowfish.js | 471 ++ node_modules/crypto-js/bower.json | 39 + node_modules/crypto-js/cipher-core.js | 895 +++ node_modules/crypto-js/core.js | 807 ++ node_modules/crypto-js/crypto-js.js | 6657 +++++++++++++++++ .../crypto-js/docs/QuickStartGuide.wiki | 470 ++ node_modules/crypto-js/enc-base64.js | 136 + node_modules/crypto-js/enc-base64url.js | 148 + node_modules/crypto-js/enc-hex.js | 18 + node_modules/crypto-js/enc-latin1.js | 18 + node_modules/crypto-js/enc-utf16.js | 149 + node_modules/crypto-js/enc-utf8.js | 18 + node_modules/crypto-js/evpkdf.js | 134 + node_modules/crypto-js/format-hex.js | 66 + node_modules/crypto-js/format-openssl.js | 18 + node_modules/crypto-js/hmac-md5.js | 18 + node_modules/crypto-js/hmac-ripemd160.js | 18 + node_modules/crypto-js/hmac-sha1.js | 18 + node_modules/crypto-js/hmac-sha224.js | 18 + node_modules/crypto-js/hmac-sha256.js | 18 + node_modules/crypto-js/hmac-sha3.js | 18 + node_modules/crypto-js/hmac-sha384.js | 18 + node_modules/crypto-js/hmac-sha512.js | 18 + node_modules/crypto-js/hmac.js | 143 + node_modules/crypto-js/index.js | 18 + node_modules/crypto-js/lib-typedarrays.js | 76 + node_modules/crypto-js/md5.js | 268 + node_modules/crypto-js/mode-cfb.js | 80 + node_modules/crypto-js/mode-ctr-gladman.js | 116 + node_modules/crypto-js/mode-ctr.js | 58 + node_modules/crypto-js/mode-ecb.js | 40 + node_modules/crypto-js/mode-ofb.js | 54 + node_modules/crypto-js/package.json | 42 + node_modules/crypto-js/pad-ansix923.js | 49 + node_modules/crypto-js/pad-iso10126.js | 44 + node_modules/crypto-js/pad-iso97971.js | 40 + node_modules/crypto-js/pad-nopadding.js | 30 + node_modules/crypto-js/pad-pkcs7.js | 18 + node_modules/crypto-js/pad-zeropadding.js | 47 + node_modules/crypto-js/pbkdf2.js | 145 + node_modules/crypto-js/rabbit-legacy.js | 190 + node_modules/crypto-js/rabbit.js | 192 + node_modules/crypto-js/rc4.js | 139 + node_modules/crypto-js/ripemd160.js | 267 + node_modules/crypto-js/sha1.js | 150 + node_modules/crypto-js/sha224.js | 80 + node_modules/crypto-js/sha256.js | 199 + node_modules/crypto-js/sha3.js | 326 + node_modules/crypto-js/sha384.js | 83 + node_modules/crypto-js/sha512.js | 326 + node_modules/crypto-js/tripledes.js | 779 ++ node_modules/crypto-js/x64-core.js | 304 + package-lock.json | 21 + package.json | 18 + pages.json | 300 + pages/approval/approval.vue | 597 ++ pages/azureLogin/azureLogin.vue | 81 + pages/azureLogout/azureLogout.vue | 84 + pages/dashboard/dashboard.vue | 311 + pages/disableApp/disableApp.vue | 48 + pages/findPlayer/findPlayer.vue | 235 + pages/idpLogin/idpLogin.vue | 112 + pages/login/login.vue | 408 + pages/notification/notification.vue | 235 + pages/playerDetail/playerDetail.vue | 986 +++ pages/regionRestrict/regionRestrict.vue | 96 + pages/roomCount/roomCount.vue | 75 + pages/samlLogin/samlLogin.vue | 92 + pages/setting/setting.vue | 454 ++ pages/ssoLogin/ssoLogin.vue | 150 + salessupport/todoList/todoList.vue | 1646 ++++ static/css/custom.scss | 448 ++ static/css/font_3379718_ey1vmrktwg7.ttf | Bin 0 -> 35152 bytes static/css/iconfont.css | 742 ++ static/css/todo.scss | 400 + static/fonts/Inter-Bold.otf | Bin 0 -> 271436 bytes static/fonts/Inter-ExtraLight.otf | Bin 0 -> 264196 bytes static/fonts/Inter-Light.otf | Bin 0 -> 265000 bytes static/fonts/Inter-Medium.otf | Bin 0 -> 269692 bytes static/fonts/Inter-Regular.otf | Bin 0 -> 258992 bytes static/fonts/font.css | 30 + static/fonts/font_3379718_ey1vmrktwg7.ttf | Bin 0 -> 35152 bytes static/images/160task01.png | Bin 0 -> 3321 bytes static/images/arrow_next.png | Bin 0 -> 2722 bytes static/images/arrow_next_active.png | Bin 0 -> 2808 bytes static/images/arrow_previous.png | Bin 0 -> 5008 bytes static/images/arrow_previous_active.png | Bin 0 -> 5539 bytes static/images/clearFilter.png | Bin 0 -> 676 bytes static/images/close.png | Bin 0 -> 746 bytes static/images/datanull.png | Bin 0 -> 17165 bytes static/images/edit.png | Bin 0 -> 1117 bytes static/images/edit_active.png | Bin 0 -> 1460 bytes static/images/err.png | Bin 0 -> 3155 bytes static/images/filter-clear.svg | 1 + static/images/filter_active.png | Bin 0 -> 1496 bytes static/images/filter_inactive.png | Bin 0 -> 1361 bytes static/images/find_player.png | Bin 0 -> 2200 bytes static/images/find_player.svg | 1 + static/images/flight_line.svg | 1 + static/images/flight_line_2.svg | 1 + static/images/ico_calendar.png | Bin 0 -> 343 bytes static/images/ico_calendar_grey.png | Bin 0 -> 1723 bytes static/images/ico_err.png | Bin 0 -> 1915 bytes static/images/ico_exit.png | Bin 0 -> 289 bytes static/images/ico_find_player.png | Bin 0 -> 632 bytes static/images/ico_find_player_active.png | Bin 0 -> 2001 bytes static/images/ico_home.png | Bin 0 -> 865 bytes static/images/ico_home_active.png | Bin 0 -> 2118 bytes static/images/ico_hotel.png | Bin 0 -> 322 bytes static/images/ico_hotel_active.png | Bin 0 -> 356 bytes static/images/ico_list.png | Bin 0 -> 382 bytes static/images/ico_night.png | Bin 0 -> 650 bytes static/images/ico_night_grey.png | Bin 0 -> 2181 bytes static/images/ico_room.png | Bin 0 -> 541 bytes static/images/ico_room_grey.png | Bin 0 -> 1961 bytes static/images/ico_set.png | Bin 0 -> 747 bytes static/images/ico_set_active.png | Bin 0 -> 1992 bytes static/images/ico_suc.png | Bin 0 -> 1985 bytes static/images/ico_todo.png | Bin 0 -> 672 bytes static/images/ico_todo_active.png | Bin 0 -> 846 bytes static/images/ico_warn.png | Bin 0 -> 594 bytes static/images/limo_line.svg | 1 + static/images/limo_line_2.svg | 1 + static/images/location_fail.png | Bin 0 -> 15950 bytes static/images/logo.png | Bin 0 -> 45248 bytes static/images/mgm_logo_1.png | Bin 0 -> 57027 bytes static/images/missing-face.png | Bin 0 -> 4379 bytes static/images/notification.png | Bin 0 -> 1187 bytes static/images/notification_active.png | Bin 0 -> 1523 bytes static/images/refresh.svg | 1 + static/images/room_book.png | Bin 0 -> 1131 bytes static/images/room_line.svg | 1 + static/images/room_line_2.svg | 1 + static/images/sharer_line.svg | 1 + static/images/sharer_line_2.svg | 1 + static/images/suc.png | Bin 0 -> 2847 bytes static/images/task.png | Bin 0 -> 2389 bytes static/images/temp.jpg | Bin 0 -> 5857 bytes static/images/time_line.svg | 1 + static/images/warn.png | Bin 0 -> 2984 bytes store/index.js | 72 + store/watermark.js | 212 + uni.promisify.adaptor.js | 10 + uni.scss | 105 + uni_modules/lu-data-select/changelog.md | 120 + .../lu-data-select/lu-data-select.vue | 1055 +++ .../components/lu-data-select/props.js | 106 + .../components/lu-data-select/utils.js | 68 + uni_modules/lu-data-select/package.json | 99 + uni_modules/lu-data-select/readme.md | 189 + uni_modules/uni-card/changelog.md | 26 + .../uni-card/components/uni-card/uni-card.vue | 269 + uni_modules/uni-card/package.json | 90 + uni_modules/uni-card/readme.md | 12 + uni_modules/uni-icons/changelog.md | 44 + .../components/uni-icons/uni-icons.uvue | 91 + .../components/uni-icons/uni-icons.vue | 110 + .../components/uni-icons/uniicons.css | 664 ++ .../components/uni-icons/uniicons.ttf | Bin 0 -> 35824 bytes .../components/uni-icons/uniicons_file.ts | 664 ++ .../components/uni-icons/uniicons_file_vue.js | 649 ++ uni_modules/uni-icons/package.json | 111 + uni_modules/uni-icons/readme.md | 8 + uni_modules/uni-scss/changelog.md | 8 + uni_modules/uni-scss/index.scss | 1 + uni_modules/uni-scss/package.json | 82 + uni_modules/uni-scss/readme.md | 4 + uni_modules/uni-scss/styles/index.scss | 7 + .../uni-scss/styles/setting/_border.scss | 3 + .../uni-scss/styles/setting/_color.scss | 66 + .../uni-scss/styles/setting/_radius.scss | 55 + .../uni-scss/styles/setting/_space.scss | 56 + .../uni-scss/styles/setting/_styles.scss | 167 + .../uni-scss/styles/setting/_text.scss | 24 + .../uni-scss/styles/setting/_variables.scss | 146 + .../uni-scss/styles/tools/functions.scss | 19 + uni_modules/uni-scss/theme.scss | 31 + uni_modules/uni-scss/variables.scss | 62 + uni_modules/uni-swipe-action/changelog.md | 58 + .../uni-swipe-action-item/bindingx.js | 302 + .../components/uni-swipe-action-item/isPC.js | 12 + .../uni-swipe-action-item/mpalipay.js | 195 + .../uni-swipe-action-item/mpother.js | 260 + .../components/uni-swipe-action-item/mpwxs.js | 84 + .../uni-swipe-action-item/render.js | 277 + .../uni-swipe-action-item.vue | 347 + .../components/uni-swipe-action-item/wx.wxs | 349 + .../uni-swipe-action/uni-swipe-action.vue | 60 + uni_modules/uni-swipe-action/package.json | 112 + uni_modules/uni-swipe-action/readme.md | 11 + uni_modules/uview-ui/LICENSE | 21 + uni_modules/uview-ui/README.md | 66 + uni_modules/uview-ui/changelog.md | 374 + .../uview-ui/components/u--form/u--form.vue | 78 + .../uview-ui/components/u--image/u--image.vue | 47 + .../uview-ui/components/u--input/u--input.vue | 73 + .../uview-ui/components/u--text/u--text.vue | 44 + .../components/u--textarea/u--textarea.vue | 48 + .../components/u-action-sheet/props.js | 54 + .../u-action-sheet/u-action-sheet.vue | 278 + .../uview-ui/components/u-album/props.js | 59 + .../uview-ui/components/u-album/u-album.vue | 259 + .../uview-ui/components/u-alert/props.js | 44 + .../uview-ui/components/u-alert/u-alert.vue | 243 + .../components/u-avatar-group/props.js | 52 + .../u-avatar-group/u-avatar-group.vue | 103 + .../uview-ui/components/u-avatar/props.js | 78 + .../uview-ui/components/u-avatar/u-avatar.vue | 173 + .../uview-ui/components/u-back-top/props.js | 54 + .../components/u-back-top/u-back-top.vue | 129 + .../uview-ui/components/u-badge/props.js | 72 + .../uview-ui/components/u-badge/u-badge.vue | 171 + .../uview-ui/components/u-button/nvue.scss | 46 + .../uview-ui/components/u-button/props.js | 161 + .../uview-ui/components/u-button/u-button.vue | 495 ++ .../uview-ui/components/u-button/vue.scss | 80 + .../uview-ui/components/u-calendar/header.vue | 105 + .../uview-ui/components/u-calendar/month.vue | 722 ++ .../uview-ui/components/u-calendar/props.js | 154 + .../components/u-calendar/u-calendar.vue | 443 ++ .../uview-ui/components/u-calendar/util.js | 85 + .../components/u-car-keyboard/props.js | 14 + .../u-car-keyboard/u-car-keyboard.vue | 311 + .../uview-ui/components/u-cell-group/props.js | 14 + .../components/u-cell-group/u-cell-group.vue | 61 + .../uview-ui/components/u-cell/props.js | 110 + .../uview-ui/components/u-cell/u-cell.vue | 229 + .../components/u-checkbox-group/props.js | 82 + .../u-checkbox-group/u-checkbox-group.vue | 103 + .../uview-ui/components/u-checkbox/props.js | 69 + .../components/u-checkbox/u-checkbox.vue | 344 + .../components/u-circle-progress/props.js | 8 + .../u-circle-progress/u-circle-progress.vue | 198 + .../uview-ui/components/u-code-input/props.js | 84 + .../components/u-code-input/u-code-input.vue | 258 + .../uview-ui/components/u-code/props.js | 34 + .../uview-ui/components/u-code/u-code.vue | 129 + .../uview-ui/components/u-col/props.js | 29 + .../uview-ui/components/u-col/u-col.vue | 162 + .../components/u-collapse-item/props.js | 59 + .../u-collapse-item/u-collapse-item.vue | 225 + .../uview-ui/components/u-collapse/props.js | 19 + .../components/u-collapse/u-collapse.vue | 90 + .../components/u-column-notice/props.js | 55 + .../u-column-notice/u-column-notice.vue | 160 + .../uview-ui/components/u-count-down/props.js | 24 + .../components/u-count-down/u-count-down.vue | 163 + .../uview-ui/components/u-count-down/utils.js | 62 + .../uview-ui/components/u-count-to/props.js | 59 + .../components/u-count-to/u-count-to.vue | 184 + .../components/u-datetime-picker/props.js | 116 + .../u-datetime-picker/u-datetime-picker.vue | 360 + .../uview-ui/components/u-divider/props.js | 44 + .../components/u-divider/u-divider.vue | 116 + .../components/u-dropdown-item/props.js | 36 + .../u-dropdown-item/u-dropdown-item.vue | 127 + .../uview-ui/components/u-dropdown/props.js | 65 + .../components/u-dropdown/u-dropdown.vue | 127 + .../uview-ui/components/u-empty/props.js | 59 + .../uview-ui/components/u-empty/u-empty.vue | 128 + .../uview-ui/components/u-form-item/props.js | 48 + .../components/u-form-item/u-form-item.vue | 235 + .../uview-ui/components/u-form/props.js | 45 + .../uview-ui/components/u-form/u-form.vue | 214 + .../uview-ui/components/u-gap/props.js | 24 + .../uview-ui/components/u-gap/u-gap.vue | 38 + .../uview-ui/components/u-grid-item/props.js | 14 + .../components/u-grid-item/u-grid-item.vue | 209 + .../uview-ui/components/u-grid/props.js | 19 + .../uview-ui/components/u-grid/u-grid.vue | 97 + .../u-icon/font_2225171_8kdcwk4po24.ttf | Bin 0 -> 55940 bytes .../uview-ui/components/u-icon/icons.js | 214 + .../uview-ui/components/u-icon/props.js | 89 + .../uview-ui/components/u-icon/u-icon.vue | 235 + .../uview-ui/components/u-image/props.js | 84 + .../uview-ui/components/u-image/u-image.vue | 232 + .../components/u-index-anchor/props.js | 29 + .../u-index-anchor/u-index-anchor.vue | 91 + .../uview-ui/components/u-index-item/props.js | 5 + .../components/u-index-item/u-index-item.vue | 87 + .../uview-ui/components/u-index-list/props.js | 29 + .../components/u-index-list/u-index-list.vue | 440 ++ .../uview-ui/components/u-input/props.js | 187 + .../uview-ui/components/u-input/u-input.vue | 354 + .../uview-ui/components/u-keyboard/props.js | 84 + .../components/u-keyboard/u-keyboard.vue | 164 + .../components/u-line-progress/props.js | 32 + .../u-line-progress/u-line-progress.vue | 164 + .../uview-ui/components/u-line/props.js | 33 + .../uview-ui/components/u-line/u-line.vue | 62 + .../uview-ui/components/u-link/props.js | 39 + .../uview-ui/components/u-link/u-link.vue | 83 + .../uview-ui/components/u-list-item/props.js | 9 + .../components/u-list-item/u-list-item.vue | 116 + .../uview-ui/components/u-list/props.js | 76 + .../uview-ui/components/u-list/u-list.vue | 157 + .../components/u-loading-icon/props.js | 59 + .../u-loading-icon/u-loading-icon.vue | 343 + .../components/u-loading-page/props.js | 49 + .../u-loading-page/u-loading-page.vue | 115 + .../uview-ui/components/u-loadmore/props.js | 94 + .../components/u-loadmore/u-loadmore.vue | 150 + .../uview-ui/components/u-modal/props.js | 89 + .../uview-ui/components/u-modal/u-modal.vue | 228 + .../uview-ui/components/u-navbar/props.js | 84 + .../uview-ui/components/u-navbar/u-navbar.vue | 186 + .../uview-ui/components/u-no-network/props.js | 19 + .../components/u-no-network/u-no-network.vue | 220 + .../uview-ui/components/u-notice-bar/props.js | 70 + .../components/u-notice-bar/u-notice-bar.vue | 101 + .../uview-ui/components/u-notify/props.js | 49 + .../uview-ui/components/u-notify/u-notify.vue | 211 + .../uview-ui/components/u-number-box/props.js | 109 + .../components/u-number-box/u-number-box.vue | 416 + .../components/u-number-keyboard/props.js | 19 + .../u-number-keyboard/u-number-keyboard.vue | 196 + .../uview-ui/components/u-overlay/props.js | 24 + .../components/u-overlay/u-overlay.vue | 68 + .../uview-ui/components/u-parse/node/node.vue | 499 ++ .../uview-ui/components/u-parse/parser.js | 1075 +++ .../uview-ui/components/u-parse/props.js | 45 + .../uview-ui/components/u-parse/u-parse.vue | 366 + .../components/u-picker-column/props.js | 5 + .../u-picker-column/u-picker-column.vue | 27 + .../uview-ui/components/u-picker/props.js | 79 + .../uview-ui/components/u-picker/u-picker.vue | 286 + .../uview-ui/components/u-popup/props.js | 79 + .../uview-ui/components/u-popup/u-popup.vue | 304 + .../components/u-radio-group/props.js | 85 + .../u-radio-group/u-radio-group.vue | 108 + .../uview-ui/components/u-radio/props.js | 64 + .../uview-ui/components/u-radio/u-radio.vue | 339 + .../uview-ui/components/u-rate/props.js | 69 + .../uview-ui/components/u-rate/u-rate.vue | 306 + .../uview-ui/components/u-read-more/props.js | 61 + .../components/u-read-more/u-read-more.vue | 157 + .../uview-ui/components/u-row-notice/props.js | 39 + .../components/u-row-notice/u-row-notice.vue | 330 + .../uview-ui/components/u-row/props.js | 19 + .../uview-ui/components/u-row/u-row.vue | 93 + .../components/u-safe-bottom/props.js | 5 + .../u-safe-bottom/u-safe-bottom.vue | 56 + .../uview-ui/components/u-scroll-list/nvue.js | 28 + .../components/u-scroll-list/other.js | 0 .../components/u-scroll-list/props.js | 34 + .../components/u-scroll-list/scrollWxs.wxs | 50 + .../u-scroll-list/u-scroll-list.vue | 224 + .../uview-ui/components/u-search/props.js | 118 + .../uview-ui/components/u-search/u-search.vue | 304 + .../uview-ui/components/u-skeleton/props.js | 59 + .../components/u-skeleton/u-skeleton.vue | 244 + .../uview-ui/components/u-slider/mpother.js | 113 + .../uview-ui/components/u-slider/mpwxs.js | 42 + .../uview-ui/components/u-slider/mpwxs.wxs | 121 + .../components/u-slider/nvue - 副本.js | 180 + .../uview-ui/components/u-slider/nvue.js | 193 + .../uview-ui/components/u-slider/props.js | 54 + .../uview-ui/components/u-slider/u-slider.vue | 55 + .../uview-ui/components/u-status-bar/props.js | 8 + .../components/u-status-bar/u-status-bar.vue | 46 + .../uview-ui/components/u-steps-item/props.js | 24 + .../components/u-steps-item/u-steps-item.vue | 316 + .../uview-ui/components/u-steps/props.js | 39 + .../uview-ui/components/u-steps/u-steps.vue | 80 + .../uview-ui/components/u-sticky/props.js | 40 + .../uview-ui/components/u-sticky/u-sticky.vue | 212 + .../uview-ui/components/u-subsection/props.js | 49 + .../components/u-subsection/u-subsection.vue | 299 + .../u-swipe-action-item/index - backup.wxs | 256 + .../components/u-swipe-action-item/index.wxs | 225 + .../u-swipe-action-item/nvue - backup.js | 270 + .../components/u-swipe-action-item/nvue.js | 174 + .../components/u-swipe-action-item/props.js | 41 + .../u-swipe-action-item.vue | 190 + .../components/u-swipe-action-item/wxs.js | 15 + .../components/u-swipe-action/props.js | 9 + .../u-swipe-action/u-swipe-action.vue | 67 + .../components/u-swiper-indicator/props.js | 29 + .../u-swiper-indicator/u-swiper-indicator.vue | 110 + .../uview-ui/components/u-swiper/props.js | 125 + .../uview-ui/components/u-swiper/u-swiper.vue | 255 + .../uview-ui/components/u-switch/props.js | 54 + .../uview-ui/components/u-switch/u-switch.vue | 177 + .../components/u-tabbar-item/props.js | 35 + .../u-tabbar-item/u-tabbar-item.vue | 142 + .../uview-ui/components/u-tabbar/props.js | 44 + .../uview-ui/components/u-tabbar/u-tabbar.vue | 141 + .../uview-ui/components/u-table/props.js | 5 + .../uview-ui/components/u-table/u-table.vue | 29 + .../uview-ui/components/u-tabs-item/props.js | 5 + .../components/u-tabs-item/u-tabs-item.vue | 29 + .../uview-ui/components/u-tabs/props.js | 64 + .../uview-ui/components/u-tabs/u-tabs.vue | 363 + .../uview-ui/components/u-tag/props.js | 84 + .../uview-ui/components/u-tag/u-tag.vue | 358 + uni_modules/uview-ui/components/u-td/props.js | 5 + uni_modules/uview-ui/components/u-td/u-td.vue | 31 + .../uview-ui/components/u-text/props.js | 110 + .../uview-ui/components/u-text/u-text.vue | 223 + .../uview-ui/components/u-text/value.js | 85 + .../uview-ui/components/u-textarea/props.js | 119 + .../components/u-textarea/u-textarea.vue | 239 + .../uview-ui/components/u-toast/u-toast.vue | 291 + .../uview-ui/components/u-toolbar/props.js | 34 + .../components/u-toolbar/u-toolbar.vue | 102 + .../components/u-tooltip/clipboard.min.js | 58 + .../uview-ui/components/u-tooltip/props.js | 59 + .../components/u-tooltip/u-tooltip.vue | 365 + uni_modules/uview-ui/components/u-tr/props.js | 5 + uni_modules/uview-ui/components/u-tr/u-tr.vue | 31 + .../components/u-transition/nvue.ani-map.js | 68 + .../uview-ui/components/u-transition/props.js | 24 + .../components/u-transition/transition.js | 157 + .../components/u-transition/u-transition.vue | 92 + .../u-transition/vue.ani-style.scss | 113 + .../uview-ui/components/u-upload/mixin.js | 21 + .../uview-ui/components/u-upload/props.js | 124 + .../uview-ui/components/u-upload/u-upload.vue | 558 ++ .../uview-ui/components/u-upload/utils.js | 151 + .../uview-ui/components/uview-ui/uview-ui.vue | 15 + uni_modules/uview-ui/index.js | 79 + uni_modules/uview-ui/index.scss | 23 + uni_modules/uview-ui/libs/config/color.js | 17 + uni_modules/uview-ui/libs/config/config.js | 34 + uni_modules/uview-ui/libs/config/props.js | 190 + .../uview-ui/libs/config/props/actionSheet.js | 25 + .../uview-ui/libs/config/props/album.js | 25 + .../uview-ui/libs/config/props/alert.js | 22 + .../uview-ui/libs/config/props/avatar.js | 28 + .../uview-ui/libs/config/props/avatarGroup.js | 23 + .../uview-ui/libs/config/props/backtop.js | 27 + .../uview-ui/libs/config/props/badge.js | 27 + .../uview-ui/libs/config/props/button.js | 42 + .../uview-ui/libs/config/props/calendar.js | 42 + .../uview-ui/libs/config/props/carKeyboard.js | 15 + .../uview-ui/libs/config/props/cell.js | 35 + .../uview-ui/libs/config/props/cellGroup.js | 17 + .../uview-ui/libs/config/props/checkbox.js | 27 + .../libs/config/props/checkboxGroup.js | 29 + .../libs/config/props/circleProgress.js | 15 + .../uview-ui/libs/config/props/code.js | 21 + .../uview-ui/libs/config/props/codeInput.js | 29 + uni_modules/uview-ui/libs/config/props/col.js | 19 + .../uview-ui/libs/config/props/collapse.js | 17 + .../libs/config/props/collapseItem.js | 25 + .../libs/config/props/columnNotice.js | 24 + .../uview-ui/libs/config/props/countDown.js | 18 + .../uview-ui/libs/config/props/countTo.js | 25 + .../libs/config/props/datetimePicker.js | 36 + .../uview-ui/libs/config/props/divider.js | 23 + .../uview-ui/libs/config/props/empty.js | 26 + .../uview-ui/libs/config/props/form.js | 22 + .../uview-ui/libs/config/props/formItem.js | 23 + uni_modules/uview-ui/libs/config/props/gap.js | 19 + .../uview-ui/libs/config/props/grid.js | 17 + .../uview-ui/libs/config/props/gridItem.js | 16 + .../uview-ui/libs/config/props/icon.js | 36 + .../uview-ui/libs/config/props/image.js | 30 + .../uview-ui/libs/config/props/indexAnchor.js | 19 + .../uview-ui/libs/config/props/indexList.js | 19 + .../uview-ui/libs/config/props/input.js | 48 + .../uview-ui/libs/config/props/keyboard.js | 30 + .../uview-ui/libs/config/props/line.js | 20 + .../libs/config/props/lineProgress.js | 20 + .../uview-ui/libs/config/props/link.js | 26 + .../uview-ui/libs/config/props/list.js | 28 + .../uview-ui/libs/config/props/listItem.js | 15 + .../uview-ui/libs/config/props/loadingIcon.js | 30 + .../uview-ui/libs/config/props/loadingPage.js | 23 + .../uview-ui/libs/config/props/loadmore.js | 32 + .../uview-ui/libs/config/props/modal.js | 31 + .../uview-ui/libs/config/props/navbar.js | 32 + .../uview-ui/libs/config/props/noNetwork.js | 18 + .../uview-ui/libs/config/props/noticeBar.js | 27 + .../uview-ui/libs/config/props/notify.js | 22 + .../uview-ui/libs/config/props/numberBox.js | 35 + .../libs/config/props/numberKeyboard.js | 17 + .../uview-ui/libs/config/props/overlay.js | 18 + .../uview-ui/libs/config/props/parse.js | 22 + .../uview-ui/libs/config/props/picker.js | 29 + .../uview-ui/libs/config/props/popup.js | 29 + .../uview-ui/libs/config/props/radio.js | 27 + .../uview-ui/libs/config/props/radioGroup.js | 30 + .../uview-ui/libs/config/props/rate.js | 26 + .../uview-ui/libs/config/props/readMore.js | 22 + uni_modules/uview-ui/libs/config/props/row.js | 17 + .../uview-ui/libs/config/props/rowNotice.js | 21 + .../uview-ui/libs/config/props/scrollList.js | 20 + .../uview-ui/libs/config/props/search.js | 37 + .../uview-ui/libs/config/props/section.js | 24 + .../uview-ui/libs/config/props/skeleton.js | 25 + .../uview-ui/libs/config/props/slider.js | 25 + .../uview-ui/libs/config/props/statusBar.js | 15 + .../uview-ui/libs/config/props/steps.js | 21 + .../uview-ui/libs/config/props/stepsItem.js | 18 + .../uview-ui/libs/config/props/sticky.js | 20 + .../uview-ui/libs/config/props/subsection.js | 23 + .../uview-ui/libs/config/props/swipeAction.js | 15 + .../libs/config/props/swipeActionItem.js | 21 + .../uview-ui/libs/config/props/swiper.js | 39 + .../libs/config/props/swipterIndicator.js | 19 + .../uview-ui/libs/config/props/switch.js | 24 + .../uview-ui/libs/config/props/tabbar.js | 22 + .../uview-ui/libs/config/props/tabbarItem.js | 20 + .../uview-ui/libs/config/props/tabs.js | 32 + uni_modules/uview-ui/libs/config/props/tag.js | 29 + .../uview-ui/libs/config/props/text.js | 38 + .../uview-ui/libs/config/props/textarea.js | 36 + .../uview-ui/libs/config/props/toast.js | 30 + .../uview-ui/libs/config/props/toolbar.js | 21 + .../uview-ui/libs/config/props/tooltip.js | 25 + .../uview-ui/libs/config/props/transition.js | 18 + .../uview-ui/libs/config/props/upload.js | 36 + uni_modules/uview-ui/libs/config/zIndex.js | 20 + uni_modules/uview-ui/libs/css/color.scss | 155 + uni_modules/uview-ui/libs/css/common.scss | 97 + uni_modules/uview-ui/libs/css/components.scss | 15 + uni_modules/uview-ui/libs/css/flex.scss | 257 + uni_modules/uview-ui/libs/css/h5.scss | 0 uni_modules/uview-ui/libs/css/mixin.scss | 8 + uni_modules/uview-ui/libs/css/mp.scss | 0 uni_modules/uview-ui/libs/css/nvue.scss | 0 uni_modules/uview-ui/libs/css/vue.scss | 27 + .../uview-ui/libs/function/colorGradient.js | 134 + .../uview-ui/libs/function/debounce.js | 29 + uni_modules/uview-ui/libs/function/digit.js | 167 + uni_modules/uview-ui/libs/function/index.js | 731 ++ .../uview-ui/libs/function/platform.js | 75 + uni_modules/uview-ui/libs/function/test.js | 288 + .../uview-ui/libs/function/throttle.js | 30 + .../libs/luch-request/adapters/index.js | 97 + .../luch-request/core/InterceptorManager.js | 50 + .../libs/luch-request/core/Request.js | 198 + .../libs/luch-request/core/buildFullPath.js | 20 + .../libs/luch-request/core/defaults.js | 29 + .../libs/luch-request/core/dispatchRequest.js | 3 + .../libs/luch-request/core/mergeConfig.js | 103 + .../uview-ui/libs/luch-request/core/settle.js | 16 + .../libs/luch-request/helpers/buildURL.js | 69 + .../libs/luch-request/helpers/combineURLs.js | 14 + .../luch-request/helpers/isAbsoluteURL.js | 14 + .../uview-ui/libs/luch-request/index.d.ts | 116 + .../uview-ui/libs/luch-request/index.js | 3 + .../uview-ui/libs/luch-request/utils.js | 131 + .../uview-ui/libs/luch-request/utils/clone.js | 264 + uni_modules/uview-ui/libs/mixin/button.js | 13 + uni_modules/uview-ui/libs/mixin/mixin.js | 160 + uni_modules/uview-ui/libs/mixin/mpMixin.js | 8 + uni_modules/uview-ui/libs/mixin/mpShare.js | 13 + uni_modules/uview-ui/libs/mixin/openType.js | 25 + uni_modules/uview-ui/libs/mixin/style.js | 228 + uni_modules/uview-ui/libs/mixin/touch.js | 59 + .../uview-ui/libs/util/async-validator.js | 1343 ++++ uni_modules/uview-ui/libs/util/calendar.js | 546 ++ uni_modules/uview-ui/libs/util/dayjs.js | 308 + uni_modules/uview-ui/libs/util/emitter.js | 51 + uni_modules/uview-ui/libs/util/route.js | 124 + uni_modules/uview-ui/package.json | 84 + uni_modules/uview-ui/theme.scss | 44 + 752 files changed, 111259 insertions(+) create mode 100644 .hbuilderx/launch.json create mode 100644 App.vue create mode 100644 api/approvalApi.js create mode 100644 api/bookingApi.js create mode 100644 api/commonApi.js create mode 100644 api/configApi.js create mode 100644 api/mgmApi.js create mode 100644 api/notification.js create mode 100644 api/ssoApi.js create mode 100644 api/todoApi.js create mode 100644 booking/bookingConfirm/bookingConfirm.vue create mode 100644 booking/bookingDetail/bookingDetail.vue create mode 100644 booking/bookingGroup/bookingGroup.vue create mode 100644 booking/bookingRecord/bookingRecord.vue create mode 100644 booking/multipleDate/multipleDate.vue create mode 100644 booking/newBooking/newBooking.vue create mode 100644 booking/newWaitlist/newWaitlist.vue create mode 100644 booking/submitBooking/submitBooking.vue create mode 100644 common/cfgSettingCrypto.js create mode 100644 common/config.js create mode 100644 common/fixedCoordinateConverter.js create mode 100644 common/mapping.js create mode 100644 common/request.js create mode 100644 common/stringUtils.js create mode 100644 components/header/header.vue create mode 100644 components/p-checkbox/p-checkbox.vue create mode 100644 components/playerInfoForBooking/playerInfoForBooking.vue create mode 100644 components/simple-watermark/simple-watermark.vue create mode 100644 index.html create mode 100644 locale/en.json create mode 100644 locale/index.js create mode 100644 locale/zh-Hant.json create mode 100644 main.js create mode 100644 manifest.json create mode 100644 nativeplugins/NetworkUtils/ios/NetworkUtils.framework/Info.plist create mode 100644 nativeplugins/NetworkUtils/ios/NetworkUtils.framework/NetworkUtils create mode 100644 nativeplugins/NetworkUtils/package.json create mode 100644 node_modules/.package-lock.json create mode 100644 node_modules/@noble/ciphers/LICENSE create mode 100644 node_modules/@noble/ciphers/README.md create mode 100644 node_modules/@noble/ciphers/_arx.d.ts create mode 100644 node_modules/@noble/ciphers/_arx.d.ts.map create mode 100644 node_modules/@noble/ciphers/_arx.js create mode 100644 node_modules/@noble/ciphers/_arx.js.map create mode 100644 node_modules/@noble/ciphers/_poly1305.d.ts create mode 100644 node_modules/@noble/ciphers/_poly1305.d.ts.map create mode 100644 node_modules/@noble/ciphers/_poly1305.js create mode 100644 node_modules/@noble/ciphers/_poly1305.js.map create mode 100644 node_modules/@noble/ciphers/_polyval.d.ts create mode 100644 node_modules/@noble/ciphers/_polyval.d.ts.map create mode 100644 node_modules/@noble/ciphers/_polyval.js create mode 100644 node_modules/@noble/ciphers/_polyval.js.map create mode 100644 node_modules/@noble/ciphers/aes.d.ts create mode 100644 node_modules/@noble/ciphers/aes.d.ts.map create mode 100644 node_modules/@noble/ciphers/aes.js create mode 100644 node_modules/@noble/ciphers/aes.js.map create mode 100644 node_modules/@noble/ciphers/chacha.d.ts create mode 100644 node_modules/@noble/ciphers/chacha.d.ts.map create mode 100644 node_modules/@noble/ciphers/chacha.js create mode 100644 node_modules/@noble/ciphers/chacha.js.map create mode 100644 node_modules/@noble/ciphers/ff1.d.ts create mode 100644 node_modules/@noble/ciphers/ff1.d.ts.map create mode 100644 node_modules/@noble/ciphers/ff1.js create mode 100644 node_modules/@noble/ciphers/ff1.js.map create mode 100644 node_modules/@noble/ciphers/index.d.ts create mode 100644 node_modules/@noble/ciphers/index.d.ts.map create mode 100644 node_modules/@noble/ciphers/index.js create mode 100644 node_modules/@noble/ciphers/index.js.map create mode 100644 node_modules/@noble/ciphers/package.json create mode 100644 node_modules/@noble/ciphers/salsa.d.ts create mode 100644 node_modules/@noble/ciphers/salsa.d.ts.map create mode 100644 node_modules/@noble/ciphers/salsa.js create mode 100644 node_modules/@noble/ciphers/salsa.js.map create mode 100644 node_modules/@noble/ciphers/src/_arx.ts create mode 100644 node_modules/@noble/ciphers/src/_poly1305.ts create mode 100644 node_modules/@noble/ciphers/src/_polyval.ts create mode 100644 node_modules/@noble/ciphers/src/aes.ts create mode 100644 node_modules/@noble/ciphers/src/chacha.ts create mode 100644 node_modules/@noble/ciphers/src/ff1.ts create mode 100644 node_modules/@noble/ciphers/src/index.ts create mode 100644 node_modules/@noble/ciphers/src/salsa.ts create mode 100644 node_modules/@noble/ciphers/src/utils.ts create mode 100644 node_modules/@noble/ciphers/src/webcrypto.ts create mode 100644 node_modules/@noble/ciphers/utils.d.ts create mode 100644 node_modules/@noble/ciphers/utils.d.ts.map create mode 100644 node_modules/@noble/ciphers/utils.js create mode 100644 node_modules/@noble/ciphers/utils.js.map create mode 100644 node_modules/@noble/ciphers/webcrypto.d.ts create mode 100644 node_modules/@noble/ciphers/webcrypto.d.ts.map create mode 100644 node_modules/@noble/ciphers/webcrypto.js create mode 100644 node_modules/@noble/ciphers/webcrypto.js.map create mode 100644 node_modules/@noble/hashes/LICENSE create mode 100644 node_modules/@noble/hashes/README.md create mode 100644 node_modules/@noble/hashes/_blake.d.ts create mode 100644 node_modules/@noble/hashes/_blake.d.ts.map create mode 100644 node_modules/@noble/hashes/_blake.js create mode 100644 node_modules/@noble/hashes/_blake.js.map create mode 100644 node_modules/@noble/hashes/_md.d.ts create mode 100644 node_modules/@noble/hashes/_md.d.ts.map create mode 100644 node_modules/@noble/hashes/_md.js create mode 100644 node_modules/@noble/hashes/_md.js.map create mode 100644 node_modules/@noble/hashes/_u64.d.ts create mode 100644 node_modules/@noble/hashes/_u64.d.ts.map create mode 100644 node_modules/@noble/hashes/_u64.js create mode 100644 node_modules/@noble/hashes/_u64.js.map create mode 100644 node_modules/@noble/hashes/argon2.d.ts create mode 100644 node_modules/@noble/hashes/argon2.d.ts.map create mode 100644 node_modules/@noble/hashes/argon2.js create mode 100644 node_modules/@noble/hashes/argon2.js.map create mode 100644 node_modules/@noble/hashes/blake1.d.ts create mode 100644 node_modules/@noble/hashes/blake1.d.ts.map create mode 100644 node_modules/@noble/hashes/blake1.js create mode 100644 node_modules/@noble/hashes/blake1.js.map create mode 100644 node_modules/@noble/hashes/blake2.d.ts create mode 100644 node_modules/@noble/hashes/blake2.d.ts.map create mode 100644 node_modules/@noble/hashes/blake2.js create mode 100644 node_modules/@noble/hashes/blake2.js.map create mode 100644 node_modules/@noble/hashes/blake3.d.ts create mode 100644 node_modules/@noble/hashes/blake3.d.ts.map create mode 100644 node_modules/@noble/hashes/blake3.js create mode 100644 node_modules/@noble/hashes/blake3.js.map create mode 100644 node_modules/@noble/hashes/eskdf.d.ts create mode 100644 node_modules/@noble/hashes/eskdf.d.ts.map create mode 100644 node_modules/@noble/hashes/eskdf.js create mode 100644 node_modules/@noble/hashes/eskdf.js.map create mode 100644 node_modules/@noble/hashes/hkdf.d.ts create mode 100644 node_modules/@noble/hashes/hkdf.d.ts.map create mode 100644 node_modules/@noble/hashes/hkdf.js create mode 100644 node_modules/@noble/hashes/hkdf.js.map create mode 100644 node_modules/@noble/hashes/hmac.d.ts create mode 100644 node_modules/@noble/hashes/hmac.d.ts.map create mode 100644 node_modules/@noble/hashes/hmac.js create mode 100644 node_modules/@noble/hashes/hmac.js.map create mode 100644 node_modules/@noble/hashes/index.d.ts create mode 100644 node_modules/@noble/hashes/index.d.ts.map create mode 100644 node_modules/@noble/hashes/index.js create mode 100644 node_modules/@noble/hashes/index.js.map create mode 100644 node_modules/@noble/hashes/legacy.d.ts create mode 100644 node_modules/@noble/hashes/legacy.d.ts.map create mode 100644 node_modules/@noble/hashes/legacy.js create mode 100644 node_modules/@noble/hashes/legacy.js.map create mode 100644 node_modules/@noble/hashes/package.json create mode 100644 node_modules/@noble/hashes/pbkdf2.d.ts create mode 100644 node_modules/@noble/hashes/pbkdf2.d.ts.map create mode 100644 node_modules/@noble/hashes/pbkdf2.js create mode 100644 node_modules/@noble/hashes/pbkdf2.js.map create mode 100644 node_modules/@noble/hashes/scrypt.d.ts create mode 100644 node_modules/@noble/hashes/scrypt.d.ts.map create mode 100644 node_modules/@noble/hashes/scrypt.js create mode 100644 node_modules/@noble/hashes/scrypt.js.map create mode 100644 node_modules/@noble/hashes/sha2.d.ts create mode 100644 node_modules/@noble/hashes/sha2.d.ts.map create mode 100644 node_modules/@noble/hashes/sha2.js create mode 100644 node_modules/@noble/hashes/sha2.js.map create mode 100644 node_modules/@noble/hashes/sha3-addons.d.ts create mode 100644 node_modules/@noble/hashes/sha3-addons.d.ts.map create mode 100644 node_modules/@noble/hashes/sha3-addons.js create mode 100644 node_modules/@noble/hashes/sha3-addons.js.map create mode 100644 node_modules/@noble/hashes/sha3.d.ts create mode 100644 node_modules/@noble/hashes/sha3.d.ts.map create mode 100644 node_modules/@noble/hashes/sha3.js create mode 100644 node_modules/@noble/hashes/sha3.js.map create mode 100644 node_modules/@noble/hashes/src/_blake.ts create mode 100644 node_modules/@noble/hashes/src/_md.ts create mode 100644 node_modules/@noble/hashes/src/_u64.ts create mode 100644 node_modules/@noble/hashes/src/argon2.ts create mode 100644 node_modules/@noble/hashes/src/blake1.ts create mode 100644 node_modules/@noble/hashes/src/blake2.ts create mode 100644 node_modules/@noble/hashes/src/blake3.ts create mode 100644 node_modules/@noble/hashes/src/eskdf.ts create mode 100644 node_modules/@noble/hashes/src/hkdf.ts create mode 100644 node_modules/@noble/hashes/src/hmac.ts create mode 100644 node_modules/@noble/hashes/src/index.ts create mode 100644 node_modules/@noble/hashes/src/legacy.ts create mode 100644 node_modules/@noble/hashes/src/pbkdf2.ts create mode 100644 node_modules/@noble/hashes/src/scrypt.ts create mode 100644 node_modules/@noble/hashes/src/sha2.ts create mode 100644 node_modules/@noble/hashes/src/sha3-addons.ts create mode 100644 node_modules/@noble/hashes/src/sha3.ts create mode 100644 node_modules/@noble/hashes/src/utils.ts create mode 100644 node_modules/@noble/hashes/src/webcrypto.ts create mode 100644 node_modules/@noble/hashes/utils.d.ts create mode 100644 node_modules/@noble/hashes/utils.d.ts.map create mode 100644 node_modules/@noble/hashes/utils.js create mode 100644 node_modules/@noble/hashes/utils.js.map create mode 100644 node_modules/@noble/hashes/webcrypto.d.ts create mode 100644 node_modules/@noble/hashes/webcrypto.d.ts.map create mode 100644 node_modules/@noble/hashes/webcrypto.js create mode 100644 node_modules/@noble/hashes/webcrypto.js.map create mode 100644 node_modules/crypto-js/CONTRIBUTING.md create mode 100644 node_modules/crypto-js/LICENSE create mode 100644 node_modules/crypto-js/README.md create mode 100644 node_modules/crypto-js/aes.js create mode 100644 node_modules/crypto-js/blowfish.js create mode 100644 node_modules/crypto-js/bower.json create mode 100644 node_modules/crypto-js/cipher-core.js create mode 100644 node_modules/crypto-js/core.js create mode 100644 node_modules/crypto-js/crypto-js.js create mode 100644 node_modules/crypto-js/docs/QuickStartGuide.wiki create mode 100644 node_modules/crypto-js/enc-base64.js create mode 100644 node_modules/crypto-js/enc-base64url.js create mode 100644 node_modules/crypto-js/enc-hex.js create mode 100644 node_modules/crypto-js/enc-latin1.js create mode 100644 node_modules/crypto-js/enc-utf16.js create mode 100644 node_modules/crypto-js/enc-utf8.js create mode 100644 node_modules/crypto-js/evpkdf.js create mode 100644 node_modules/crypto-js/format-hex.js create mode 100644 node_modules/crypto-js/format-openssl.js create mode 100644 node_modules/crypto-js/hmac-md5.js create mode 100644 node_modules/crypto-js/hmac-ripemd160.js create mode 100644 node_modules/crypto-js/hmac-sha1.js create mode 100644 node_modules/crypto-js/hmac-sha224.js create mode 100644 node_modules/crypto-js/hmac-sha256.js create mode 100644 node_modules/crypto-js/hmac-sha3.js create mode 100644 node_modules/crypto-js/hmac-sha384.js create mode 100644 node_modules/crypto-js/hmac-sha512.js create mode 100644 node_modules/crypto-js/hmac.js create mode 100644 node_modules/crypto-js/index.js create mode 100644 node_modules/crypto-js/lib-typedarrays.js create mode 100644 node_modules/crypto-js/md5.js create mode 100644 node_modules/crypto-js/mode-cfb.js create mode 100644 node_modules/crypto-js/mode-ctr-gladman.js create mode 100644 node_modules/crypto-js/mode-ctr.js create mode 100644 node_modules/crypto-js/mode-ecb.js create mode 100644 node_modules/crypto-js/mode-ofb.js create mode 100644 node_modules/crypto-js/package.json create mode 100644 node_modules/crypto-js/pad-ansix923.js create mode 100644 node_modules/crypto-js/pad-iso10126.js create mode 100644 node_modules/crypto-js/pad-iso97971.js create mode 100644 node_modules/crypto-js/pad-nopadding.js create mode 100644 node_modules/crypto-js/pad-pkcs7.js create mode 100644 node_modules/crypto-js/pad-zeropadding.js create mode 100644 node_modules/crypto-js/pbkdf2.js create mode 100644 node_modules/crypto-js/rabbit-legacy.js create mode 100644 node_modules/crypto-js/rabbit.js create mode 100644 node_modules/crypto-js/rc4.js create mode 100644 node_modules/crypto-js/ripemd160.js create mode 100644 node_modules/crypto-js/sha1.js create mode 100644 node_modules/crypto-js/sha224.js create mode 100644 node_modules/crypto-js/sha256.js create mode 100644 node_modules/crypto-js/sha3.js create mode 100644 node_modules/crypto-js/sha384.js create mode 100644 node_modules/crypto-js/sha512.js create mode 100644 node_modules/crypto-js/tripledes.js create mode 100644 node_modules/crypto-js/x64-core.js create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 pages.json create mode 100644 pages/approval/approval.vue create mode 100644 pages/azureLogin/azureLogin.vue create mode 100644 pages/azureLogout/azureLogout.vue create mode 100644 pages/dashboard/dashboard.vue create mode 100644 pages/disableApp/disableApp.vue create mode 100644 pages/findPlayer/findPlayer.vue create mode 100644 pages/idpLogin/idpLogin.vue create mode 100644 pages/login/login.vue create mode 100644 pages/notification/notification.vue create mode 100644 pages/playerDetail/playerDetail.vue create mode 100644 pages/regionRestrict/regionRestrict.vue create mode 100644 pages/roomCount/roomCount.vue create mode 100644 pages/samlLogin/samlLogin.vue create mode 100644 pages/setting/setting.vue create mode 100644 pages/ssoLogin/ssoLogin.vue create mode 100644 salessupport/todoList/todoList.vue create mode 100644 static/css/custom.scss create mode 100644 static/css/font_3379718_ey1vmrktwg7.ttf create mode 100644 static/css/iconfont.css create mode 100644 static/css/todo.scss create mode 100644 static/fonts/Inter-Bold.otf create mode 100644 static/fonts/Inter-ExtraLight.otf create mode 100644 static/fonts/Inter-Light.otf create mode 100644 static/fonts/Inter-Medium.otf create mode 100644 static/fonts/Inter-Regular.otf create mode 100644 static/fonts/font.css create mode 100644 static/fonts/font_3379718_ey1vmrktwg7.ttf create mode 100644 static/images/160task01.png create mode 100644 static/images/arrow_next.png create mode 100644 static/images/arrow_next_active.png create mode 100644 static/images/arrow_previous.png create mode 100644 static/images/arrow_previous_active.png create mode 100644 static/images/clearFilter.png create mode 100644 static/images/close.png create mode 100644 static/images/datanull.png create mode 100644 static/images/edit.png create mode 100644 static/images/edit_active.png create mode 100644 static/images/err.png create mode 100644 static/images/filter-clear.svg create mode 100644 static/images/filter_active.png create mode 100644 static/images/filter_inactive.png create mode 100644 static/images/find_player.png create mode 100644 static/images/find_player.svg create mode 100644 static/images/flight_line.svg create mode 100644 static/images/flight_line_2.svg create mode 100644 static/images/ico_calendar.png create mode 100644 static/images/ico_calendar_grey.png create mode 100644 static/images/ico_err.png create mode 100644 static/images/ico_exit.png create mode 100644 static/images/ico_find_player.png create mode 100644 static/images/ico_find_player_active.png create mode 100644 static/images/ico_home.png create mode 100644 static/images/ico_home_active.png create mode 100644 static/images/ico_hotel.png create mode 100644 static/images/ico_hotel_active.png create mode 100644 static/images/ico_list.png create mode 100644 static/images/ico_night.png create mode 100644 static/images/ico_night_grey.png create mode 100644 static/images/ico_room.png create mode 100644 static/images/ico_room_grey.png create mode 100644 static/images/ico_set.png create mode 100644 static/images/ico_set_active.png create mode 100644 static/images/ico_suc.png create mode 100644 static/images/ico_todo.png create mode 100644 static/images/ico_todo_active.png create mode 100644 static/images/ico_warn.png create mode 100644 static/images/limo_line.svg create mode 100644 static/images/limo_line_2.svg create mode 100644 static/images/location_fail.png create mode 100644 static/images/logo.png create mode 100644 static/images/mgm_logo_1.png create mode 100644 static/images/missing-face.png create mode 100644 static/images/notification.png create mode 100644 static/images/notification_active.png create mode 100644 static/images/refresh.svg create mode 100644 static/images/room_book.png create mode 100644 static/images/room_line.svg create mode 100644 static/images/room_line_2.svg create mode 100644 static/images/sharer_line.svg create mode 100644 static/images/sharer_line_2.svg create mode 100644 static/images/suc.png create mode 100644 static/images/task.png create mode 100644 static/images/temp.jpg create mode 100644 static/images/time_line.svg create mode 100644 static/images/warn.png create mode 100644 store/index.js create mode 100644 store/watermark.js create mode 100644 uni.promisify.adaptor.js create mode 100644 uni.scss create mode 100644 uni_modules/lu-data-select/changelog.md create mode 100644 uni_modules/lu-data-select/components/lu-data-select/lu-data-select.vue create mode 100644 uni_modules/lu-data-select/components/lu-data-select/props.js create mode 100644 uni_modules/lu-data-select/components/lu-data-select/utils.js create mode 100644 uni_modules/lu-data-select/package.json create mode 100644 uni_modules/lu-data-select/readme.md create mode 100644 uni_modules/uni-card/changelog.md create mode 100644 uni_modules/uni-card/components/uni-card/uni-card.vue create mode 100644 uni_modules/uni-card/package.json create mode 100644 uni_modules/uni-card/readme.md create mode 100644 uni_modules/uni-icons/changelog.md create mode 100644 uni_modules/uni-icons/components/uni-icons/uni-icons.uvue create mode 100644 uni_modules/uni-icons/components/uni-icons/uni-icons.vue create mode 100644 uni_modules/uni-icons/components/uni-icons/uniicons.css create mode 100644 uni_modules/uni-icons/components/uni-icons/uniicons.ttf create mode 100644 uni_modules/uni-icons/components/uni-icons/uniicons_file.ts create mode 100644 uni_modules/uni-icons/components/uni-icons/uniicons_file_vue.js create mode 100644 uni_modules/uni-icons/package.json create mode 100644 uni_modules/uni-icons/readme.md create mode 100644 uni_modules/uni-scss/changelog.md create mode 100644 uni_modules/uni-scss/index.scss create mode 100644 uni_modules/uni-scss/package.json create mode 100644 uni_modules/uni-scss/readme.md create mode 100644 uni_modules/uni-scss/styles/index.scss create mode 100644 uni_modules/uni-scss/styles/setting/_border.scss create mode 100644 uni_modules/uni-scss/styles/setting/_color.scss create mode 100644 uni_modules/uni-scss/styles/setting/_radius.scss create mode 100644 uni_modules/uni-scss/styles/setting/_space.scss create mode 100644 uni_modules/uni-scss/styles/setting/_styles.scss create mode 100644 uni_modules/uni-scss/styles/setting/_text.scss create mode 100644 uni_modules/uni-scss/styles/setting/_variables.scss create mode 100644 uni_modules/uni-scss/styles/tools/functions.scss create mode 100644 uni_modules/uni-scss/theme.scss create mode 100644 uni_modules/uni-scss/variables.scss create mode 100644 uni_modules/uni-swipe-action/changelog.md create mode 100644 uni_modules/uni-swipe-action/components/uni-swipe-action-item/bindingx.js create mode 100644 uni_modules/uni-swipe-action/components/uni-swipe-action-item/isPC.js create mode 100644 uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpalipay.js create mode 100644 uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpother.js create mode 100644 uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpwxs.js create mode 100644 uni_modules/uni-swipe-action/components/uni-swipe-action-item/render.js create mode 100644 uni_modules/uni-swipe-action/components/uni-swipe-action-item/uni-swipe-action-item.vue create mode 100644 uni_modules/uni-swipe-action/components/uni-swipe-action-item/wx.wxs create mode 100644 uni_modules/uni-swipe-action/components/uni-swipe-action/uni-swipe-action.vue create mode 100644 uni_modules/uni-swipe-action/package.json create mode 100644 uni_modules/uni-swipe-action/readme.md create mode 100644 uni_modules/uview-ui/LICENSE create mode 100644 uni_modules/uview-ui/README.md create mode 100644 uni_modules/uview-ui/changelog.md create mode 100644 uni_modules/uview-ui/components/u--form/u--form.vue create mode 100644 uni_modules/uview-ui/components/u--image/u--image.vue create mode 100644 uni_modules/uview-ui/components/u--input/u--input.vue create mode 100644 uni_modules/uview-ui/components/u--text/u--text.vue create mode 100644 uni_modules/uview-ui/components/u--textarea/u--textarea.vue create mode 100644 uni_modules/uview-ui/components/u-action-sheet/props.js create mode 100644 uni_modules/uview-ui/components/u-action-sheet/u-action-sheet.vue create mode 100644 uni_modules/uview-ui/components/u-album/props.js create mode 100644 uni_modules/uview-ui/components/u-album/u-album.vue create mode 100644 uni_modules/uview-ui/components/u-alert/props.js create mode 100644 uni_modules/uview-ui/components/u-alert/u-alert.vue create mode 100644 uni_modules/uview-ui/components/u-avatar-group/props.js create mode 100644 uni_modules/uview-ui/components/u-avatar-group/u-avatar-group.vue create mode 100644 uni_modules/uview-ui/components/u-avatar/props.js create mode 100644 uni_modules/uview-ui/components/u-avatar/u-avatar.vue create mode 100644 uni_modules/uview-ui/components/u-back-top/props.js create mode 100644 uni_modules/uview-ui/components/u-back-top/u-back-top.vue create mode 100644 uni_modules/uview-ui/components/u-badge/props.js create mode 100644 uni_modules/uview-ui/components/u-badge/u-badge.vue create mode 100644 uni_modules/uview-ui/components/u-button/nvue.scss create mode 100644 uni_modules/uview-ui/components/u-button/props.js create mode 100644 uni_modules/uview-ui/components/u-button/u-button.vue create mode 100644 uni_modules/uview-ui/components/u-button/vue.scss create mode 100644 uni_modules/uview-ui/components/u-calendar/header.vue create mode 100644 uni_modules/uview-ui/components/u-calendar/month.vue create mode 100644 uni_modules/uview-ui/components/u-calendar/props.js create mode 100644 uni_modules/uview-ui/components/u-calendar/u-calendar.vue create mode 100644 uni_modules/uview-ui/components/u-calendar/util.js create mode 100644 uni_modules/uview-ui/components/u-car-keyboard/props.js create mode 100644 uni_modules/uview-ui/components/u-car-keyboard/u-car-keyboard.vue create mode 100644 uni_modules/uview-ui/components/u-cell-group/props.js create mode 100644 uni_modules/uview-ui/components/u-cell-group/u-cell-group.vue create mode 100644 uni_modules/uview-ui/components/u-cell/props.js create mode 100644 uni_modules/uview-ui/components/u-cell/u-cell.vue create mode 100644 uni_modules/uview-ui/components/u-checkbox-group/props.js create mode 100644 uni_modules/uview-ui/components/u-checkbox-group/u-checkbox-group.vue create mode 100644 uni_modules/uview-ui/components/u-checkbox/props.js create mode 100644 uni_modules/uview-ui/components/u-checkbox/u-checkbox.vue create mode 100644 uni_modules/uview-ui/components/u-circle-progress/props.js create mode 100644 uni_modules/uview-ui/components/u-circle-progress/u-circle-progress.vue create mode 100644 uni_modules/uview-ui/components/u-code-input/props.js create mode 100644 uni_modules/uview-ui/components/u-code-input/u-code-input.vue create mode 100644 uni_modules/uview-ui/components/u-code/props.js create mode 100644 uni_modules/uview-ui/components/u-code/u-code.vue create mode 100644 uni_modules/uview-ui/components/u-col/props.js create mode 100644 uni_modules/uview-ui/components/u-col/u-col.vue create mode 100644 uni_modules/uview-ui/components/u-collapse-item/props.js create mode 100644 uni_modules/uview-ui/components/u-collapse-item/u-collapse-item.vue create mode 100644 uni_modules/uview-ui/components/u-collapse/props.js create mode 100644 uni_modules/uview-ui/components/u-collapse/u-collapse.vue create mode 100644 uni_modules/uview-ui/components/u-column-notice/props.js create mode 100644 uni_modules/uview-ui/components/u-column-notice/u-column-notice.vue create mode 100644 uni_modules/uview-ui/components/u-count-down/props.js create mode 100644 uni_modules/uview-ui/components/u-count-down/u-count-down.vue create mode 100644 uni_modules/uview-ui/components/u-count-down/utils.js create mode 100644 uni_modules/uview-ui/components/u-count-to/props.js create mode 100644 uni_modules/uview-ui/components/u-count-to/u-count-to.vue create mode 100644 uni_modules/uview-ui/components/u-datetime-picker/props.js create mode 100644 uni_modules/uview-ui/components/u-datetime-picker/u-datetime-picker.vue create mode 100644 uni_modules/uview-ui/components/u-divider/props.js create mode 100644 uni_modules/uview-ui/components/u-divider/u-divider.vue create mode 100644 uni_modules/uview-ui/components/u-dropdown-item/props.js create mode 100644 uni_modules/uview-ui/components/u-dropdown-item/u-dropdown-item.vue create mode 100644 uni_modules/uview-ui/components/u-dropdown/props.js create mode 100644 uni_modules/uview-ui/components/u-dropdown/u-dropdown.vue create mode 100644 uni_modules/uview-ui/components/u-empty/props.js create mode 100644 uni_modules/uview-ui/components/u-empty/u-empty.vue create mode 100644 uni_modules/uview-ui/components/u-form-item/props.js create mode 100644 uni_modules/uview-ui/components/u-form-item/u-form-item.vue create mode 100644 uni_modules/uview-ui/components/u-form/props.js create mode 100644 uni_modules/uview-ui/components/u-form/u-form.vue create mode 100644 uni_modules/uview-ui/components/u-gap/props.js create mode 100644 uni_modules/uview-ui/components/u-gap/u-gap.vue create mode 100644 uni_modules/uview-ui/components/u-grid-item/props.js create mode 100644 uni_modules/uview-ui/components/u-grid-item/u-grid-item.vue create mode 100644 uni_modules/uview-ui/components/u-grid/props.js create mode 100644 uni_modules/uview-ui/components/u-grid/u-grid.vue create mode 100644 uni_modules/uview-ui/components/u-icon/font_2225171_8kdcwk4po24.ttf create mode 100644 uni_modules/uview-ui/components/u-icon/icons.js create mode 100644 uni_modules/uview-ui/components/u-icon/props.js create mode 100644 uni_modules/uview-ui/components/u-icon/u-icon.vue create mode 100644 uni_modules/uview-ui/components/u-image/props.js create mode 100644 uni_modules/uview-ui/components/u-image/u-image.vue create mode 100644 uni_modules/uview-ui/components/u-index-anchor/props.js create mode 100644 uni_modules/uview-ui/components/u-index-anchor/u-index-anchor.vue create mode 100644 uni_modules/uview-ui/components/u-index-item/props.js create mode 100644 uni_modules/uview-ui/components/u-index-item/u-index-item.vue create mode 100644 uni_modules/uview-ui/components/u-index-list/props.js create mode 100644 uni_modules/uview-ui/components/u-index-list/u-index-list.vue create mode 100644 uni_modules/uview-ui/components/u-input/props.js create mode 100644 uni_modules/uview-ui/components/u-input/u-input.vue create mode 100644 uni_modules/uview-ui/components/u-keyboard/props.js create mode 100644 uni_modules/uview-ui/components/u-keyboard/u-keyboard.vue create mode 100644 uni_modules/uview-ui/components/u-line-progress/props.js create mode 100644 uni_modules/uview-ui/components/u-line-progress/u-line-progress.vue create mode 100644 uni_modules/uview-ui/components/u-line/props.js create mode 100644 uni_modules/uview-ui/components/u-line/u-line.vue create mode 100644 uni_modules/uview-ui/components/u-link/props.js create mode 100644 uni_modules/uview-ui/components/u-link/u-link.vue create mode 100644 uni_modules/uview-ui/components/u-list-item/props.js create mode 100644 uni_modules/uview-ui/components/u-list-item/u-list-item.vue create mode 100644 uni_modules/uview-ui/components/u-list/props.js create mode 100644 uni_modules/uview-ui/components/u-list/u-list.vue create mode 100644 uni_modules/uview-ui/components/u-loading-icon/props.js create mode 100644 uni_modules/uview-ui/components/u-loading-icon/u-loading-icon.vue create mode 100644 uni_modules/uview-ui/components/u-loading-page/props.js create mode 100644 uni_modules/uview-ui/components/u-loading-page/u-loading-page.vue create mode 100644 uni_modules/uview-ui/components/u-loadmore/props.js create mode 100644 uni_modules/uview-ui/components/u-loadmore/u-loadmore.vue create mode 100644 uni_modules/uview-ui/components/u-modal/props.js create mode 100644 uni_modules/uview-ui/components/u-modal/u-modal.vue create mode 100644 uni_modules/uview-ui/components/u-navbar/props.js create mode 100644 uni_modules/uview-ui/components/u-navbar/u-navbar.vue create mode 100644 uni_modules/uview-ui/components/u-no-network/props.js create mode 100644 uni_modules/uview-ui/components/u-no-network/u-no-network.vue create mode 100644 uni_modules/uview-ui/components/u-notice-bar/props.js create mode 100644 uni_modules/uview-ui/components/u-notice-bar/u-notice-bar.vue create mode 100644 uni_modules/uview-ui/components/u-notify/props.js create mode 100644 uni_modules/uview-ui/components/u-notify/u-notify.vue create mode 100644 uni_modules/uview-ui/components/u-number-box/props.js create mode 100644 uni_modules/uview-ui/components/u-number-box/u-number-box.vue create mode 100644 uni_modules/uview-ui/components/u-number-keyboard/props.js create mode 100644 uni_modules/uview-ui/components/u-number-keyboard/u-number-keyboard.vue create mode 100644 uni_modules/uview-ui/components/u-overlay/props.js create mode 100644 uni_modules/uview-ui/components/u-overlay/u-overlay.vue create mode 100644 uni_modules/uview-ui/components/u-parse/node/node.vue create mode 100644 uni_modules/uview-ui/components/u-parse/parser.js create mode 100644 uni_modules/uview-ui/components/u-parse/props.js create mode 100644 uni_modules/uview-ui/components/u-parse/u-parse.vue create mode 100644 uni_modules/uview-ui/components/u-picker-column/props.js create mode 100644 uni_modules/uview-ui/components/u-picker-column/u-picker-column.vue create mode 100644 uni_modules/uview-ui/components/u-picker/props.js create mode 100644 uni_modules/uview-ui/components/u-picker/u-picker.vue create mode 100644 uni_modules/uview-ui/components/u-popup/props.js create mode 100644 uni_modules/uview-ui/components/u-popup/u-popup.vue create mode 100644 uni_modules/uview-ui/components/u-radio-group/props.js create mode 100644 uni_modules/uview-ui/components/u-radio-group/u-radio-group.vue create mode 100644 uni_modules/uview-ui/components/u-radio/props.js create mode 100644 uni_modules/uview-ui/components/u-radio/u-radio.vue create mode 100644 uni_modules/uview-ui/components/u-rate/props.js create mode 100644 uni_modules/uview-ui/components/u-rate/u-rate.vue create mode 100644 uni_modules/uview-ui/components/u-read-more/props.js create mode 100644 uni_modules/uview-ui/components/u-read-more/u-read-more.vue create mode 100644 uni_modules/uview-ui/components/u-row-notice/props.js create mode 100644 uni_modules/uview-ui/components/u-row-notice/u-row-notice.vue create mode 100644 uni_modules/uview-ui/components/u-row/props.js create mode 100644 uni_modules/uview-ui/components/u-row/u-row.vue create mode 100644 uni_modules/uview-ui/components/u-safe-bottom/props.js create mode 100644 uni_modules/uview-ui/components/u-safe-bottom/u-safe-bottom.vue create mode 100644 uni_modules/uview-ui/components/u-scroll-list/nvue.js create mode 100644 uni_modules/uview-ui/components/u-scroll-list/other.js create mode 100644 uni_modules/uview-ui/components/u-scroll-list/props.js create mode 100644 uni_modules/uview-ui/components/u-scroll-list/scrollWxs.wxs create mode 100644 uni_modules/uview-ui/components/u-scroll-list/u-scroll-list.vue create mode 100644 uni_modules/uview-ui/components/u-search/props.js create mode 100644 uni_modules/uview-ui/components/u-search/u-search.vue create mode 100644 uni_modules/uview-ui/components/u-skeleton/props.js create mode 100644 uni_modules/uview-ui/components/u-skeleton/u-skeleton.vue create mode 100644 uni_modules/uview-ui/components/u-slider/mpother.js create mode 100644 uni_modules/uview-ui/components/u-slider/mpwxs.js create mode 100644 uni_modules/uview-ui/components/u-slider/mpwxs.wxs create mode 100644 uni_modules/uview-ui/components/u-slider/nvue - 副本.js create mode 100644 uni_modules/uview-ui/components/u-slider/nvue.js create mode 100644 uni_modules/uview-ui/components/u-slider/props.js create mode 100644 uni_modules/uview-ui/components/u-slider/u-slider.vue create mode 100644 uni_modules/uview-ui/components/u-status-bar/props.js create mode 100644 uni_modules/uview-ui/components/u-status-bar/u-status-bar.vue create mode 100644 uni_modules/uview-ui/components/u-steps-item/props.js create mode 100644 uni_modules/uview-ui/components/u-steps-item/u-steps-item.vue create mode 100644 uni_modules/uview-ui/components/u-steps/props.js create mode 100644 uni_modules/uview-ui/components/u-steps/u-steps.vue create mode 100644 uni_modules/uview-ui/components/u-sticky/props.js create mode 100644 uni_modules/uview-ui/components/u-sticky/u-sticky.vue create mode 100644 uni_modules/uview-ui/components/u-subsection/props.js create mode 100644 uni_modules/uview-ui/components/u-subsection/u-subsection.vue create mode 100644 uni_modules/uview-ui/components/u-swipe-action-item/index - backup.wxs create mode 100644 uni_modules/uview-ui/components/u-swipe-action-item/index.wxs create mode 100644 uni_modules/uview-ui/components/u-swipe-action-item/nvue - backup.js create mode 100644 uni_modules/uview-ui/components/u-swipe-action-item/nvue.js create mode 100644 uni_modules/uview-ui/components/u-swipe-action-item/props.js create mode 100644 uni_modules/uview-ui/components/u-swipe-action-item/u-swipe-action-item.vue create mode 100644 uni_modules/uview-ui/components/u-swipe-action-item/wxs.js create mode 100644 uni_modules/uview-ui/components/u-swipe-action/props.js create mode 100644 uni_modules/uview-ui/components/u-swipe-action/u-swipe-action.vue create mode 100644 uni_modules/uview-ui/components/u-swiper-indicator/props.js create mode 100644 uni_modules/uview-ui/components/u-swiper-indicator/u-swiper-indicator.vue create mode 100644 uni_modules/uview-ui/components/u-swiper/props.js create mode 100644 uni_modules/uview-ui/components/u-swiper/u-swiper.vue create mode 100644 uni_modules/uview-ui/components/u-switch/props.js create mode 100644 uni_modules/uview-ui/components/u-switch/u-switch.vue create mode 100644 uni_modules/uview-ui/components/u-tabbar-item/props.js create mode 100644 uni_modules/uview-ui/components/u-tabbar-item/u-tabbar-item.vue create mode 100644 uni_modules/uview-ui/components/u-tabbar/props.js create mode 100644 uni_modules/uview-ui/components/u-tabbar/u-tabbar.vue create mode 100644 uni_modules/uview-ui/components/u-table/props.js create mode 100644 uni_modules/uview-ui/components/u-table/u-table.vue create mode 100644 uni_modules/uview-ui/components/u-tabs-item/props.js create mode 100644 uni_modules/uview-ui/components/u-tabs-item/u-tabs-item.vue create mode 100644 uni_modules/uview-ui/components/u-tabs/props.js create mode 100644 uni_modules/uview-ui/components/u-tabs/u-tabs.vue create mode 100644 uni_modules/uview-ui/components/u-tag/props.js create mode 100644 uni_modules/uview-ui/components/u-tag/u-tag.vue create mode 100644 uni_modules/uview-ui/components/u-td/props.js create mode 100644 uni_modules/uview-ui/components/u-td/u-td.vue create mode 100644 uni_modules/uview-ui/components/u-text/props.js create mode 100644 uni_modules/uview-ui/components/u-text/u-text.vue create mode 100644 uni_modules/uview-ui/components/u-text/value.js create mode 100644 uni_modules/uview-ui/components/u-textarea/props.js create mode 100644 uni_modules/uview-ui/components/u-textarea/u-textarea.vue create mode 100644 uni_modules/uview-ui/components/u-toast/u-toast.vue create mode 100644 uni_modules/uview-ui/components/u-toolbar/props.js create mode 100644 uni_modules/uview-ui/components/u-toolbar/u-toolbar.vue create mode 100644 uni_modules/uview-ui/components/u-tooltip/clipboard.min.js create mode 100644 uni_modules/uview-ui/components/u-tooltip/props.js create mode 100644 uni_modules/uview-ui/components/u-tooltip/u-tooltip.vue create mode 100644 uni_modules/uview-ui/components/u-tr/props.js create mode 100644 uni_modules/uview-ui/components/u-tr/u-tr.vue create mode 100644 uni_modules/uview-ui/components/u-transition/nvue.ani-map.js create mode 100644 uni_modules/uview-ui/components/u-transition/props.js create mode 100644 uni_modules/uview-ui/components/u-transition/transition.js create mode 100644 uni_modules/uview-ui/components/u-transition/u-transition.vue create mode 100644 uni_modules/uview-ui/components/u-transition/vue.ani-style.scss create mode 100644 uni_modules/uview-ui/components/u-upload/mixin.js create mode 100644 uni_modules/uview-ui/components/u-upload/props.js create mode 100644 uni_modules/uview-ui/components/u-upload/u-upload.vue create mode 100644 uni_modules/uview-ui/components/u-upload/utils.js create mode 100644 uni_modules/uview-ui/components/uview-ui/uview-ui.vue create mode 100644 uni_modules/uview-ui/index.js create mode 100644 uni_modules/uview-ui/index.scss create mode 100644 uni_modules/uview-ui/libs/config/color.js create mode 100644 uni_modules/uview-ui/libs/config/config.js create mode 100644 uni_modules/uview-ui/libs/config/props.js create mode 100644 uni_modules/uview-ui/libs/config/props/actionSheet.js create mode 100644 uni_modules/uview-ui/libs/config/props/album.js create mode 100644 uni_modules/uview-ui/libs/config/props/alert.js create mode 100644 uni_modules/uview-ui/libs/config/props/avatar.js create mode 100644 uni_modules/uview-ui/libs/config/props/avatarGroup.js create mode 100644 uni_modules/uview-ui/libs/config/props/backtop.js create mode 100644 uni_modules/uview-ui/libs/config/props/badge.js create mode 100644 uni_modules/uview-ui/libs/config/props/button.js create mode 100644 uni_modules/uview-ui/libs/config/props/calendar.js create mode 100644 uni_modules/uview-ui/libs/config/props/carKeyboard.js create mode 100644 uni_modules/uview-ui/libs/config/props/cell.js create mode 100644 uni_modules/uview-ui/libs/config/props/cellGroup.js create mode 100644 uni_modules/uview-ui/libs/config/props/checkbox.js create mode 100644 uni_modules/uview-ui/libs/config/props/checkboxGroup.js create mode 100644 uni_modules/uview-ui/libs/config/props/circleProgress.js create mode 100644 uni_modules/uview-ui/libs/config/props/code.js create mode 100644 uni_modules/uview-ui/libs/config/props/codeInput.js create mode 100644 uni_modules/uview-ui/libs/config/props/col.js create mode 100644 uni_modules/uview-ui/libs/config/props/collapse.js create mode 100644 uni_modules/uview-ui/libs/config/props/collapseItem.js create mode 100644 uni_modules/uview-ui/libs/config/props/columnNotice.js create mode 100644 uni_modules/uview-ui/libs/config/props/countDown.js create mode 100644 uni_modules/uview-ui/libs/config/props/countTo.js create mode 100644 uni_modules/uview-ui/libs/config/props/datetimePicker.js create mode 100644 uni_modules/uview-ui/libs/config/props/divider.js create mode 100644 uni_modules/uview-ui/libs/config/props/empty.js create mode 100644 uni_modules/uview-ui/libs/config/props/form.js create mode 100644 uni_modules/uview-ui/libs/config/props/formItem.js create mode 100644 uni_modules/uview-ui/libs/config/props/gap.js create mode 100644 uni_modules/uview-ui/libs/config/props/grid.js create mode 100644 uni_modules/uview-ui/libs/config/props/gridItem.js create mode 100644 uni_modules/uview-ui/libs/config/props/icon.js create mode 100644 uni_modules/uview-ui/libs/config/props/image.js create mode 100644 uni_modules/uview-ui/libs/config/props/indexAnchor.js create mode 100644 uni_modules/uview-ui/libs/config/props/indexList.js create mode 100644 uni_modules/uview-ui/libs/config/props/input.js create mode 100644 uni_modules/uview-ui/libs/config/props/keyboard.js create mode 100644 uni_modules/uview-ui/libs/config/props/line.js create mode 100644 uni_modules/uview-ui/libs/config/props/lineProgress.js create mode 100644 uni_modules/uview-ui/libs/config/props/link.js create mode 100644 uni_modules/uview-ui/libs/config/props/list.js create mode 100644 uni_modules/uview-ui/libs/config/props/listItem.js create mode 100644 uni_modules/uview-ui/libs/config/props/loadingIcon.js create mode 100644 uni_modules/uview-ui/libs/config/props/loadingPage.js create mode 100644 uni_modules/uview-ui/libs/config/props/loadmore.js create mode 100644 uni_modules/uview-ui/libs/config/props/modal.js create mode 100644 uni_modules/uview-ui/libs/config/props/navbar.js create mode 100644 uni_modules/uview-ui/libs/config/props/noNetwork.js create mode 100644 uni_modules/uview-ui/libs/config/props/noticeBar.js create mode 100644 uni_modules/uview-ui/libs/config/props/notify.js create mode 100644 uni_modules/uview-ui/libs/config/props/numberBox.js create mode 100644 uni_modules/uview-ui/libs/config/props/numberKeyboard.js create mode 100644 uni_modules/uview-ui/libs/config/props/overlay.js create mode 100644 uni_modules/uview-ui/libs/config/props/parse.js create mode 100644 uni_modules/uview-ui/libs/config/props/picker.js create mode 100644 uni_modules/uview-ui/libs/config/props/popup.js create mode 100644 uni_modules/uview-ui/libs/config/props/radio.js create mode 100644 uni_modules/uview-ui/libs/config/props/radioGroup.js create mode 100644 uni_modules/uview-ui/libs/config/props/rate.js create mode 100644 uni_modules/uview-ui/libs/config/props/readMore.js create mode 100644 uni_modules/uview-ui/libs/config/props/row.js create mode 100644 uni_modules/uview-ui/libs/config/props/rowNotice.js create mode 100644 uni_modules/uview-ui/libs/config/props/scrollList.js create mode 100644 uni_modules/uview-ui/libs/config/props/search.js create mode 100644 uni_modules/uview-ui/libs/config/props/section.js create mode 100644 uni_modules/uview-ui/libs/config/props/skeleton.js create mode 100644 uni_modules/uview-ui/libs/config/props/slider.js create mode 100644 uni_modules/uview-ui/libs/config/props/statusBar.js create mode 100644 uni_modules/uview-ui/libs/config/props/steps.js create mode 100644 uni_modules/uview-ui/libs/config/props/stepsItem.js create mode 100644 uni_modules/uview-ui/libs/config/props/sticky.js create mode 100644 uni_modules/uview-ui/libs/config/props/subsection.js create mode 100644 uni_modules/uview-ui/libs/config/props/swipeAction.js create mode 100644 uni_modules/uview-ui/libs/config/props/swipeActionItem.js create mode 100644 uni_modules/uview-ui/libs/config/props/swiper.js create mode 100644 uni_modules/uview-ui/libs/config/props/swipterIndicator.js create mode 100644 uni_modules/uview-ui/libs/config/props/switch.js create mode 100644 uni_modules/uview-ui/libs/config/props/tabbar.js create mode 100644 uni_modules/uview-ui/libs/config/props/tabbarItem.js create mode 100644 uni_modules/uview-ui/libs/config/props/tabs.js create mode 100644 uni_modules/uview-ui/libs/config/props/tag.js create mode 100644 uni_modules/uview-ui/libs/config/props/text.js create mode 100644 uni_modules/uview-ui/libs/config/props/textarea.js create mode 100644 uni_modules/uview-ui/libs/config/props/toast.js create mode 100644 uni_modules/uview-ui/libs/config/props/toolbar.js create mode 100644 uni_modules/uview-ui/libs/config/props/tooltip.js create mode 100644 uni_modules/uview-ui/libs/config/props/transition.js create mode 100644 uni_modules/uview-ui/libs/config/props/upload.js create mode 100644 uni_modules/uview-ui/libs/config/zIndex.js create mode 100644 uni_modules/uview-ui/libs/css/color.scss create mode 100644 uni_modules/uview-ui/libs/css/common.scss create mode 100644 uni_modules/uview-ui/libs/css/components.scss create mode 100644 uni_modules/uview-ui/libs/css/flex.scss create mode 100644 uni_modules/uview-ui/libs/css/h5.scss create mode 100644 uni_modules/uview-ui/libs/css/mixin.scss create mode 100644 uni_modules/uview-ui/libs/css/mp.scss create mode 100644 uni_modules/uview-ui/libs/css/nvue.scss create mode 100644 uni_modules/uview-ui/libs/css/vue.scss create mode 100644 uni_modules/uview-ui/libs/function/colorGradient.js create mode 100644 uni_modules/uview-ui/libs/function/debounce.js create mode 100644 uni_modules/uview-ui/libs/function/digit.js create mode 100644 uni_modules/uview-ui/libs/function/index.js create mode 100644 uni_modules/uview-ui/libs/function/platform.js create mode 100644 uni_modules/uview-ui/libs/function/test.js create mode 100644 uni_modules/uview-ui/libs/function/throttle.js create mode 100644 uni_modules/uview-ui/libs/luch-request/adapters/index.js create mode 100644 uni_modules/uview-ui/libs/luch-request/core/InterceptorManager.js create mode 100644 uni_modules/uview-ui/libs/luch-request/core/Request.js create mode 100644 uni_modules/uview-ui/libs/luch-request/core/buildFullPath.js create mode 100644 uni_modules/uview-ui/libs/luch-request/core/defaults.js create mode 100644 uni_modules/uview-ui/libs/luch-request/core/dispatchRequest.js create mode 100644 uni_modules/uview-ui/libs/luch-request/core/mergeConfig.js create mode 100644 uni_modules/uview-ui/libs/luch-request/core/settle.js create mode 100644 uni_modules/uview-ui/libs/luch-request/helpers/buildURL.js create mode 100644 uni_modules/uview-ui/libs/luch-request/helpers/combineURLs.js create mode 100644 uni_modules/uview-ui/libs/luch-request/helpers/isAbsoluteURL.js create mode 100644 uni_modules/uview-ui/libs/luch-request/index.d.ts create mode 100644 uni_modules/uview-ui/libs/luch-request/index.js create mode 100644 uni_modules/uview-ui/libs/luch-request/utils.js create mode 100644 uni_modules/uview-ui/libs/luch-request/utils/clone.js create mode 100644 uni_modules/uview-ui/libs/mixin/button.js create mode 100644 uni_modules/uview-ui/libs/mixin/mixin.js create mode 100644 uni_modules/uview-ui/libs/mixin/mpMixin.js create mode 100644 uni_modules/uview-ui/libs/mixin/mpShare.js create mode 100644 uni_modules/uview-ui/libs/mixin/openType.js create mode 100644 uni_modules/uview-ui/libs/mixin/style.js create mode 100644 uni_modules/uview-ui/libs/mixin/touch.js create mode 100644 uni_modules/uview-ui/libs/util/async-validator.js create mode 100644 uni_modules/uview-ui/libs/util/calendar.js create mode 100644 uni_modules/uview-ui/libs/util/dayjs.js create mode 100644 uni_modules/uview-ui/libs/util/emitter.js create mode 100644 uni_modules/uview-ui/libs/util/route.js create mode 100644 uni_modules/uview-ui/package.json create mode 100644 uni_modules/uview-ui/theme.scss diff --git a/.hbuilderx/launch.json b/.hbuilderx/launch.json new file mode 100644 index 0000000..a54163e --- /dev/null +++ b/.hbuilderx/launch.json @@ -0,0 +1,38 @@ +{ + "version" : "1.0", + "configurations" : [ + { + "bundleId" : "com.mgm.mcrm", + "certificateFile" : "/Users/liuchong/Downloads/ios_cert_test/private_key_250619.p12", + "certificateProfileFile" : "/Users/liuchong/Downloads/ProfileMgmMCRM_250619.mobileprovision", + "playground" : "custom", + "runSignStatus" : 1, + "type" : "uni-app:APP-PLUS" + }, + { + "app-plus" : { + "launchtype" : "local" + }, + "mp-weixin" : { + "launchtype" : "local" + }, + "type" : "uniCloud" + }, + { + "playground" : "standard", + "type" : "uni-app:APP-PLUS_simulator" + }, + { + "bundleId" : "com.mgm.mcrm", + "certificateFile" : "/Users/liuchong/Downloads/ios_cert_test/private_key_250619.p12", + "certificateProfileFile" : "/Users/liuchong/Downloads/ios_cert_test/profileMCRM_250709.mobileprovision", + "playground" : "custom", + "runSignStatus" : 1, + "type" : "uni-app:app-ios" + }, + { + "openVueDevtools" : true, + "type" : "uni-app:h5" + } + ] +} diff --git a/App.vue b/App.vue new file mode 100644 index 0000000..6c85e4e --- /dev/null +++ b/App.vue @@ -0,0 +1,661 @@ + + + diff --git a/api/approvalApi.js b/api/approvalApi.js new file mode 100644 index 0000000..095b85d --- /dev/null +++ b/api/approvalApi.js @@ -0,0 +1,9 @@ +export const getApprovalReason = (params, config = {}) => uni.$u.http.post('/app/approval/get_reason', params, config) +export const getApprover = (params, config = {}) => uni.$u.http.post('/app/approval/get_approver', params, config) +export const getApprovalList = (params, config = {}) => uni.$u.http.post('/app/approval/approval_list', params, config) +export const getApprovalCount = (params, config = {}) => uni.$u.http.post('/app/approval/get_approval_count', params, config) +export const getApprovalData = (params, config = {}) => uni.$u.http.post('/app/approval/get_approval_data', params, config) +export const rejectApproval = (params, config = {}) => uni.$u.http.post('/app/approval/reject_approval', params, config) +export const submitApproval = (params, config = {}) => uni.$u.http.post('/app/approval/submit_approval', params, config) +export const batchSubmitApproval = (params, config = {}) => uni.$u.http.post('/app/approval/batch_submit_approval', params, config) +export const batchSubmitReject = (params, config = {}) => uni.$u.http.post('/app/approval/batch_submit_reject', params, config) \ No newline at end of file diff --git a/api/bookingApi.js b/api/bookingApi.js new file mode 100644 index 0000000..4f8056e --- /dev/null +++ b/api/bookingApi.js @@ -0,0 +1,11 @@ +export const getBookingsMock = (params, config = {}) => uni.$u.http.post('/app/booking/get_bookings_by_nameId', params, config) +export const saveBooking = (params, config = {}) => uni.$u.http.post('/app/booking/create', params, config) +export const getBookings = (params, config = {}) => uni.$u.http.post('/app/bookings/search_optimize', params, config) +export const getBookingByConf = (params, config = {}) => uni.$u.http.post('/app/booking/get_booking_by_conf', params, config) +export const getBookingById = (params, config = {}) => uni.$u.http.post('/app/booking/get_booking_by_id', params, config) +export const editBooking = (params, config = {}) => uni.$u.http.post('/app/booking/edit', params, config) +export const getBookingsByGroupId = (params, config = {}) => uni.$u.http.post('/app/booking/get_bookings_by_groupId', params, config) +export const cancelWaitlistBooking = (params, config = {}) => uni.$u.http.post('/app/booking/cancel_waitlist', params, config) +export const cancelApproval = (params, config = {}) => uni.$u.http.post('/app/approval/cancel_approval', params, config) +export const approveWaitlistBooking = (params, config = {}) => uni.$u.http.post('/app/booking/approve_waitlist', params, config) +export const changeMiscCharge = (params, config = {}) => uni.$u.http.post('/app/booking/change_misc_charge', params, config) diff --git a/api/commonApi.js b/api/commonApi.js new file mode 100644 index 0000000..ccb79ec --- /dev/null +++ b/api/commonApi.js @@ -0,0 +1,6 @@ +export const writeDebugLog = (params, config = {}) => uni.$u.http.post('/system/write_log', params, config) +export const getSettingByKey = (params, config = {}) => uni.$u.http.post('/system/sys_setting/get', params, config) +export const getSettings = (params, config = {}) => uni.$u.http.post('/system/sys_setting/get_list', params, config) +export const verifyToken = (params, config = {}) => uni.$u.http.post('/app/me', params, config) +export const refreshToken = (params, config = {}) => uni.$u.http.post('/app/refresh_token?isRenewRefreshToken=false', params, config) +export const logout = (params, config = {}) => uni.$u.http.post('/app/logout', params, config) diff --git a/api/configApi.js b/api/configApi.js new file mode 100644 index 0000000..0365ad1 --- /dev/null +++ b/api/configApi.js @@ -0,0 +1,12 @@ +export const getProperties = (params, config = {}) => uni.$u.http.post('/app/config/property_list', params, config) +export const getBookingTypes = (params, config = {}) => uni.$u.http.post('/app/config/booking_type_list', params, config) +export const getRooms = (params, config = {}) => uni.$u.http.post('/app/config/room_list', params, config) +export const getRoomTypes = (params, config = {}) => uni.$u.http.post('/app/config/room_type_list', params, config) +export const getSpecials = (params, config = {}) => uni.$u.http.post('/app/config/special_list', params, config) +export const getBedTypes = (params, config = {}) => uni.$u.http.post('/app/config/bed_type_list', params, config) +export const getCriterias = (params, config = {}) => uni.$u.http.post('/app/config/criteria_list', params, config) +export const getSetting = (params, config = {}) => uni.$u.http.post('/app/config/setting_list', params, config) +export const getAvailableRoom = (params, config = {}) => uni.$u.http.post('/app/config/available_room_list', params, config) +export const getExtendBooking = (params, config = {}) => uni.$u.http.post('/app/config/is_extend_booking', params, config) +export const getWaitlistBooking = (params, config = {}) => uni.$u.http.post('/app/config/get_waitlist_booking', params, config) +export const getCfgSettingByKey = (params, config = {}) => uni.$u.http.post('/web/setting/get_setting_by_key', params, config) \ No newline at end of file diff --git a/api/mgmApi.js b/api/mgmApi.js new file mode 100644 index 0000000..5e78a6c --- /dev/null +++ b/api/mgmApi.js @@ -0,0 +1,3 @@ +export const playerLookup = (params, config = {}) => uni.$u.http.post('/app/mgm/player_lookup', params, config) +export const checkTPD = (params, config = {}) => uni.$u.http.post('/app/mgm/check_tpd_by_playerId_room_dates', params, config) +export const checkSecondTPD = (params, config = {}) => uni.$u.http.post('/app/mgm/check_second_tpd_by_playerId_room_dates', params, config) \ No newline at end of file diff --git a/api/notification.js b/api/notification.js new file mode 100644 index 0000000..d5fa900 --- /dev/null +++ b/api/notification.js @@ -0,0 +1,9 @@ +export const saveNotification = (params, config = {}) => uni.$u.http.post('/notification/saveNotification', params, config) +export const getNotificationByUserId = (params, config = {}) => + uni.$u.http.get('/notification/get_notification_by_user_id', { params, ...config }) +export const changeNotification = (params, config = {}) => uni.$u.http.post('/notification/change_status', params, config) +export const readAllNotification = (params, config = {}) => uni.$u.http.post('/notification/read_all', params, config) +export const countNotification = (params, config = {}) => + uni.$u.http.get('/notification/count_notification_by_user_id', { params, ...config }) +export const saveDeviceToken = (params, config = {}) => uni.$u.http.post('/deviceToken/save_device_token', params, config) +export const updateDeviceToken = (params, config = {}) => uni.$u.http.post('/deviceToken/update_device_token', params, config) \ No newline at end of file diff --git a/api/ssoApi.js b/api/ssoApi.js new file mode 100644 index 0000000..6ea5bb7 --- /dev/null +++ b/api/ssoApi.js @@ -0,0 +1,4 @@ +export const mockUserSSOLogin = (params, config = {}) => uni.$u.http.post('/app/sso/mock_user_sso_login', params, config) +export const getSSOTokenByCode = (params, config = {}) => uni.$u.http.post('/app/sso/get_sso_token_by_code', params, config) +export const userSSOlogin = (params, config = {}) => uni.$u.http.post('/app/sso/user_sso_login', params, config) +export const userOpenIdlogin = (params, config = {}) => uni.$u.http.post('/app/sso/loginidp', params, config) \ No newline at end of file diff --git a/api/todoApi.js b/api/todoApi.js new file mode 100644 index 0000000..5365ebd --- /dev/null +++ b/api/todoApi.js @@ -0,0 +1,8 @@ +export const getTodoDashboard = (params, config = {}) => uni.$u.http.post('/app/todo/get_dashboard_data', params, config) +export const getTodoDetail = (params, config = {}) => uni.$u.http.post('/app/todo/get_todolist_details', params, config) +export const getTodoList = (params, config = {}) => uni.$u.http.post('/app/todo/get_todolist', params, config) +export const submitETA = (params, config = {}) => uni.$u.http.post('/app/todo/submit_ETA', params, config) +export const cancelBooking = (params, config = {}) => uni.$u.http.post('/app/todo/cancel_booking', params, config) +export const changeDate = (params, config = {}) => uni.$u.http.post('/app/todo/change_date', params, config) +export const userConfirm = (params, config = {}) => uni.$u.http.post('/app/log_confirm/save_confirm_log', params, config) + diff --git a/booking/bookingConfirm/bookingConfirm.vue b/booking/bookingConfirm/bookingConfirm.vue new file mode 100644 index 0000000..4002fc0 --- /dev/null +++ b/booking/bookingConfirm/bookingConfirm.vue @@ -0,0 +1,1885 @@ + + + + + diff --git a/booking/bookingDetail/bookingDetail.vue b/booking/bookingDetail/bookingDetail.vue new file mode 100644 index 0000000..125dd30 --- /dev/null +++ b/booking/bookingDetail/bookingDetail.vue @@ -0,0 +1,2080 @@ + + + + + \ No newline at end of file diff --git a/booking/bookingGroup/bookingGroup.vue b/booking/bookingGroup/bookingGroup.vue new file mode 100644 index 0000000..fabc4a7 --- /dev/null +++ b/booking/bookingGroup/bookingGroup.vue @@ -0,0 +1,195 @@ + + + + + \ No newline at end of file diff --git a/booking/bookingRecord/bookingRecord.vue b/booking/bookingRecord/bookingRecord.vue new file mode 100644 index 0000000..193b99c --- /dev/null +++ b/booking/bookingRecord/bookingRecord.vue @@ -0,0 +1,579 @@ + + + + + \ No newline at end of file diff --git a/booking/multipleDate/multipleDate.vue b/booking/multipleDate/multipleDate.vue new file mode 100644 index 0000000..f81decd --- /dev/null +++ b/booking/multipleDate/multipleDate.vue @@ -0,0 +1,389 @@ + + + + + \ No newline at end of file diff --git a/booking/newBooking/newBooking.vue b/booking/newBooking/newBooking.vue new file mode 100644 index 0000000..c7d4227 --- /dev/null +++ b/booking/newBooking/newBooking.vue @@ -0,0 +1,1636 @@ + + + + + diff --git a/booking/newWaitlist/newWaitlist.vue b/booking/newWaitlist/newWaitlist.vue new file mode 100644 index 0000000..25c2152 --- /dev/null +++ b/booking/newWaitlist/newWaitlist.vue @@ -0,0 +1,655 @@ + + + + + diff --git a/booking/submitBooking/submitBooking.vue b/booking/submitBooking/submitBooking.vue new file mode 100644 index 0000000..d325089 --- /dev/null +++ b/booking/submitBooking/submitBooking.vue @@ -0,0 +1,1994 @@ + + + + + \ No newline at end of file diff --git a/common/cfgSettingCrypto.js b/common/cfgSettingCrypto.js new file mode 100644 index 0000000..b72d116 --- /dev/null +++ b/common/cfgSettingCrypto.js @@ -0,0 +1,187 @@ +/** + * 与后端 EncryptUtil.aesEncryptToBase64(AES-GCM,12 字节 IV,16 字节 tag)一致。 + * App 端 WebView 往往无 crypto.subtle,需用纯 JS 解密。 + */ +import { gcm } from '@noble/ciphers/aes.js'; +import { sha256 } from '@noble/hashes/sha2.js'; + +// Polyfill for TextEncoder/TextDecoder in Weex environment +class TextEncoderPolyfill { + encode(text) { + const arr = new Uint8Array(text.length); + for (let i = 0; i < text.length; i++) { + arr[i] = text.charCodeAt(i) & 0xff; + } + return arr; + } +} + +class TextDecoderPolyfill { + decode(uint8Array) { + let str = ''; + let i = 0; + while (i < uint8Array.length) { + const byte1 = uint8Array[i]; + if (byte1 < 0x80) { + // 单字节 ASCII + str += String.fromCharCode(byte1); + i++; + } else if ((byte1 & 0xe0) === 0xc0) { + // 双字节 UTF-8 + const byte2 = uint8Array[i + 1]; + const code = ((byte1 & 0x1f) << 6) | (byte2 & 0x3f); + str += String.fromCharCode(code); + i += 2; + } else if ((byte1 & 0xf0) === 0xe0) { + // 三字节 UTF-8 + const byte2 = uint8Array[i + 1]; + const byte3 = uint8Array[i + 2]; + const code = ((byte1 & 0x0f) << 12) | ((byte2 & 0x3f) << 6) | (byte3 & 0x3f); + str += String.fromCharCode(code); + i += 3; + } else if ((byte1 & 0xf8) === 0xf0) { + // 四字节 UTF-8(需要代理对) + const byte2 = uint8Array[i + 1]; + const byte3 = uint8Array[i + 2]; + const byte4 = uint8Array[i + 3]; + let code = ((byte1 & 0x07) << 18) | ((byte2 & 0x3f) << 12) | ((byte3 & 0x3f) << 6) | (byte4 & 0x3f); + // 转换为 UTF-16 代理对 + code -= 0x10000; + const high = 0xd800 + (code >> 10); + const low = 0xdc00 + (code & 0x3ff); + str += String.fromCharCode(high, low); + i += 4; + } else { + // 非法字节,跳过 + str += String.fromCharCode(byte1); + i++; + } + } + return str; + } +} + +const TextEncoder = typeof globalThis !== 'undefined' && globalThis.TextEncoder ? globalThis.TextEncoder : TextEncoderPolyfill; +const TextDecoder = typeof globalThis !== 'undefined' && globalThis.TextDecoder ? globalThis.TextDecoder : TextDecoderPolyfill; + +/** 与后端 EncryptUtil 一致:去掉 BOM/空白,避免与 SHA-256(UTF-8) 密钥不一致 */ +function normalizeSecret(secret) { + if (secret == null || typeof secret !== 'string') { + return secret; + } + let s = secret.trim(); + if (s.length > 0 && s.charCodeAt(0) === 0xfeff) { + s = s.slice(1); + } + return s; +} + +/** + * x-www-form-urlencoded /部分网关会把 Base64 里的 "+" 变成空格;JSON 一般不受影响。 + */ +function normalizeBase64Segment(seg) { + if (seg == null || seg === '') { + return seg; + } + let s = String(seg).trim().replace(/\s/g, '+'); + s = s.replace(/-/g, '+').replace(/_/g, '/'); + const pad = s.length % 4; + if (pad !== 0) { + s += '='.repeat(4 - pad); + } + return s; +} + +function base64ToUint8Array(b64) { + const normalized = normalizeBase64Segment(b64); + if (typeof atob === 'function') { + const bin = atob(normalized); + const out = new Uint8Array(bin.length); + for (let i = 0; i < bin.length; i++) { + out[i] = bin.charCodeAt(i) & 0xff; + } + return out; + } + if (typeof uni !== 'undefined' && uni.base64ToArrayBuffer) { + return new Uint8Array(uni.base64ToArrayBuffer(normalized)); + } + throw new Error('cfgSettingCrypto: no base64 decoder'); +} + +function splitIvAndCipher(encryptedText) { + const idx = encryptedText.indexOf(':'); + if (idx <= 0 || idx === encryptedText.length - 1) { + return null; + } + return { + ivB64: encryptedText.slice(0, idx), + cipherB64: encryptedText.slice(idx + 1), + }; +} + +async function decryptWithSubtle(encryptedText, secret) { + const parts = splitIvAndCipher(encryptedText); + if (!parts) { + throw new Error('cfgSettingCrypto: invalid iv:cipher format'); + } + const ivBytes = base64ToUint8Array(parts.ivB64); + const cipherBytes = base64ToUint8Array(parts.cipherB64); + const keyRaw = new TextEncoder().encode(normalizeSecret(secret)); + const keyHash = await globalThis.crypto.subtle.digest('SHA-256', keyRaw); + const aesKey = await globalThis.crypto.subtle.importKey( + 'raw', + keyHash, + { name: 'AES-GCM' }, + false, + ['decrypt'] + ); + const decrypted = await globalThis.crypto.subtle.decrypt( + { name: 'AES-GCM', iv: ivBytes, tagLength: 128 }, + aesKey, + cipherBytes + ); + return new TextDecoder().decode(decrypted); +} + +function decryptWithNoble(encryptedText, secret) { + const parts = splitIvAndCipher(encryptedText); + if (!parts) { + throw new Error('cfgSettingCrypto: invalid iv:cipher format'); + } + const ivBytes = base64ToUint8Array(parts.ivB64); + const cipherBytes = base64ToUint8Array(parts.cipherB64); + const keyBytes = sha256(new TextEncoder().encode(normalizeSecret(secret))); + const decipher = gcm(keyBytes, ivBytes); + const plainBytes = decipher.decrypt(cipherBytes); + return new TextDecoder().decode(plainBytes); +} + +/** + * @param {string} encryptedText 格式 base64(iv):base64(ciphertext||tag) + * @param {string} secret 与后端 allow_key 一致 + * @returns {Promise} + */ +export async function decryptCfgSettingValue(encryptedText, secret) { + if (!encryptedText || !secret || encryptedText.indexOf(':') === -1) { + return encryptedText; + } + if (!splitIvAndCipher(encryptedText)) { + return encryptedText; + } + try { + if (globalThis.crypto && globalThis.crypto.subtle) { + const plain = await decryptWithSubtle(encryptedText, secret); + if (plain) { + return plain; + } + } + } catch (e) { + console.warn('[cfgSettingCrypto] WebCrypto 解密失败,改用 @noble/ciphers', e); + } + try { + return decryptWithNoble(encryptedText, secret); + } catch (e) { + console.error('[cfgSettingCrypto]解密失败', e); + return encryptedText; + } +} diff --git a/common/config.js b/common/config.js new file mode 100644 index 0000000..40beca1 --- /dev/null +++ b/common/config.js @@ -0,0 +1,39 @@ +class config { + constructor() { + //local + this.internalUrl = 'https://localhost:9086'; + + // mgm web DEV + // this.internalUrl = 'https://localhost'; + + // willtech DEV + // this.internalUrl = 'https://47.238.46.81'; + + // MGM APP DEV + // this.internalUrl = 'https://dlahcadev.mcmsapoc.com'; + + //this.version = "beta 2.0"; + //ali ECS + // this.internalUrl = 'https://mcrm.willtechmacau.com:9086'; + + this.externalUrl = 'https://mp.mixixili.cn'; + this.debugMode = true; + this.apiPath = '/api'; + this.internalSSOUrl = 'https://adserver.willtechmacau.com'; + this.externalSSOUrl = 'https://adserver.willtechmacau.com'; + this.internalTag = true; + this.originUrl = "MGM_CRM_APP"; + this.appId='MGM_CRM_APP'; + this.allowKey='U2FsdGVkX19JXgsp9IZ+cr6P67KVShdWWRX5niRURIk='; + //dev + // this.internalUrl = 'https://hca.mcmsapoc.com'; + // this.internalUrl = 'https://localhost'; + this.version = "Dev 1.64"; + //prod + //this.internalUrl = 'https://hostcrmapp.mgm.mo'; + //this.version = "v2.0"; + this.resourceCallBackUrl = "hostcrmapp_dev"; + this.emailExt = "";// 如果是dev的時候設置成空字符串,讓他們自己輸入 + } +} +export default config \ No newline at end of file diff --git a/common/fixedCoordinateConverter.js b/common/fixedCoordinateConverter.js new file mode 100644 index 0000000..bc6ad05 --- /dev/null +++ b/common/fixedCoordinateConverter.js @@ -0,0 +1,324 @@ +/** + * 坐标转换问题分析和解决方案 - 精确修正 + * lc 2025-07-15 + */ + +class FixedCoordinateConverter { + constructor() { + this.a = 6378245.0; + this.ee = 0.00669342162296594323; + this.PI = Math.PI; + + // 精确偏移校正参数(基于实际测试数据) + this.OFFSET_CORRECTIONS = { + // 经度偏移校正 + lngCorrection: -0.00003, + // 纬度偏移校正 + latCorrection: 0.0003 + }; + } + + /** + * 标准算法实现 + */ + wgs84ToGcj02Standard(wgsLat, wgsLng) { + if (!this.isInChina(wgsLat, wgsLng)) { + return { lat: wgsLat, lng: wgsLng }; + } + + let dLat = this.transformLat(wgsLng - 105.0, wgsLat - 35.0); + let dLng = this.transformLng(wgsLng - 105.0, wgsLat - 35.0); + + const radLat = wgsLat / 180.0 * this.PI; + let magic = Math.sin(radLat); + magic = 1 - this.ee * magic * magic; + const sqrtMagic = Math.sqrt(magic); + + dLat = (dLat * 180.0) / ((this.a * (1 - this.ee)) / (magic * sqrtMagic) * this.PI); + dLng = (dLng * 180.0) / (this.a / sqrtMagic * Math.cos(radLat) * this.PI); + + return { + lat: wgsLat + dLat, + lng: wgsLng + dLng + }; + } + wgs84ToGcj02Fixed(wgsLat, wgsLng) { + if (!this.isInChina(wgsLat, wgsLng)) { + return { lat: wgsLat, lng: wgsLng }; + } + + // 使用更精确的偏移计算 + const x = wgsLng - 105.0; + const y = wgsLat - 35.0; + + let dLat = this.transformLatFixed(x, y); + let dLng = this.transformLngFixed(x, y); + + const radLat = wgsLat / 180.0 * this.PI; + const sinLat = Math.sin(radLat); + const cosLat = Math.cos(radLat); + + // 修正魔法数计算 + const magic = 1.0 - this.ee * sinLat * sinLat; + const sqrtMagic = Math.sqrt(magic); + + // 使用更精确的转换公式 + const M = this.a * (1.0 - this.ee) / (magic * sqrtMagic); // 子午圈曲率半径 + const N = this.a / sqrtMagic; // 卯酉圈曲率半径 + + dLat = (dLat * 180.0) / (M * this.PI); + dLng = (dLng * 180.0) / (N * cosLat * this.PI); + + // 应用精确偏移校正 + const correctedLat = wgsLat + dLat + this.OFFSET_CORRECTIONS.latCorrection; + const correctedLng = wgsLng + dLng + this.OFFSET_CORRECTIONS.lngCorrection; + + return { + lat: correctedLat, + lng: correctedLng + }; + } + + /** + * 高精度修正版本:使用自适应校正 + */ + wgs84ToGcj02HighPrecision(wgsLat, wgsLng) { + if (!this.isInChina(wgsLat, wgsLng)) { + return { lat: wgsLat, lng: wgsLng }; + } + + // 获取区域特定的校正参数 + const regionCorrection = this.getRegionSpecificCorrection(wgsLat, wgsLng); + + const x = wgsLng - 105.0; + const y = wgsLat - 35.0; + + let dLat = this.transformLatFixed(x, y); + let dLng = this.transformLngFixed(x, y); + + const radLat = wgsLat / 180.0 * this.PI; + const sinLat = Math.sin(radLat); + const cosLat = Math.cos(radLat); + + const magic = 1.0 - this.ee * sinLat * sinLat; + const sqrtMagic = Math.sqrt(magic); + + const M = this.a * (1.0 - this.ee) / (magic * sqrtMagic); + const N = this.a / sqrtMagic; + + dLat = (dLat * 180.0) / (M * this.PI); + dLng = (dLng * 180.0) / (N * cosLat * this.PI); + + // 应用区域特定校正 + const correctedLat = wgsLat + dLat + regionCorrection.latCorrection; + const correctedLng = wgsLng + dLng + regionCorrection.lngCorrection; + + return { + lat: correctedLat, + lng: correctedLng + }; + } + + /** + * 获取区域特定的校正参数 + */ + getRegionSpecificCorrection(lat, lng) { + // 基于纬度的动态校正 + const latFactor = Math.cos(lat * this.PI / 180); + + // 默认校正值(基于实际测试) + let latCorrection = this.OFFSET_CORRECTIONS.latCorrection; + let lngCorrection = this.OFFSET_CORRECTIONS.lngCorrection * latFactor; + + // 针对不同地区的微调 + if (lat >= 39.0 && lat <= 41.0 && lng >= 115.0 && lng <= 118.0) { + // 北京地区特殊校正 + latCorrection = 0.00220; + lngCorrection = -0.00140 * latFactor; + } else if (lat >= 30.5 && lat <= 32.0 && lng >= 120.5 && lng <= 122.5) { + // 上海地区特殊校正 + latCorrection = 0.00230; + lngCorrection = -0.00150 * latFactor; + } else if (lat >= 22.0 && lat <= 24.0 && lng >= 112.5 && lng <= 115.0) { + // 广州深圳地区特殊校正 + latCorrection = 0.00240; + lngCorrection = -0.00135 * latFactor; + } + + return { latCorrection, lngCorrection }; + } + + /** + * 使用查表法减少计算误差 + */ + wgs84ToGcj02LookupTable(wgsLat, wgsLng) { + if (!this.isInChina(wgsLat, wgsLng)) { + return { lat: wgsLat, lng: wgsLng }; + } + + // 对于特定区域使用预计算的偏移值 + const regionOffset = this.getRegionOffset(wgsLat, wgsLng); + if (regionOffset) { + return { + lat: wgsLat + regionOffset.latOffset, + lng: wgsLng + regionOffset.lngOffset + }; + } + + // 否则使用高精度算法 + return this.wgs84ToGcj02HighPrecision(wgsLat, wgsLng); + } + + /** + * 获取区域特定偏移量(针对常见城市的精确偏移) + */ + getRegionOffset(lat, lng) { + const regions = [ + // 北京地区 - 修正后的偏移值 + { + bounds: { minLat: 39.4, maxLat: 41.0, minLng: 115.4, maxLng: 117.5 }, + latOffset: 0.00580, // 修正向南偏移 + lngOffset: 0.00506 // 修正向东偏移 + }, + // 上海地区 + { + bounds: { minLat: 30.7, maxLat: 31.9, minLng: 120.9, maxLng: 122.2 }, + latOffset: 0.00590, + lngOffset: 0.00496 + }, + // 广州地区 + { + bounds: { minLat: 22.5, maxLat: 23.9, minLng: 112.9, maxLng: 114.8 }, + latOffset: 0.00600, + lngOffset: 0.00486 + }, + // 深圳地区 + { + bounds: { minLat: 22.4, maxLat: 22.8, minLng: 113.7, maxLng: 114.6 }, + latOffset: 0.00595, + lngOffset: 0.00491 + } + ]; + + for (const region of regions) { + if (lat >= region.bounds.minLat && lat <= region.bounds.maxLat && + lng >= region.bounds.minLng && lng <= region.bounds.maxLng) { + return region; + } + } + return null; + } + + /** + * 修正的纬度转换函数 + */ + transformLatFixed(x, y) { + let ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x)); + + ret += (20.0 * Math.sin(6.0 * x * this.PI) + + 20.0 * Math.sin(2.0 * x * this.PI)) * 2.0 / 3.0; + + ret += (20.0 * Math.sin(y * this.PI) + + 40.0 * Math.sin(y / 3.0 * this.PI)) * 2.0 / 3.0; + + ret += (160.0 * Math.sin(y / 12.0 * this.PI) + + 320.0 * Math.sin(y * this.PI / 30.0)) * 2.0 / 3.0; + + return ret; + } + + /** + * 修正的经度转换函数 + */ + transformLngFixed(x, y) { + let ret = 300.0 + x + 2.0 * y + 0.1 * x * x + + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x)); + + ret += (20.0 * Math.sin(6.0 * x * this.PI) + + 20.0 * Math.sin(2.0 * x * this.PI)) * 2.0 / 3.0; + + ret += (20.0 * Math.sin(x * this.PI) + + 40.0 * Math.sin(x / 3.0 * this.PI)) * 2.0 / 3.0; + + ret += (150.0 * Math.sin(x / 12.0 * this.PI) + + 300.0 * Math.sin(x / 30.0 * this.PI)) * 2.0 / 3.0; + + return ret; + } + + transformLat(x, y) { + return this.transformLatFixed(x, y); + } + + transformLng(x, y) { + return this.transformLngFixed(x, y); + } + + isInChina(lat, lng) { + return lng >= 72.004 && lng <= 137.8347 && + lat >= 0.8293 && lat <= 55.8271; + } + + /** + * 计算偏移距离(米) + */ + calculateOffsetDistance(originalLat, originalLng, convertedLat, convertedLng) { + const latDiffMeters = (convertedLat - originalLat) * 111000; + const lngDiffMeters = (convertedLng - originalLng) * 111000 * Math.cos(originalLat * this.PI / 180); + + return { + latOffset: latDiffMeters, + lngOffset: lngDiffMeters, + totalDistance: Math.sqrt(latDiffMeters * latDiffMeters + lngDiffMeters * lngDiffMeters) + }; + } + + /** + * 比较不同算法的转换结果 + */ + compareAlgorithms(wgsLat, wgsLng) { + const standard = this.wgs84ToGcj02Standard(wgsLat, wgsLng); + const fixed = this.wgs84ToGcj02Fixed(wgsLat, wgsLng); + const highPrecision = this.wgs84ToGcj02HighPrecision(wgsLat, wgsLng); + const lookup = this.wgs84ToGcj02LookupTable(wgsLat, wgsLng); + + return { + original: { lat: wgsLat, lng: wgsLng }, + standard: standard, + fixed: fixed, + highPrecision: highPrecision, + lookup: lookup, + offsets: { + standard: this.calculateOffsetDistance(wgsLat, wgsLng, standard.lat, standard.lng), + fixed: this.calculateOffsetDistance(wgsLat, wgsLng, fixed.lat, fixed.lng), + highPrecision: this.calculateOffsetDistance(wgsLat, wgsLng, highPrecision.lat, highPrecision.lng), + lookup: this.calculateOffsetDistance(wgsLat, wgsLng, lookup.lat, lookup.lng) + } + }; + } + + /** + * 验证修正效果 + */ + validateCorrection(wgsLat, wgsLng, expectedGcjLat, expectedGcjLng) { + const result = this.wgs84ToGcj02Fixed(wgsLat, wgsLng); + const error = this.calculateOffsetDistance(expectedGcjLat, expectedGcjLng, result.lat, result.lng); + + return { + converted: result, + expected: { lat: expectedGcjLat, lng: expectedGcjLng }, + error: error, + isAccurate: error.totalDistance < 10 // 误差小于10米认为准确 + }; + } +} + +// 导出修正版本 +if (typeof module !== 'undefined' && module.exports) { + module.exports = FixedCoordinateConverter; +} + +if (typeof window !== 'undefined') { + window.FixedCoordinateConverter = FixedCoordinateConverter; +} \ No newline at end of file diff --git a/common/mapping.js b/common/mapping.js new file mode 100644 index 0000000..061980c --- /dev/null +++ b/common/mapping.js @@ -0,0 +1,41 @@ +function mapOperaStatus(status){ + if(status=="DUE_IN"){ + return 'DUE IN'; + }else if(status=="CHECKED_IN"){ + return 'CHECKED IN'; + }else if(status=="DUE_OUT"){ + return 'DUE OUT'; + }else if(status=="CHECKED_OUT"){ + return 'CHECKED OUT'; + }else if(status=="RESERVED"){ + return 'RESERVED'; + } + else{ + return status; + } +} +function mapApproveStatus(status){ + if(status=="PN"){ + return 'PENDING'; + }else if(status=="N"){ + return 'CONFIRMED'; + }else if(status=="W"){ + return 'PENDING WAITLIST'; + }else if(status=="WA"){ + return 'APPROVED'; + }else if(status=="WC"){ + return 'WAITLIST CANCELLED'; + }else if(status=="F"){ + return 'FAILED'; + }else if(status=="FC"){ + return 'FAILED COMPLETE'; + }else if(status=="AP"){ + return 'PENDING APPROVAL'; + }else{ + return status; + } +} +export { + mapApproveStatus, + mapOperaStatus, +} \ No newline at end of file diff --git a/common/request.js b/common/request.js new file mode 100644 index 0000000..4439fa9 --- /dev/null +++ b/common/request.js @@ -0,0 +1,201 @@ +import {refreshToken} from '../api/commonApi.js' +import dayjs from '../uni_modules/uview-ui/libs/util/dayjs.js'; +// 此vm参数为页面的实例,可以通过它引用vuex中的变量 +module.exports = (vm) => { + // 请求拦截 + uni.$u.http.interceptors.request.use((config) => { // 可使用async await 做异步操作 + // 初始化请求拦截器时,会执行此方法,此时data为undefined,赋予默认{} + config.data = config.data || {} + // 根据custom参数中配置的是否需要token,添加对应的请求头 + // #ifdef APP-PLUS + if( + config.url!==undefined && config.url!=='' + && config.url.indexOf('logout')==-1 + && config.url.indexOf('Logout')==-1 + && config.url.indexOf('login')==-1 + && config.url.indexOf('Login')==-1 + && config.url.indexOf('setting')==-1 + && config.url.indexOf('regionRestrict')==-1 + && config.url.indexOf('refresh_token')==-1 + && config.url.indexOf('adfs')==-1 + && config.url.indexOf('/me')==-1 + && config.url.indexOf('sys_setting/get_list')==-1 + && config.url.indexOf('sso/get_sso_token_by_code')==-1 + && config.url.indexOf('sso/user_sso_login')==-1 + && config.url.indexOf('sso/mock_user_sso_login')==-1 + && config.url.indexOf('write_log')==-1 + ) + { + let siteData = uni.getStorageSync("siteData"); + //模拟内网登录 打包删除 + // siteData.internalTag=true; + //模拟内网登录 打包删除 + if(siteData!==undefined && siteData!==null && siteData.internalTag===false) + { + getApp().checkLocationAndVPN(); + } + } + // #endif + if(config?.custom?.auth) { + const token = uni.getStorageSync("token") + const clientId = uni.getStorageSync("clientId") + config.header.Authorization = token; + config.header.ClientId = clientId; + // #ifdef APP-PLUS + config.header.Origin = config.custom.origin; + // #endif + if(config.url.indexOf('refresh_token')==-1 ){ + // checkToken(); + }else{ + config.header.RefreshToken = uni.getStorageSync("refreshToken") + } + } + return config + }, config => { // 可使用async await 做异步操作 + return Promise.reject(config) + }) + + // 响应拦截 + uni.$u.http.interceptors.response.use((response) => { + /* 对响应成功做点什么 可使用async await 做异步操作*/ + const data = response.data + + // 自定义参数 + // const custom = response.config?.custom + if (data.code != 0) { + // 如果没有显式定义custom的toast参数为false的话,默认对报错进行toast弹出提示 + if (data.success==false && data.message) { + console.log(data.message) + } + let url = response.config.url + let isCheck = (url!==undefined && url!=='' + && url.indexOf('logout')==-1 + && url.indexOf('Logout')==-1 + && url.indexOf('login')==-1 + && url.indexOf('Login')==-1 + && url.indexOf('setting')==-1 + && url.indexOf('regionRestrict')==-1 + && url.indexOf('refresh_token')==-1 + && url.indexOf('adfs')==-1 + && url.indexOf('/me')==-1 + && url.indexOf('sys_setting/get_list')==-1 + && url.indexOf('sso/get_sso_token_by_code')==-1 + && url.indexOf('save_confirm_log')==-1 + && url.indexOf('write_log')==-1); + if(isCheck){ + checkIP(response.header) + } + + if(url.indexOf('mock_user_sso_login')!=-1){ + checkIP(response.header) + } + // // 如果需要catch返回,则进行reject + // if (custom?.catch) { + // return Promise.reject(data) + // } else { + // // 否则返回一个pending中的promise,请求不会进入catch中 + // return new Promise(() => {}) + // } + } + return data === undefined ? {} : data + }, (error) => { + console.log(error) + if( error.errMsg=="request:ok") { + error.errMsg= "request:fail"; + if(error.data!=undefined){ + if(error.data.message!=undefined){ + if(error.data.message=="The token was expected to have 3 parts, but got 1."){ + uni.$u.toast(error.errMsg) + kickout() + } + } + } + } + + if(error.errMsg!==undefined && error.errMsg!=="request:fail" && error.errMsg!=="request:ok" && error.errMsg.indexOf('-1')<=0 && !error.errMsg.includes("request:fail abort")){ + uni.$u.toast(error.errMsg) + } + + switch (error.statusCode) { + case 403: + break; + case 400: + kickout() + case 401: + if(error.config.url.indexOf('refresh_token')==-1 && error.config.url.indexOf('logout')==-1){ + return tokenRefresh().then(_ => { + error.config.header.Authorization = uni.getStorageSync("token"); + error.config.header.RefreshToken = uni.getStorageSync("refreshToken") + error.config.baseURL = undefined; + return uni.$u.http.request(error.config); + }) + }else{ + kickout() + } + + default: + break; + } + return Promise.reject(error) + }) + +} +function tokenRefresh(){ + let oldToken = uni.getStorageSync("token"); + if (oldToken !== null && oldToken !== '') { + return refreshToken({}) + .then((data) => { + uni.setStorageSync("token",data.accessToken); + uni.setStorageSync("tokenTime",dayjs().unix()); + return Promise.resolve(true) + }) + .catch(error => { + kickout() + }) + } else { + kickout() + } +} +function checkToken(){ + let now = Math.floor(new Date().getTime() / 1000); + let tokenTime = uni.getStorageSync("tokenTime"); + let token = uni.getStorageSync("token") + //4 min refresh token + + if(token!="" && now - tokenTime>240){ + tokenRefresh() + } +} +function kickout() { + uni.removeStorageSync("userData"); + uni.removeStorageSync("token"); + uni.removeStorageSync("idToken"); + uni.removeStorageSync("clientId"); + uni.removeStorageSync("refreshToken"); + uni.redirectTo({ + url:'/pages/login/login' + }) +} +function checkIP(header){ + let isInternal = header.IsInternal + let macauIP = header.MacauIP + //console.log(header); + if(isInternal!=undefined){ + let internal = false; + if(isInternal=="true") internal = true; + let siteData = uni.getStorageSync("siteData"); + if(siteData){ + siteData.internalTag = internal; + if(macauIP!=undefined && macauIP!="" && macauIP == "true") + siteData.macauIp = true; + else + siteData.macauIp = false; + uni.setStorageSync("siteData",siteData); + } + /*if(!internal){ + if(macauIP!=undefined && macauIP!="" && macauIP == "false"){ + getApp().navTo('/pages/regionRestrict/regionRestrict?type=7',0,false); //8 + } + }*/ + } +} \ No newline at end of file diff --git a/common/stringUtils.js b/common/stringUtils.js new file mode 100644 index 0000000..3c4d075 --- /dev/null +++ b/common/stringUtils.js @@ -0,0 +1,160 @@ + //-------------------------------------------------------------- + //LC + //2021-10-31 + //-------------------------------------------------------------- + +//校验银行卡号,银行卡校验规则(Luhn算法) +function isBankNo(value) { + if (value == "" || !isPositiveInteger(value)) return false; + var wei = [], + sumOdd = 0, + sumEven = 0, + length = value.length; + for (var j = 0; j < length; j++) { + wei[j] = parseInt(value.substring(length - j - 1, length - j)); // 从最末一位开始提取,每一位上的数值 + } + for (var i = 0; i < length / 2; i++) { + sumOdd += wei[2 * i]; + if (wei[2 * i + 1] * 2 > 9) wei[2 * i + 1] = wei[2 * i + 1] * 2 - 9; + else wei[2 * i + 1] *= 2; + sumEven += wei[2 * i + 1]; + } + return (sumOdd + sumEven) % 10 == 0; +} +//验证手机号 +function isPhone(phone){ + let reg = /^[1][3-9][0-9]{9}$/ + if(reg.test(phone)){ + return true; + }else{ + return false; + } +} +//验证 +//正整数 +function isInteger(value) { + return /^[1-9][0-9]*$/.test(value); +} +//浮点类型 +function isFloat(num) { + var reg = /^\d+(?=\.{0,1}\d+$|$)/ + num=num.replace(/\.\d{2,}$/,num.substr(num.indexOf('.'),3))//删除小数点后两位 + return reg.test(num) ; +} + +//date类型转string,就是2019-10-10 12:00:00这样,date转时间戳就new Date().valueOf() +function formatDate (date,type) { + if(type=="long") + return date.getFullYear()+'-'+(parseInt(date.getMonth())+1)+'-'+date.getDate()+' '+date.getHours()+':'+date.getMinutes()+':'+date.getSeconds() + else + return date.getFullYear()+'-'+(parseInt(date.getMonth())+1)+'-'+date.getDate() +} + +//是否身份证 +function isIdCard (num) { + let reg = /^[1-9]\d{5}(18|19|20|(3\d))\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/ + return reg.test(reg) +} + +//密码必须是大小写英文加数字 +function isPassword(pass) { + if(pass.length <8 || pass.length >20){ + return false; + } + var str = pass; + var regexpUperStr = /[A-Z]+/; + var reexpLowerStr = /[a-z]+/; + var regexpNum = /\d+/; + var uperStrFlag = regexpUperStr.test(str); + var lowerStrFlag = reexpLowerStr.test(str); + var numFlag = regexpNum.test(str); + + if (uperStrFlag == true && lowerStrFlag == true && numFlag == true) + return true; + else + return false; +} +//验证昵称 +function isNickname(nickname){ + if(nickname.length <2 || nickname.length >16){ + return false; + } + var regex = /^(\w|[\u4E00-\u9FA5])*$/; + var res = regex.test(nickname); + if(res==true){ + return true; + }else{ + return false; + } +} + +var minute = 1000 * 60; +var hour = minute *60; +var day = hour *24; +var week = day * 7; +var month = day * 30; +function getTimer(stringTime){ + var time1 = new Date().getTime();//当前的时间戳 + stringTime = stringTime.replace(/-/g,'/'); //IOS不支持-格式时间,只支持/格式时间 + var time2 = Date.parse(new Date(stringTime));//指定时间的时间戳 + var time = time1 - time2; + + var result = null; + if(time < 0){ + return ""; + }else if(time/month >= 1){ + result = parseInt(time/month) + "月前"; + }else if(time/week >= 1){ + result = parseInt(time/week) + "周前"; + }else if(time/day >= 1){ + result = parseInt(time/day) + "天前"; + }else if(time/hour >= 1){ + result = parseInt(time/hour) + "小时前"; + }else if(time/minute >= 1){ + result = parseInt(time/minute) + "分钟前"; + }else { + result = "刚刚"; + } + return result; +} +function getUrlParam(name) { + var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); + var r = window.location.search.substr(1).match(reg); + if(r != null) return unescape(r[2]); + return null; +} +function getParam(url,name) { + var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); + var r = url.substr(1).match(reg); + if(r != null) return unescape(r[2]); + return null; +} +function formatRichText(html){ + let newContent= html.replace(/]*>/gi,function(match,capture){ + match = match.replace(/style="[^"]+"/gi, '').replace(/style='[^']+'/gi, ''); + match = match.replace(/width="[^"]+"/gi, '').replace(/width='[^']+'/gi, ''); + match = match.replace(/height="[^"]+"/gi, '').replace(/height='[^']+'/gi, ''); + return match; + }); + newContent = newContent.replace(/style="[^"]+"/gi,function(match,capture){ + match = match.replace(/width:[^;]+;/gi, 'max-width:100%;').replace(/width:[^;]+;/gi, 'max-width:100%;'); + return match; + }); + newContent = newContent.replace(/]*\/>/gi, ''); + newContent = newContent.replace(/\ + + + + + + + + + + + + \ No newline at end of file diff --git a/components/p-checkbox/p-checkbox.vue b/components/p-checkbox/p-checkbox.vue new file mode 100644 index 0000000..389dff9 --- /dev/null +++ b/components/p-checkbox/p-checkbox.vue @@ -0,0 +1,78 @@ + + + + + diff --git a/components/playerInfoForBooking/playerInfoForBooking.vue b/components/playerInfoForBooking/playerInfoForBooking.vue new file mode 100644 index 0000000..e9855d7 --- /dev/null +++ b/components/playerInfoForBooking/playerInfoForBooking.vue @@ -0,0 +1,20 @@ + + + + + \ No newline at end of file diff --git a/components/simple-watermark/simple-watermark.vue b/components/simple-watermark/simple-watermark.vue new file mode 100644 index 0000000..bfff2d0 --- /dev/null +++ b/components/simple-watermark/simple-watermark.vue @@ -0,0 +1,122 @@ + + + + + \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..c3ff205 --- /dev/null +++ b/index.html @@ -0,0 +1,20 @@ + + + + + + + + + + +
+ + + diff --git a/locale/en.json b/locale/en.json new file mode 100644 index 0000000..7802045 --- /dev/null +++ b/locale/en.json @@ -0,0 +1,323 @@ +{ + "common.appName":"MOBILE CRM APP", + "common.userLogin":"User Login", + "common.loginsso":"LOGIN", + "common.loginFail":"Login failed", + "common.playerId":"Player ID", + "common.tier":"Tier", + "common.name":"Name", + "common.gender":"Gender", + "common.property":"Property", + "common.night":"Night", + "common.nights":"Nights", + "common.room":"Room", + "common.rooms":"Rooms", + "common.bookingType":"Booking Type", + "common.misCharge":"Misc Charge", + "common.checkInDate":"C/I Date", + "common.checkOutDate":"C/O Date", + "common.etaTime":"ETA", + "common.roomType":"Room Type", + "common.confirmationNo":"Conf #", + "common.loadMore":"Load more bookings", + "common.loading":"Loading...", + "common.nomore":"No more bookings", + "common.dataNotFound":"Data not found", + "common.cancel":"Cancel", + "common.ok":"OK", + "common.yes":"Yes", + "common.no":"No", + "common.confirm":"Confirm", + "common.in":"IN", + "common.out":"OUT", + "common.start":"START", + "common.end":"END", + "common.selected": "selected", + "common.userLocked":"This user account has been locked", + "common.rangeError":"Date Range invalid", + "common.removeConfirm":"Are you sure to remove?", + "common.warning":"Warning", + "common.login":"Login", + "common.loginAlert":"You haven't logged in yet, please login first", + "common.alterSharerOneself":"Cannot add current player", + "common.alterSharerExist":"Sharer is existing", + "common.alterSharerLimit":"Sharer limit", + "common.saveFail":"Save failed", + "common.connectionFail":"Connect server failed", + "common.errorMsg":"Error Message", + "common.goBack":"Go back", + "common.back":"Back", + "common.language":"Language", + "common.version":"Version", + "common.user":"User", + "common.division":"Division", + "common.department":"Department", + "common.section":"Section", + "common.debugMode":"Debug Mode", + "common.picSaveSuccess":"Image saved", + "common.search":"Search", + "common.status":"Status", + "common.inputRemark":"Please input remark", + "common.nextBooking":"Next booking", + "common.to":"to", + "common.close":"Close", + "common.save":"Save", + "common.inputUserNameAndPassword":"Please input username and password.", + "common.loginerror":"Invalid account or password.", + "common.mfaerror":"Login failed.", + "common.loginfail":"Login failed.", + "common.connected":"Connected", + "common.disconnected":"Disconnected", + "common.submit":"Submit", + "common.noPermission":"No permission to view", + "common.jailBreakTitle":"APP Disabled", + "common.jailBreakMessage":"Devices that have been jailbroken are prohibited from using this app.", + "common.rangeTip": "Date Range invalid", + "common.noRecord":"No Record", + "common.rejectFail":"Reject Approval Routing Fail", + "calendar.mon":"MON", + "calendar.tue":"TUE", + "calendar.wed":"WED", + "calendar.thu":"THU", + "calendar.fri":"FRI", + "calendar.sat":"SAT", + "calendar.sun":"SUN", + "roomCalendar.title":"Calendar", + "roomCalendar.playerTitle":"Player Calendar", + "roomCalendar.updated":"Calendar updated", + "roomCalendar.maxSelectedRoomTypes":"Up to {count} room types can be selected", + "findPlayer.title":"Find Player", + "findPlayer.alert":"Please input player ID", + "findPlayer.noPermission":"You are not authorized to view this player.", + "bookingRecord.title":"Booking Record", + "bookingRecord.calendar":"CALENDAR", + "bookingRecord.newsBooking":"NEW BOOKING / WAITLIST", + "bookingRecord.newsBooking":"ROOM BOOKING", + "bookingRecord.newLimo":"LIMO BOOKING", + "bookingRecord.extend":"Extend", + "bookingRecord.group":"Group", + "bookingRecord.sharer":"Sharer", + "bookingRecord.operaProfile":"No Opera profile, please contact MSC to support.", + "newBooking.title":"New Booking", + "newBooking.multipleDate":"MULTIPLE DATE", + "newBooking.selectDate":"SELECT DATE", + "newBooking.changeBlockAlert":"Are you sure to select this room block?", + "newBooking.room":"Room", + "newBooking.alertRoom":"Room type must be selected", + "newBooking.roomType":"Room Type", + "newBooking.maxNight1":"Maximum", + "newBooking.maxNight2":"consecutive nights", + "newBooking.specialPreference":"Special Preference", + "newBooking.otherProperty":"Other Property", + "newBooking.appFull":"App Channel full on below selected date,please contact MSC team.", + "newBooking.protectionPeriod":"Protection Period on below selected date.", + "newBooking.alertRoomType":"Room type must be selected", + "newBooking.sameBooking":"Player already has a booking on the same day, please contact MSC if required.", + "newBooking.reservedBooking":"Player already has a booking on the same day, booking will put in waitlist.", + "newBooking.waitlist":"The selected date is under Waitlist.", + "newBooking.extendBooking":"Are you sure to make New Booking or Extension?", + "newBooking.alertBookingType":"Booking type must be selected", + "newBooking.extension":"Extension", + "newBooking.preference":"Note:Selected preference is not guaranteed!", + "newBooking.deposit":"Deposit", + "newBooking.postCharge":"Post Charge", + "newBooking.waiveDeposit":"Waive Deposit", + "newBooking.collectDeposit":"Collect Deposit", + "newBooking.yesPost":"Yes Post", + "newBooking.noPost":"No Post", + "newLimo.title":"New Limo", + "newLimo.createTitle":"Create Booking", + "newLimo.editTitle":"Edit Booking", + "newLimo.sectionBookingInformation":"Booking Information", + "newLimo.sectionBookingItinerary":"Booking Itinerary", + "newLimo.sectionApprovalDetails":"Approval Details", + "newLimo.additionalOptions":"Additional Options", + "newLimo.serviceType":"Service Type", + "newLimo.pickUpDate":"Pick-up Date", + "newLimo.pickUpTime":"Pick-up Time", + "newLimo.carType":"Car Type", + "newLimo.noOfPax":"No of Pax", + "newLimo.flightDetail":"Flight Number", + "newLimo.eta":"ETA", + "newLimo.flightStatus":"Flight Status", + "newLimo.pickUpLocation":"Pick-up Location", + "newLimo.greetType":"Greet Type", + "newLimo.signage":"Signage", + "newLimo.dropOffLocation":"Drop-off Location", + "newLimo.bookingContact":"Booking Contact", + "newLimo.phoneNumber":"Phone Number", + "newLimo.highImportance":"High Importance", + "newLimo.tenOut":"10 Out", + "newLimo.tenOutContact":"10 Out Contact", + "newLimo.contactGuestDirectly":"Contact Guest Directly", + "newLimo.guestContact":"Guest Contact", + "newLimo.extraDropOffLocation":"Extra Drop Off Location", + "newLimo.hour":"Hour", + "newLimo.addStop":"+Add", + "newLimo.approvedBy":"Approved By", + "newLimo.paymentMethod":"Payment Method", + "newLimo.tripPrice":"Trip Price", + "newLimo.tripContact":"Trip Contact", + "newLimo.hourlyRate":"Hourly Rate", + "newLimo.remarks":"Remarks", + "newLimo.selectDate":"Select Date", + "newLimo.selectTime":"Select Time", + "newLimo.notApplicable":"N/A", + "newLimo.remarksPlaceholder":"", + "newLimo.removeStop":"Remove", + "bookingConfirm.title":"Preview & Confirm", + "bookingConfirm.submitBooking":"SUBMIT", + "bookingConfirm.createdOn":"Created on", + "bookingConfirm.createdBy":"Created by", + "bookingConfirm.viewBooking":"VIEW BOOKING", + "bookingConfirm.backToRecords":"BACK TO RECORDS", + "bookingConfirm.alert10":"Booking for player ", + "bookingConfirm.alert1":"Booking for player is processing", + "bookingConfirm.alert1_1":"Waitlist for player ", + "bookingConfirm.alert1_2":"Urgent approval for player ", + "bookingConfirm.alert2":" is processing!", + "bookingConfirm.alert3":"Booking Criteria is not qualified!", + "bookingConfirm.alert4":"Select date is in waitlist", + "bookingConfirm.alert5":"Partial Booking Criteria is not qualified!", + "bookingConfirm.IMAlert1":"Please contact MSC for booking", + "bookingConfirm.IMAlert2":"The select date is under waitlist, please seek for approval", + "bookingConfirm.putInWaitlist":"PUT IN WAITLIST", + "bookingConfirm.currentStay":"Current stay", + "bookingConfirm.extending":"Extending", + "bookingConfirm.extensionEmail":"Extending request is proceeding by MSC", + "bookingConfirm.extensionProccessing":"Booking extension is proccessing!", + "bookingConfirm.addSharer":"Add", + "bookingConfirm.canNotAddSharer":"Cannot add sharer", + "bookingConfirm.confirmBooking":"CONFIRM BOOKING", + "bookingConfirm.viewProceedBooking":"VIEW TO PROCEED BOOKING", + "bookingConfirm.wantToWaitList":"Do you want to Waitlist?", + "bookingConfirm.secondRoom1":"Reach maximum room request", + "bookingConfirm.secondRoom2":"One night reach maximum room request", + "bookingConfirm.secondRoom3":"Reserved Suite or above on the same day", + "bookingConfirm.secondRoom4":"Only Standard room is available", + "bookingConfirm.duplicateWaitlist":"Duplicated waitlist is submitted", + "bookingConfirm.remark":"Waitlist Remark", + "bookingConfirm.approvalRemark":"Remark", + "bookingConfirm.urgentApproval":"URGENT APPROVAL REQUEST", + "bookingConfirm.numOfRoom":"Nubmer of Room Request", + "bookingConfirm.requestReason":"Request Reason", + "bookingConfirm.routeToApprover":"Route to Approver", + "bookingConfirm.approvalRoutingRemark":"Approval Routing Remark", + "bookingConfirm.submitApproval":"SUBMIT APPROVAL", + "bookingDetail.title":"Booking Detail", + "bookingDetail.toCancelBooking":"To Cancel Booking?", + "bookingDetail.pendingAlert":"Booking is processing!", + "bookingDetail.waitlistAlert":"Booking is in waitlist!", + "bookingDetail.approvalAlert":"Approval Routing", + "bookingDetail.confirmationNo":"Confirmation No.", + "bookingDetail.saveImage":"SAVE IMAGE", + "bookingDetail.cancelBooking":"CANCEL BOOKING", + "bookingDetail.ETA":"ETA", + "bookingDetail.extension":"EXTENSION", + "bookingDetail.backToBooking":"BACK TO BOOKING", + "bookingDetail.cannotExtend":"Reached booking max stay days", + "bookingDetail.cancelSuccessful":"Booking is Cancelled", + "bookingDetail.cancelFailed":"Booking Cancel failed", + "bookingDetail.errorDate":"Save date must be continuous.", + "bookingDetail.nullDate":"Cancel booking date can not be null", + "bookingDetail.cancelTimeErr":"The current time period cannot cancel the booking.", + "bookingDetail.confirmCancel":"Are you sure to cancel booking?", + "bookingDetail.backToDetail":"Back To Detail", + "bookingDetail.statusChange":"Booking status has changed", + "bookingDetail.approve":"Approve", + "bookingDetail.reject":"Reject", + "bookingDetail.SelectDate":"Select Booking Date", + "bookingDetail.successfully":" Successfully", + "bookingDetail.cannotCancel":"Can not cancel this booking", + "bookingDetail.failed":" Failed", + "bookingDetail.confirmApprove":"Are you sure to approve booking?", + "bookingDetail.confirmReject":"Are you sure to reject booking?", + "bookingDetail.changeMiscChargeSuccess":"Change Misc Charge Success", + "bookingDetail.miscChargeLess":"Amount cannot be less than original.", + "bookingDetail.changeMiscChargeFail":"Change Misc Charge Fail", + "multipleDate.title":"Multiple Date", + "multipleDate.addDate":"ADD DATE", + "multipleDate.pleaseAddDate":"Please Add Date", + "multipleDate.reachMaxBookNum":"Reached multiple book num", + "submitBooking.title":"Submit", + "submitBooking.alert1":"The status of TPD has changed, please check again.", + "submitBooking.submitedSuccessful":"Submitted successfully", + "submitBooking.roomCriteriaNotQualified":"Room Criteria is not qualified", + "submitBooking.underWaitlist":"Under Waitlist", + "submitBooking.copyRemark":"Copy Remark", + "newWaitlist.title":"New Waitlist", + "newWaitlist.remark":"Remark", + "newWaitlist.submitWaitlist":"SUBMIT WAITLIST", + "newWaitlist.savesuccessful":"Save waitlist successful!", + "newWailist.viewSubmitedWaitlist":"VIEW SUBMITED WAITLIST", + "setting.title":"Settings", + "region.title":"Region Restrict", + "region.showMessage":"This app is only available in the Macao region.", + "region.reson":"Reason", + "region.resonMsgNotInMacau":"Your location is not in Macau.", + "region.resonMsgOpenVPN":"Your VPN is ON.", + "region.resonMsgNotInMacauOpenVpn":"Your location is not in Macau and VPN is ON", + "region.resonMsglocationErr":"Error occurred while checking the location.", + "region.resonMsgVPNErr":"Error occurred while checking the VPN.", + "region.resonMsgFunctionErr":"Error occurred while checking the location and VPN.", + "region.retry":"RETRY", + "region.commitTitle":"用戶使用協議及聲明", + "region.commitment1":"本人在此承諾遵守所有適用於使用 Mobile CRM (以下簡稱MCRM) 的公司政策及法定義務。尤其,本人所在地不在澳門特別行政區時,本人同意不使用具有博彩數據的MCRM功能。此外,本人承諾不允許任何其他人(無論是否為澳門美高梅員工)使用安裝在本人移動裝置上的MCRM或存取其中的數據。本人亦承諾不將MCRM上的任何信息分享至其他個人設備。本人知悉此類行為將受到法律的刑事處分,並嚴重違反本人合同規定的責任義務。", + "region.commitment2":"I hereby undertake to adhere to all Company’s policies and all legal obligations that are applicable to the usage of Mobile CRM (hereinafter called MCRM). In particular, I agree not to use MCRM functionality with gaming data whenever my location is outside of the Macau SAR. I further undertake not to allow anybody else, whether an MGM employee or not, to use MCRM on my mobile phone or to access the data therein. I also undertake not to share any of the information on MCRM to any other personal devices. I’m aware that such actions are criminally punished by law and constitute a serious breach of my contractual obligations.", + "region.resonMsgNotInMacauIP":"Your IP is not in Macau.", + "dashboard.title":"Home", + "dashboard.dataAsOf":"Data As Of:", + "dashboard.achievement":"Achievement", + "dashboard.kpi":"KPI", + "dashboard.teamtarget":"Team Target", + "dashboard.individualtarget":"Individual Target", + "dashboard.newreactivetheo":"New & Reactive Theo", + "dashboard.directoffer":"Direct Offer Redemption Rate", + "dashboard.hostedplayer":"Hosted Player Active Rate", + "dashboard.eventattendance":"Event Attendance (w/gaming action)", + "todo.title":"Todo", + "todo.arrival":"Arrival", + "todo.notConfNo":"Record without opera Confirmation No.", + "todo.departure":"Departure", + "todo.inhouse":"Inhouse", + "todo.others":"Others", + "todo.etaSuccess":"CHANGE ETA SUCCESS", + "todo.missParams":"Miss Parameter", + "todo.notRecord":"There are no corresponding other booking records", + "todo.noPermission":"Have not permission", + "todo.invokeError":"Invoke GetTodoDashboard Api Error", + "todo.returnError":"Return Data Error", + "todo.etaFail":"CHANGE ETA FAIL", + "todo.detailFail":"Fetch TodoDetail Fail", + "todo.lookupPlayer":"You have not permission to view this player", + "todo.etaFormatError":"ETA Time Format Error", + "todo.etaRequired": "ETA Time Cannot Null", + "hotel.title":"Room", + "reservations.title":"Reservations", + "approval.title":"Approval", + "hotel.roombooking":"Room Booking", + "approval.pendingApproval":"Pending Approval", + "approval.allRequest":"All Request", + "approval.searchStr":"Search", + "approval.submitApproval":"Confirm to Approval?", + "approval.submitReject":"Confirm to Reject?", + "approval.submitBatchApproval":"Confirm to Batch Approval?", + "approval.batchApprove": "Batch Approve", + "approval.batchReject": "Batch Reject", + "approval.submitBatchReject":"Confirm to Batch Reject?", + "approval.approve":"Approve", + "approval.backToAll":"Back to All Request", + "approval.backToRecord":"Back to Pending Approval", + "approval.reason":"Approval Reason", + "approval.pendingResponse":"Approver", + "bookingConfirm.approvalSuccess": "Approved Successfully.", + "bookingConfirm.approvalFail": "Approved Failed.", + "bookingConfirm.rejectSuccess": "Rejected Successfully.", + "bookingConfirm.failSubmitted": "Submitted Failed.", + "notification.noData":"NO DATA", + "notification.noPermission":"NO PERMISSION", + "notification.pendingApproval":"Pending Approval", + "notification.pendingApprovalRequest": "Pending Approval Request", + "playerDetail.confirm":"CONFIRM", + "newBooking.validEta":"The ETA time format is incorrect. Please re-enter it, eg: HH:mm" +} diff --git a/locale/index.js b/locale/index.js new file mode 100644 index 0000000..25a0031 --- /dev/null +++ b/locale/index.js @@ -0,0 +1,7 @@ +import en from './en.json' +import zhHant from './zh-Hant.json' + +export default { + en, + 'zh-Hant': zhHant, +} \ No newline at end of file diff --git a/locale/zh-Hant.json b/locale/zh-Hant.json new file mode 100644 index 0000000..14551b8 --- /dev/null +++ b/locale/zh-Hant.json @@ -0,0 +1,259 @@ + { + "common.appName": "MOBILE CRM APP", + "common.userLogin": "用戶登入", + "common.loginsso": "登入", + "common.loginFail": "登入失敗", + "common.playerId": "會員號碼", + "common.tier": "等級", + "common.name": "姓名", + "common.gender": "性別", + "common.property": "酒店", + "common.night": "晚", + "common.nights": "晚", + "common.room": "間", + "common.rooms": "間", + "common.bookingType": "預訂類型", + "common.misCharge":"雜項費用", + "common.checkInDate": "入住日期", + "common.checkOutDate": "退房日期", + "common.roomType": "房型", + "common.confirmationNo": "預訂編號", + "common.loadMore": "加載更多", + "common.loading": "正在加載...", + "common.nomore": "沒有更多了", + "common.dataNotFound": "沒有查詢結果", + "common.cancel": "取消", + "common.yes": "確認", + "common.no": "取消", + "common.ok": "確認", + "common.confirm": "確認", + "common.in": "入住", + "common.out": "離開", + "common.start":"開始", + "common.selected": "已選擇", + "common.userLocked":"這個用戶賬戶已鎖定", + "common.ipLocked":"這個IP已鎖定", + "common.end":"終止", + "common.rangeError":"日期範圍不正確", + "common.removeConfirm": "確認要刪除嗎?", + "common.warning": "系統提示", + "common.login": "登入", + "common.loginAlert": "您還沒有登入,請先登入", + "common.saveFail": "保存失敗", + "common.connectionFail": "無法連接伺服器", + "common.alterSharerOneself": "不能添加當前客人", + "common.alterSharerExist": "該客人已添加", + "common.alterSharerLimit": "同住人限制", + "common.errorMsg": "錯誤信息", + "common.goBack": "返回", + "common.back":"返回", + "common.language": "語言", + "common.version": "版本", + "common.user": "用戶", + "common.division": "分部", + "common.department": "部門", + "common.section": "組別", + "common.debugMode": "調試模式", + "common.picSaveSuccess": "截屏已保存", + "common.search": "查詢", + "common.status": "狀態", + "common.inputRemark": "請輸入備註", + "common.nextBooking":"下一個預訂", + "common.to": "到", + "common.close":"關閉", + "common.save":"保存", + "common.inputUserNameAndPassword": "請輸入用戶名和密碼", + "common.loginerror":"用戶名或密碼錯誤", + "common.mfaerror":"登入失敗", + "common.loginfail":"登入失敗", + "common.connected":"已連接", + "common.disconnected":"連接失敗", + "common.submit":"遞交", + "common.noPermission":"您沒有權限查看", + "common.rangeTip":"日期范围无效", + "common.jailBreakTitle":"禁止使用", + "common.jailBreakMessage":"禁止越獄過的設備使用該APP", + "common.noRecord":"沒有記錄", + "common.etaTime":"預計時間", + "calendar.mon": "一", + "calendar.tue": "二", + "calendar.wed": "三", + "calendar.thu": "四", + "calendar.fri": "五", + "calendar.sat": "六", + "calendar.sun": "日", + "findPlayer.title": "查找客人", + "findPlayer.alert": "請輸入客人ID", + "findPlayer.noPermission": "您沒有權限查看此客人.", + "bookingRecord.title": "預定記錄", + "bookingRecord.newsBooking": "預訂房間 / 候補名單", + "bookingRecord.extend": "續房", + "bookingRecord.group": "關聯", + "bookingRecord.sharer": "同住人", + "bookingRecord.operaProfile": "沒有Opera profile, 請聯係MSC幫助.", + "newBooking.title": "預訂房間", + "newBooking.multipleDate": "多組日期", + "newBooking.selectDate": "選擇日期", + "newBooking.changeBlockAlert": "您確認切換到該block嗎?", + "newBooking.room": "房", + "newBooking.alertRoom": "必須選擇房型", + "newBooking.roomType": "房型", + "newBooking.maxNight1": "選擇天數不能超過", + "newBooking.maxNight2": "天", + "newBooking.specialPreference": "特殊需求", + "newBooking.otherProperty": "其他酒店", + "newBooking.appFull": "以下日期房間已滿,請聯係MSC team.", + "newBooking.protectionPeriod": "以下日期為保護期間.", + "newBooking.alertRoomType": "必須選擇房型", + "newBooking.sameBooking": "客人相同日期已有預定,如有必要請聯係MSC", + "newBooking.reservedBooking": "客人相同日期已有預定,確認將放入候補名單", + "newBooking.waitlist": "選擇的日期要放入候補名單.", + "newBooking.extendBooking": "您確定要預訂還是續房?", + "newBooking.alertBookingType": "必須選擇預訂類型", + "newBooking.extension": "續房", + "newBooking.preference": "注意:特殊需求均無法保證,須視乎實際状況安排", + "newBooking.deposit":"押金", + "newBooking.postCharge":"房賬", + "newBooking.waiveDeposit":"免收押金", + "newBooking.collectDeposit":"收取押金", + "newBooking.yesPost":"掛房賬", + "newBooking.noPost":"鎖房賬", + "bookingConfirm.title": "預覽 & 確認", + "bookingConfirm.submitBooking": "遞交預定", + "bookingConfirm.createdOn": "預訂日期", + "bookingConfirm.createdBy": "預訂者", + "bookingConfirm.viewBooking": "預定詳情", + "bookingConfirm.urgentApproval":"緊急審批請求", + "bookingConfirm.submitApproval":"提交審批人", + "bookingConfirm.alert10": "正在處理客人 ", + "bookingConfirm.alert1": "預訂正在處理中", + "bookingConfirm.alert1_1":" 的候補名單!", + "bookingConfirm.alert2": " 的預定!", + "bookingConfirm.alert3": "您的預定未能通過!", + "bookingConfirm.alert4": "需放在候補名單", + "bookingConfirm.alert5": "部分預定未能通過!", + "bookingConfirm.IMAlert1":"請聯繫MSC預訂房間", + "bookingConfirm.IMAlert2":"選擇的日期需放在候補名單, 請申請批准預訂房間", + "bookingConfirm.putInWaitlist": "放入候補名單", + "bookingConfirm.currentStay": "當前入住", + "bookingConfirm.extending": "延長入住", + "bookingConfirm.extensionEmail": "MSC正在處理續房", + "bookingConfirm.extensionProccessing": "續房正在處理中", + "bookingConfirm.addSharer": "新增", + "bookingConfirm.canNotAddSharer": "不能新增同住人", + "bookingConfirm.confirmBooking": "確認預定", + "bookingConfirm.backToRecords": "返回主頁", + "bookingConfirm.viewProceedBooking": "查看並繼續", + "bookingConfirm.wantToWaitList": "是否放入候補名單?", + "bookingConfirm.secondRoom1":"超過可預訂房間數量", + "bookingConfirm.secondRoom2":"其中一晚已超過可預訂房間數量", + "bookingConfirm.secondRoom3":"已預訂套房或以上房型", + "bookingConfirm.secondRoom4":"只可預訂基本房型", + "bookingConfirm.duplicateWaitlist":"已提交候補名單", + "bookingConfirm.remark":"候補名單備註", + "bookingConfirm.numOfRoom":"請求房間數量", + "bookingConfirm.requestReason":"請求原因", + "bookingConfirm.routeToApprover":"發送至審批員", + "bookingConfirm.approvalRoutingRemark":"審批備注", + "bookingDetail.title": "預定詳情", + "bookingDetail.pendingAlert": "預定正在處理中!", + "bookingDetail.waitlistAlert": "預定已列入候補名單!", + "bookingDetail.confirmationNo": "預訂編號", + "bookingDetail.saveImage": "保存圖片", + "bookingDetail.extension": "續房", + "bookingDetail.cancelSuccessful": "取消成功", + "bookingDetail.cancelFailed": "取消失敗", + "bookingDetail.confirmCancel": "你確定要取消預定嗎?", + "bookingDetail.statusChange": "預定狀態已改變", + "bookingDetail.approve":"審批", + "bookingDetail.reject":"拒絕", + "bookingDetail.changeMiscChargeSuccess":"修改雜項費用成功", + "bookingDetail.changeMiscChargeFail":"修改雜項費用失敗", + "bookingDetail.cancelTimeErr":"當前時間段不能取消預定", + "bookingDetail.successfully":"成功", + "bookingDetail.failed":"失敗", + "bookingDetail.toCancelBooking": "確定要取消預訂嗎?", + "bookingDetail.backToBooking": "返回預訂", + "bookingDetail.backToDetail": "返回詳情", + "bookingDetail.SelectDate": "選擇預訂日期", + "bookingDetail.confirmApprove": "確定要批准此預訂嗎?", + "bookingDetail.confirmReject": "確定要拒絕此預訂嗎?", + "bookingDetail.errorDate":"必須選擇連續的日期!", + "bookingDetail.cancelBooking":"取消預定", + "bookingDetail.ETA":"預計時間", + "bookingDetail.miscChargeLess":"金額不可低於原值.", + "bookingDetail.cannotCancel":"不能取消这条记录", + "multipleDate.title": "選擇多個日期", + "multipleDate.addDate": "新增日期", + "multipleDate.pleaseAddDate": "請新增日期", + "multipleDate.reachMaxBookNum": "已達最大多個日期預定", + "submitBooking.title": "遞交", + "submitBooking.alert1": "TPD的狀態發生了改變,請重新選擇", + "submitBooking.submitedSuccessful": "遞交成功", + "submitBooking.roomCriteriaNotQualified":"不符合訂房條件", + "submitBooking.underWaitlist":"放入候補名單", + "submitBooking.copyRemark":"複製備註", + "putInWaitlist.title": "候補名單", + "newWaitlist.title": "创建候補名單", + "newWaitlist.remark": "備註", + "newWaitlist.submitWaitlist": "遞交候補名單", + "newWaitlist.savesuccessful": "成功遞交候補名單!", + "newWaitlist.viewSubmitedWaitlist": "查看候補名單", + "setting.title": "設定", + "region.title":"地區限制", + "region.showMessage":"此應用程序僅限於澳門使用。", + "region.reson":"禁用原因", + "region.resonMsgNotInMacau":"您的定位不在澳門", + "region.resonMsgOpenVPN":"您打開了VPN", + "region.resonMsgNotInMacauOpenVpn":"您的定位不在澳門且打開了VPN", + "region.resonMsglocationErr":"檢查定位時出錯", + "region.resonMsgVPNErr":"檢查VPN時出錯", + "region.resonMsgFunctionErr":"檢查定位和VPN時出錯", + "region.retry":"重試", + "region.commitTitle":"用戶使用協議及聲明", + "region.commitment1":"本人在此承諾遵守所有適用於使用 Mobile CRM (以下簡稱MCRM) 的公司政策及法定義務。尤其,本人所在地不在澳門特別行政區時,本人同意不使用具有博彩數據的MCRM功能。此外,本人承諾不允許任何其他人(無論是否為澳門美高梅員工)使用安裝在本人移動裝置上的MCRM或存取其中的數據。本人亦承諾不將MCRM上的任何信息分享至其他個人設備。本人知悉此類行為將受到法律的刑事處分,並嚴重違反本人合同規定的責任義務。", + "region.commitment2":"I hereby undertake to adhere to all Company’s policies and all legal obligations that are applicable to the usage of Mobile CRM (hereinafter called MCRM). In particular, I agree not to use MCRM functionality with gaming data whenever my location is outside of the Macau SAR. I further undertake not to allow anybody else, whether an MGM employee or not, to use MCRM on my mobile phone or to access the data therein. I also undertake not to share any of the information on MCRM to any other personal devices. I’m aware that such actions are criminally punished by law and constitute a serious breach of my contractual obligations.", + "region.resonMsgNotInMacauIP":"您的IP不在澳門", + "dashboard.title":"主頁", + "dashboard.dataAsOf":"數據更新於:", + "dashboard.achievement":"成就", + "dashboard.kpi":"指標", + "dashboard.teamtarget":"團隊目標", + "dashboard.individualtarget":"個人目標", + "dashboard.newreactivetheo":"New & Reactive Theo", + "dashboard.directoffer":"Direct Offer Redemption Rate", + "dashboard.hostedplayer":"Hosted Player Active Rate", + "dashboard.eventattendance":"Event Attendance (w/gaming action)", + "todo.title":"待辦", + "todo.arrival":"到達", + "todo.departure":"離開", + "todo.inhouse":"在場", + "todo.others":"其他", + "todo.notConfNo":"該條記錄沒有Opera Confirmation No.", + "todo.etaSuccess":"修改ETA成功", + "todo.etaFail":"修改ETA失敗", + "todo.detailFail":"獲取信息失敗", + "todo.missParams":"缺少參數", + "todo.notRecord":"沒有對應的記錄", + "todo.invokeError":"調用ESB API時出錯", + "todo.noPermission":"沒有權限", + "todo.returnError":"返回數據時出錯", + "todo.etaFormatError":"ETA Time格式錯誤", + "todo.etaRequired": "ETA Time不能為空", + "todo.lookupPlayer":"您沒有權限查看該玩家", + "hotel.title":"酒店", + "approval.approve": "批准", + "hotel.roombooking":"酒店預定", + "approval.pendingApproval":"等待審批", + "approval.batchApprove": "批量批准", + "approval.batchReject": "批量拒絕", + "approval.approvalFail": "審批失敗", + "approval.allRequest":"所有請求", + "approval.searchStr":"搜索", + "notification.noData":"沒有返回數據", + "notification.noPermission":"沒有權限", + "notification.pendingApproval":"審批列表", + "notification.pendingApprovalRequest": "待批准請求", + "playerDetail.confirm":"確認", + "newBooking.validEta":"ETA 時間格式有誤,請重新輸入 eg: HH:mm" +} \ No newline at end of file diff --git a/main.js b/main.js new file mode 100644 index 0000000..81ccc39 --- /dev/null +++ b/main.js @@ -0,0 +1,122 @@ +import App from './App' +import uView from '@/uni_modules/uview-ui' +import store from './store' +import messages from './locale/index' +import watermark from './store/watermark.js' + +let i18nConfig = { + locale: uni.getLocale(), + messages +} + +// #ifndef VUE3 +import Vue from 'vue' +import VueI18n from 'vue-i18n' +import './uni.promisify.adaptor' +Vue.use(VueI18n) +const i18n = new VueI18n(i18nConfig) + +Vue.use(watermark, { + loginPaths: [ + './salessupport/todoList/todoList.vue' + ], + defaultContent: 'Cannot get user data' +}); + +Vue.config.productionTip = false +Vue.prototype.$store = store +// 注册全局方法 +Vue.prototype.isLogin = function(){ + getApp().isLogin(); +} +Vue.prototype.checkJailbreak = function(){ + getApp().checkJailbreak(); +} +Vue.prototype.navBack = function(delta){ + getApp().navBack(delta); +} +Vue.prototype.navTo = function(url,type,auth){ + getApp().navTo(url,type,auth); +} +Vue.prototype.writeLog = function(userId,eventCode,transactionId,description,requestBody,responseBody,successTag,debugTag){ + getApp().writeLog(userId,eventCode,transactionId,description,requestBody,responseBody,successTag,debugTag); +} +Vue.prototype.redirectByPermission = function(userData,needRedirect){ + getApp().redirectByPermission(userData,needRedirect); +} +Vue.prototype.showTabbarByPermission = function(userData){ + getApp().showTabbarByPermission(userData); +} +Vue.prototype.checkInMacau = function(){ + return getApp().checkInMacau(); +} +Vue.prototype.checkVPNOpen = function(){ + return getApp().checkVPNOpen(); +} +Vue.prototype.checkLocationAndVPN = function(type){ + return getApp().checkLocationAndVPN(type); +} +Vue.prototype.logout = function(){ + return getApp().logout(); +} +Vue.prototype.$onLaunched = new Promise((resolve, reject) => { + Vue.prototype.$isResolve = resolve +}) + + +App.mpType = 'app' +/*uni.addInterceptor('request', { + success: function(request) { + let adfsCookie = uni.getStorageSync('adfs_cookie'); + console.log('Set request Cookie'); + if (adfsCookie) { + console.log(adfsCookie);*/ + /*var cookies ="FederationAuthCookie="+ adfsCookie+ + ";RequestedSecurityToken="+ adfsCookie+ + ";FedAuth="+adfsCookie;*/ + + //request.header.Cookie = adfsCookie; // 将每次的请求头中加入Cookies + //request.header.cookie = cookies; + //request.header.FederationAuthCookie=adfsCookie; + //request.header.RequestedSecurityToken=adfsCookie; + //request.header.FedAuth=adfsCookie; + /*request.header.Authorization='Bearer '+adfsCookie; + } + } + });*/ +const app = new Vue({ + i18n, + store, + ...App +}) + +// 引入请求封装,将app参数传递到配置中 +require('@/common/request.js')(app) +app.$mount() +// #endif + +// #ifdef VUE3 +import { createSSRApp } from 'vue' +import { createI18n } from 'vue-i18n' +const i18n = createI18n(i18nConfig) +export function createApp() { + const app = createSSRApp(App) + /*uni.addInterceptor('request', { + success: function(request) { + let adfsCookie = uni.getStorageSync('adfs_cookie'); + console.log('Set request Cookie'); + if (adfsCookie) { + var cookies ={ + FederationAuthCookie: adfsCookie, + RequestedSecurityToken: adfsCookie + }; + request.header.Cookies = cookies // 将每次的请求头中加入Cookies + } + } + });*/ + app.use(i18n) + return { + app + } +} +// #endif \ No newline at end of file diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..49061b0 --- /dev/null +++ b/manifest.json @@ -0,0 +1,166 @@ +{ + "name" : "MobileCRM", + "appid" : "__UNI__A500790", + "description" : "", + "versionName" : "1.6.1", + "versionCode" : 161, + "transformPx" : false, + "app-plus" : { + "usingComponents" : true, + "nvueStyleCompiler" : "uni-app", + "compilerVersion" : 3, + "splashscreen" : { + "alwaysShowBeforeRender" : true, + "waiting" : true, + "autoclose" : true, + "delay" : 0 + }, + "modules" : { + "Camera" : {}, + "UTS-Proxy" : {}, + "Geolocation" : {} + }, + "distribute" : { + "distribute" : { + "orientation" : [ "portrait" ] + }, + "android" : { + "permissions" : [ + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "" + ] + }, + "ios" : { + "dSYMs" : false, + "capabilities" : { + "entitlements" : { + "com.apple.developer.networking.networkextension" : [ "packet-tunnel-provider", "app-proxy-provider" ], + "com.apple.developer.networking.vpn.api" : "allow-vpn" + } + }, + "privacyDescription" : { + "NSPhotoLibraryUsageDescription" : "", + "NSPhotoLibraryAddUsageDescription" : "", + "NSLocationWhenInUseUsageDescription" : "需要您的位置权限以提供附近服务", + "NSLocationAlwaysAndWhenInUseUsageDescription" : "需要您的位置权限以提供附近服务", + "NSLocationAlwaysUsageDescription" : "需要您的位置权限以提供附近服务", + "NSNetworkVolumesUsageDescription" : "应用需要访问网络信息以检测VPN状态", + "NSLocalNetworkUsageDescription" : "应用需要访问本地网络以检测VPN连接", + "NSNetworkExtensionUsageDescription" : "此应用需要访问网络扩展以检测VPN连接状态" + }, + "permissions" : { + "location" : { + "description" : "该应用需要获取位置信息以便于定位功能" + } + }, + "urltypes" : "mcrm.com.mgm.mcrm" + }, + "sdkConfigs" : { + "ad" : {}, + "oauth" : {}, + "geolocation" : { + "system" : { + "__platform__" : [ "ios" ] + } + } + }, + "icons" : { + "ios" : { + "appstore" : "", + "iphone" : { + "app@2x" : "", + "app@3x" : "", + "notification@2x" : "", + "notification@3x" : "", + "settings@2x" : "", + "settings@3x" : "", + "spotlight@2x" : "", + "spotlight@3x" : "" + }, + "ipad" : { + "app" : "", + "app@2x" : "", + "notification" : "", + "notification@2x" : "", + "proapp@2x" : "", + "settings" : "", + "settings@2x" : "", + "spotlight" : "", + "spotlight@2x" : "" + } + }, + "android" : { + "hdpi" : "", + "xhdpi" : "", + "xxhdpi" : "", + "xxxhdpi" : "" + } + }, + "splashscreen" : { + "iosStyle" : "storyboard", + "ios" : { + "storyboard" : "/Users/liuchong/Downloads/MCRMStoryboard.zip" + } + } + }, + "nativePlugins" : { + "NetworkUtils" : { + "__plugin_info__" : { + "name" : "NetworkUtilsModule", + "description" : "For network", + "platforms" : "iOS", + "url" : "", + "android_package_name" : "", + "ios_bundle_id" : "", + "isCloud" : false, + "bought" : -1, + "pid" : "", + "parameters" : {} + } + } + } + }, + "quickapp" : {}, + "mp-weixin" : { + "appid" : "", + "setting" : { + "urlCheck" : false + }, + "usingComponents" : true + }, + "mp-alipay" : { + "usingComponents" : true + }, + "mp-baidu" : { + "usingComponents" : true + }, + "mp-toutiao" : { + "usingComponents" : true + }, + "uniStatistics" : { + "enable" : false + }, + "vueVersion" : "2", + "locale" : "en", + "h5" : { + "devServer" : { + "https" : false + }, + "router" : { + "base" : "/mcrm_mobile_app" + } + } +} diff --git a/nativeplugins/NetworkUtils/ios/NetworkUtils.framework/Info.plist b/nativeplugins/NetworkUtils/ios/NetworkUtils.framework/Info.plist new file mode 100644 index 0000000000000000000000000000000000000000..c925cbdbc6b86cc9d7edb65b46bb80dc6ce977b2 GIT binary patch literal 756 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 LPfQl + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the “Software”), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/node_modules/@noble/ciphers/README.md b/node_modules/@noble/ciphers/README.md new file mode 100644 index 0000000..aea8e6b --- /dev/null +++ b/node_modules/@noble/ciphers/README.md @@ -0,0 +1,607 @@ +# noble-ciphers + +Audited & minimal JS implementation of Salsa20, ChaCha and AES. + +- 🔒 [**Audited**](#security) by an independent security firm +- 🔻 Tree-shakeable: unused code is excluded from your builds +- 🏎 Fast: hand-optimized for caveats of JS engines +- 🔍 Reliable: property-based / cross-library / wycheproof tests ensure correctness +- 💼 AES: ECB, CBC, CTR, CFB, GCM, SIV (nonce misuse-resistant), AESKW, AESKWP +- 💃 Salsa20, ChaCha, XSalsa20, XChaCha, ChaCha8, ChaCha12, Poly1305 +- 🥈 Two AES implementations: pure JS or friendly WebCrypto wrapper +- 🪶 11KB (gzipped) for everything, 3KB for ChaCha-only build + +Use [awasm-noble](https://github.com/paulmillr/awasm-noble) if you need an even faster (WASM) alternative. Check out [Upgrading](#upgrading) for information about upgrading from previous versions. +Take a glance at [GitHub Discussions](https://github.com/paulmillr/noble-ciphers/discussions) for questions and support. + +### This library belongs to _noble_ cryptography + +> **noble cryptography** — high-security, easily auditable set of contained cryptographic libraries and tools. + +- Zero or minimal dependencies +- Highly readable TypeScript / JS code +- PGP-signed releases and transparent NPM builds +- All libraries: + [ciphers](https://github.com/paulmillr/noble-ciphers), + [curves](https://github.com/paulmillr/noble-curves), + [hashes](https://github.com/paulmillr/noble-hashes), + [post-quantum](https://github.com/paulmillr/noble-post-quantum), + 5kb [secp256k1](https://github.com/paulmillr/noble-secp256k1) / + [ed25519](https://github.com/paulmillr/noble-ed25519) +- [Check out the homepage](https://paulmillr.com/noble/) + for reading resources, documentation, and apps built with noble + +## Usage + +> `npm install @noble/ciphers` + +> `deno add jsr:@noble/ciphers` + +We support all major platforms and runtimes. +For React Native, you may need a +[polyfill for getRandomValues](https://github.com/LinusU/react-native-get-random-values). +A standalone file +[noble-ciphers.js](https://github.com/paulmillr/noble-ciphers/releases) is also available. + +```ts +// import * from '@noble/ciphers'; // Error: use sub-imports, to ensure small app size +import { gcm, gcmsiv } from '@noble/ciphers/aes.js'; +import { chacha20poly1305, xchacha20poly1305 } from '@noble/ciphers/chacha.js'; +import { xsalsa20poly1305 } from '@noble/ciphers/salsa.js'; + +// Unauthenticated encryption: make sure to use HMAC or similar +import { ctr, cfb, cbc, ecb } from '@noble/ciphers/aes.js'; +import { salsa20, xsalsa20 } from '@noble/ciphers/salsa.js'; +import { chacha20, xchacha20, chacha8, chacha12 } from '@noble/ciphers/chacha.js'; +import { aeskw, aeskwp } from '@noble/ciphers/aes.js'; // KW +import { bytesToHex, hexToBytes, managedNonce, randomBytes } from '@noble/ciphers/utils.js'; +``` + +- [Examples](#examples) + - [XChaCha20-Poly1305 encryption](#xchacha20-poly1305-encryption) + - [AES-256-GCM encryption](#aes-256-gcm-encryption) + - [managedNonce: automatic nonce handling](#managednonce-automatic-nonce-handling) + - [AES: gcm, siv, ctr, cfb, cbc, ecb, aeskw](#aes-gcm-siv-ctr-cfb-cbc-ecb-aeskw) + - [AES: friendly WebCrypto wrapper](#aes-friendly-webcrypto-wrapper) + - [Reuse array for input and output](#reuse-array-for-input-and-output) + - [Use password for encryption](#use-password-for-encryption) +- [Internals](#internals) + - [Picking a cipher](#picking-a-cipher) + - [How to encrypt properly](#how-to-encrypt-properly) + - [Nonces](#nonces) + - [Encryption limits](#encryption-limits) + - [AES block modes](#aes-block-modes) + - [Implemented primitives](#implemented-primitives) +- [Security](#security) +- [Speed](#speed) +- [Upgrading](#upgrading) +- [Contributing & testing](#contributing--testing) +- [License](#license) + +## Examples + +> [!NOTE] +> Use different nonce every time `encrypt()` is done. + +#### XChaCha20-Poly1305 encryption + +```js +import { xchacha20poly1305 } from '@noble/ciphers/chacha.js'; +import { randomBytes } from '@noble/ciphers/utils.js'; +const key = randomBytes(32); // random key +// const key = new Uint8Array([ // existing key +// 169, 88, 160, 139, 168, 29, 147, 196, 14, 88, 237, 76, 243, 177, 109, 140, +// 195, 140, 80, 10, 216, 134, 215, 71, 191, 48, 20, 104, 189, 37, 38, 55, +// ]); +// import { hexToBytes } from '@noble/ciphers/utils.js'; // hex key +// const key = hexToBytes('4b7f89bac90a1086fef73f5da2cbe93b2fae9dfbf7678ae1f3e75fd118ddf999'); +const nonce = randomBytes(24); +const chacha = xchacha20poly1305(key, nonce); +const data = new TextEncoder().encode('hello noble'); +const ciphertext = chacha.encrypt(data); +const data_ = chacha.decrypt(ciphertext); // new TextDecoder().decode(data_) === data +``` + +#### AES-256-GCM encryption + +```js +import { gcm } from '@noble/ciphers/aes.js'; +import { randomBytes } from '@noble/ciphers/utils.js'; +const key = randomBytes(32); +const nonce = randomBytes(24); +const data = new TextEncoder().encode('hello noble'); +const aes = gcm(key, nonce); +const ciphertext = aes.encrypt(data); +const data_ = aes.decrypt(ciphertext); // new TextDecoder().decode(data_) === data +``` + +#### managedNonce: automatic nonce handling + +We provide API that manages nonce internally instead of exposing them to library's user. + +For `encrypt`: a `nonceBytes`-length buffer is fetched from CSPRNG and prenended to encrypted ciphertext. + +For `decrypt`: first `nonceBytes` of ciphertext are treated as nonce. + +> [!NOTE] +> AES-GCM & ChaCha (NOT XChaCha) [limit amount of messages](#encryption-limits) +> encryptable under the same key. + +```js +import { xchacha20poly1305 } from '@noble/ciphers/chacha.js'; +import { hexToBytes, managedNonce } from '@noble/ciphers/utils.js'; +const key = hexToBytes('fa686bfdffd3758f6377abbc23bf3d9bdc1a0dda4a6e7f8dbdd579fa1ff6d7e1'); +const chacha = managedNonce(xchacha20poly1305)(key); // manages nonces for you +const data = new TextEncoder().encode('hello noble'); +const ciphertext = chacha.encrypt(data); +const data_ = chacha.decrypt(ciphertext); +``` + +#### AES: gcm, siv, ctr, cfb, cbc, ecb, aeskw + +```js +import { gcm, gcmsiv, aessiv, ctr, cfb, cbc, ecb } from '@noble/ciphers/aes.js'; +import { randomBytes } from '@noble/ciphers/utils.js'; +const plaintext = new Uint8Array(32).fill(16); +for (let cipher of [gcm, gcmsiv, aessiv]) { + const key = randomBytes(32); // 24 for AES-192, 16 for AES-128 + const nonce = randomBytes(12); + const ciphertext_ = cipher(key, nonce).encrypt(plaintext); + const plaintext_ = cipher(key, nonce).decrypt(ciphertext_); +} +for (const cipher of [ctr, cbc, cfb]) { + const key = randomBytes(32); // 24 for AES-192, 16 for AES-128 + const nonce = randomBytes(16); + const ciphertext_ = cipher(key, nonce).encrypt(plaintext); + const plaintext_ = cipher(key, nonce).decrypt(ciphertext_); +} +for (const cipher of [ecb]) { + const key = randomBytes(32); // 24 for AES-192, 16 for AES-128 + const ciphertext_ = cipher(key).encrypt(plaintext); + const plaintext_ = cipher(key).decrypt(ciphertext_); +} + +// AESKW, AESKWP +import { aeskw, aeskwp } from '@noble/ciphers/aes.js'; +import { hexToBytes } from '@noble/ciphers/utils.js'; + +const kek = hexToBytes('000102030405060708090A0B0C0D0E0F'); +const keyData = hexToBytes('00112233445566778899AABBCCDDEEFF'); +const ciphertext = aeskw(kek).encrypt(keyData); +``` + +#### AES: friendly WebCrypto wrapper + +Noble implements AES. Sometimes people want to use built-in `crypto.subtle` instead. However, it has terrible API. We simplify access to built-ins. + +> [!NOTE] +> Webcrypto methods are always async. + +```js +import { gcm, ctr, cbc } from '@noble/ciphers/webcrypto.js'; +import { randomBytes } from '@noble/ciphers/utils.js'; +const plaintext = new Uint8Array(32).fill(16); +const key = randomBytes(32); +for (const cipher of [gcm]) { + const nonce = randomBytes(12); + const ciphertext_ = await cipher(key, nonce).encrypt(plaintext); + const plaintext_ = await cipher(key, nonce).decrypt(ciphertext_); +} +for (const cipher of [ctr, cbc]) { + const nonce = randomBytes(16); + const ciphertext_ = await cipher(key, nonce).encrypt(plaintext); + const plaintext_ = await cipher(key, nonce).decrypt(ciphertext_); +} +``` + +#### Reuse array for input and output + +To avoid additional allocations, Uint8Array can be reused +between encryption and decryption calls. + +> [!NOTE] +> Some ciphers don't support unaligned (`byteOffset % 4 !== 0`) Uint8Array as +> destination. It can decrease performance, making the optimization pointless. + +```js +import { chacha20poly1305 } from '@noble/ciphers/chacha.js'; +import { randomBytes } from '@noble/ciphers/utils.js'; + +const key = randomBytes(32); +const nonce = randomBytes(12); +const chacha = chacha20poly1305(key, nonce); + +const input = new TextEncoder().encode('hello noble'); // length == 12 +const inputLength = input.length; +const tagLength = 16; + +const buf = new Uint8Array(inputLength + tagLength); +const start = buf.subarray(0, inputLength); +start.set(input); // copy input to buf + +chacha.encrypt(start, buf); // encrypt into `buf` +chacha.decrypt(buf, start); // decrypt into `start` +``` + +xsalsa20poly1305 also supports this, but requires 32 additional bytes for encryption / decryption, +due to its inner workings. + +#### Randomness generation + +We provide userspace CSPRNG (cryptographically secure pseudorandom number generator). +It's best to limit their usage to non-production, non-critical cases: for example, test-only usage. +ChaCha-based CSPRNG does not have a specification as per 2025, which makes it less secure. + +```js +import { randomBytes } from '@noble/ciphers/utils.js'; +import { rngAesCtrDrbg256 } from '@noble/ciphers/aes.js'; +import { rngChacha8, rngChacha20 } from '@noble/ciphers/chacha.js'; + +// 1. Best: WebCrypto +const rnd1 = randomBytes(32); +// 2. AES-CTR DRBG +const seed2 = randomBytes(48); +const rnd2 = rngAesCtrDrbg256(seed2).randomBytes(1024); +// 3. ChaCha8 CSPRNG +const seed3 = randomBytes(32); +const rnd3 = rngChacha8(seed3).randomBytes(1024); +``` + +#### Use password for encryption + +It is not safe to convert password into Uint8Array. +Instead, KDF stretching function like PBKDF2 / Scrypt / Argon2id +should be applied to convert password to AES key. +Make sure to use salt (app-specific secret) in addition to password. + +> `npm install @noble/hashes` + +```js +import { xchacha20poly1305 } from '@noble/ciphers/chacha.js'; +import { managedNonce } from '@noble/ciphers/utils.js'; +import { scrypt } from '@noble/hashes/scrypt.js'; + +// Convert password into 32-byte key using scrypt +const PASSWORD = 'correct-horse-battery-staple'; +const APP_SPECIFIC_SECRET = 'salt-12345678-secret'; +const SECURITY_LEVEL = 2 ** 20; // requires 1GB of RAM to calculate +// sync, but scryptAsync is also available +const key = scrypt(PASSWORD, APP_SPECIFIC_SECRET, { N: SECURITY_LEVEL, r: 8, p: 1, dkLen: 32 }); + +// Use random, managed nonce +const chacha = managedNonce(xchacha20poly1305)(key); + +const data = new TextEncoder().encode('hello noble'); +const ciphertext = chacha.encrypt(data); +const data_ = chacha.decrypt(ciphertext); +``` + +## Internals + +### Picking a cipher + +We suggest to use **XChaCha20-Poly1305** because it's very fast and allows random keys. +**AES-GCM-SIV** is also a good idea, because it provides resistance against nonce reuse. +**AES-GCM** is a good option when those two are not available. + +### How to encrypt properly + +- Use unpredictable key with enough entropy + - Random key must be using cryptographically secure random number generator (CSPRNG), not `Math.random` etc. + - Non-random key generated from KDF is fine + - Re-using key is fine, but be aware of rules for cryptographic key wear-out and [encryption limits](#encryption-limits) +- Use new nonce every time and [don't repeat it](#nonces) + - chacha and salsa20 are fine for sequential counters that _never_ repeat: `01, 02...` + - xchacha and xsalsa20 can use random nonces instead + - AES-GCM should use 12-byte nonces: smaller nonces are security risk +- Prefer authenticated encryption (AEAD) + - Good: chacha20poly1305, GCM, GCM-SIV, ChaCha+HMAC, CTR+HMAC, CBC+HMAC + - Bad: chacha20, raw CTR, raw CBC + - Flipping bits or ciphertext substitution won't be detected in unauthenticated ciphers + - Polynomial MACs are not perfect for every situation: + they lack Random Key Robustness: the MAC can be forged, and can't + be used in PAKE schemes. See + [invisible salamanders attack](https://keymaterial.net/2020/09/07/invisible-salamanders-in-aes-gcm-siv/). + To combat salamanders, `hash(key)` can be included in ciphertext, + however, this would violate ciphertext indistinguishability: + an attacker would know which key was used - so `HKDF(key, i)` + could be used instead. +- Don't re-use keys between different protocols + - For example, using ECDH key in AES can be bad + - Use hkdf or, at least, a hash function to create sub-key instead + +### Nonces + +Most ciphers need a key and a nonce (aka initialization vector / IV) to encrypt a data. +Repeating (key, nonce) pair with different plaintexts would allow an attacker to decrypt it. + + ciphertext_a = encrypt(plaintext_a, key, nonce) + ciphertext_b = encrypt(plaintext_b, key, nonce) + stream_diff = xor(ciphertext_a, ciphertext_b) # Break encryption + +One way of not repeating nonces is using counters: + + for i in 0..: + ciphertext[i] = encrypt(plaintexts[i], key, i) + +Another is generating random nonce every time: + + for i in 0..: + rand_nonces[i] = random() + ciphertext[i] = encrypt(plaintexts[i], key, rand_nonces[i]) + +- Counters are OK, but it's not always possible to store current counter value: + e.g. in decentralized, unsyncable systems. +- Randomness is OK, but there's a catch: + ChaCha20 and AES-GCM use 96-bit / 12-byte nonces, which implies higher chance of collision. + In the example above, `random()` can collide and produce repeating nonce. + Chance is even higher for 64-bit nonces, which GCM allows - don't use them. +- To safely use random nonces, utilize XSalsa20 or XChaCha: + they increased nonce length to 192-bit, minimizing a chance of collision. + AES-SIV is also fine. In situations where you can't use eXtended-nonce + algorithms, key rotation is advised. hkdf would work great for this case. + +### Encryption limits + +A "protected message" would mean a probability of `2**-50` that a passive attacker +successfully distinguishes the ciphertext outputs of the AEAD scheme from the outputs +of a random function. + +- Max message size: + - AES-GCM: ~68GB, `2**36-256` + - Salsa, ChaCha, XSalsa, XChaCha: ~256GB, `2**38-64` +- Max amount of protected messages, under same key: + - AES-GCM: `2**32.5` + - Salsa, ChaCha: `2**46`, but only integrity (MAC) is affected, not confidentiality (encryption) + - XSalsa, XChaCha: `2**72` +- Max amount of protected messages, across all keys: + - AES-GCM: `2**69/B` where B is max blocks encrypted by a key. Meaning + `2**59` for 1KB, `2**49` for 1MB, `2**39` for 1GB + - Salsa, ChaCha, XSalsa, XChaCha: `2**100` +- Max amount of protected messages, under same key, using **random nonce**: + - Relevant for 12-byte nonces with `managedNonce`: AES-GCM, ChaCha + - `2**23` (8M) messages for `2**-50` chance, `2**32.5` (4B) for `2**-32.5` chance + +Check out [draft-irtf-cfrg-aead-limits](https://datatracker.ietf.org/doc/draft-irtf-cfrg-aead-limits/) for details. + +### Implemented primitives + +- Salsa20 stream cipher, released in 2005. + Salsa's goal was to implement AES replacement that does not rely on S-Boxes, + which are hard to implement in a constant-time manner. + Salsa20 is usually faster than AES, a big deal on slow, budget mobile phones. + - [XSalsa20](https://cr.yp.to/snuffle/xsalsa-20110204.pdf), extended-nonce + variant was released in 2008. It switched nonces from 96-bit to 192-bit, + and became safe to be picked at random. + - Nacl / Libsodium popularized term "secretbox", - which is just xsalsa20poly1305. + We provide the alias and corresponding seal / open methods. + "crypto_box" and "sealedbox" are available in package [noble-sodium](https://github.com/serenity-kit/noble-sodium). + - Check out [PDF](https://cr.yp.to/snuffle/salsafamily-20071225.pdf) + and [website](https://cr.yp.to/snuffle.html). +- ChaCha20 stream cipher, released in 2008. Developed after Salsa20, + ChaCha aims to increase diffusion per round. + - [XChaCha20](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha) + extended-nonce variant is also provided. Similar to XSalsa, it's safe to use with + randomly-generated nonces. + - Check out + [RFC 8439](https://www.rfc-editor.org/rfc/rfc8439), + [PDF](http://cr.yp.to/chacha/chacha-20080128.pdf) and + [website](https://cr.yp.to/chacha.html). +- AES is a variant of Rijndael block cipher, standardized by NIST in 2001. + We provide the fastest available pure JS implementation. + - We support AES-128, AES-192 and AES-256: the mode is selected dynamically, + based on key length (16, 24, 32). + - AES-GCM-SIV nonce-misuse-resistant mode is also provided. Our implementation of SIV + has the same speed as GCM: there is no performance hit. + The mode is described in [RFC 8452](https://www.rfc-editor.org/rfc/rfc8452). + - There is a separate AES-SIV mode, described in [RFC 5297](https://www.rfc-editor.org/rfc/rfc5297) + - We also have AESKW and AESKWP from + [RFC 3394](https://www.rfc-editor.org/rfc/rfc3394) & [RFC 5649](https://www.rfc-editor.org/rfc/rfc5649) + - Format-preserving encryption algorithm (FPE-FF1) specified in + [NIST SP 800-38G](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38G.pdf). + - Check out [AES block modes](#aes-block-modes), + [FIPS 197](https://csrc.nist.gov/files/pubs/fips/197/final/docs/fips-197.pdf) and + [original proposal](https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/aes-development/rijndael-ammended.pdf). +- Polynomial-evaluation MACs are available: Poly1305, AES-GCM's GHash and AES-SIV's Polyval. + - Poly1305 ([PDF](https://cr.yp.to/mac/poly1305-20050329.pdf), + [website](https://cr.yp.to/mac.html)) + is a fast and parallel secret-key message-authentication code suitable for + a wide variety of applications. It was standardized in + [RFC 8439](https://www.rfc-editor.org/rfc/rfc8439) and is now used in TLS 1.3. + - Ghash is used in AES-GCM: see NIST SP 800-38G + - Polyval is used in AES-GCM-SIV: see [RFC 8452](https://www.rfc-editor.org/rfc/rfc8452) + +##### AES block modes + +For non-deterministic (not ECB) schemes, initialization vector (IV) is mixed to block/key; +and each new round either depends on previous block's key, or on some counter. + +- **ECB** (Electronic Codebook): Deterministic encryption; identical plaintext blocks yield identical ciphertexts. Not secure due to pattern leakage. due to pattern leakage. + See [AES Penguin](https://words.filippo.io/the-ecb-penguin/) +- **CBC** (Cipher Block Chaining): Each plaintext block is XORed with the previous block of ciphertext + before encryption. Hard to use: requires proper padding and an IV. Unauthenticated: needs MAC. +- **CTR** (Counter Mode): Turns a block cipher into a stream cipher using a counter and IV (nonce). + Efficient and parallelizable. Requires a unique nonce per encryption. Unauthenticated: needs MAC. +- **GCM** (Galois/Counter Mode): Combines CTR mode with polynomial MAC. Efficient and widely used. Not perfect: + a) conservative key wear-out is `2**32` (4B) msgs. + b) key wear-out under random nonces is even smaller: `2**23` (8M) messages for `2**-50` chance. + c) MAC can be forged: see Poly1305 documentation. +- **SIV** (Synthetic IV): GCM with nonce-misuse resistance; repeating nonces reveal only the fact plaintexts + are identical. Also suffers from GCM issues: key wear-out limits & MAC forging. +- **XTS**: Designed for disk encryption. + Similar to ECB (deterministic), but has `[i][j]` tweak arguments corresponding to + sector i and 16-byte block (part of sector) j. Lacks MAC. + +## Security + +The library has been audited: + +- at version 2.2.0, in Apr 2026, by ourselves (self-audited) + - Scope: everything + - [Changes since audit](https://github.com/paulmillr/noble-ciphers/compare/2.2.0..main) +- at version 1.0.0, in Sep 2024, independently, by [cure53](https://cure53.de) + - PDFs: [website](https://cure53.de/audit-report_noble-crypto-libs.pdf), [in-repo](./audit/2024-09-cure53-audit-nbl4.pdf) + - [Changes since audit](https://github.com/paulmillr/noble-ciphers/compare/1.0.0..main) + - Scope: everything + - The audit has been funded by [OpenSats](https://opensats.org) + +It is tested against property-based, cross-library and Wycheproof vectors, +and is being fuzzed in [the separate repo](https://github.com/paulmillr/fuzzing). + +If you see anything unusual: investigate and report. + +### Constant-timeness + +We're targetting algorithmic constant time. _JIT-compiler_ and _Garbage Collector_ make "constant time" +extremely hard to achieve [timing attack](https://en.wikipedia.org/wiki/Timing_attack) resistance +in a scripting language. Which means _any other JS library can't have +constant-timeness_. Even statically typed Rust, a language without GC, +[makes it harder to achieve constant-time](https://www.chosenplaintext.ca/open-source/rust-timing-shield/security) +for some cases. If your goal is absolute security, don't use any JS lib — including bindings to native ones. +Use low-level libraries & languages. + +The library uses T-tables for AES, which +[leak access timings](https://cr.yp.to/antiforgery/cachetiming-20050414.pdf). +This is also done in [OpenSSL](https://github.com/openssl/openssl/blob/2f33265039cdbd0e4589c80970e02e208f3f94d2/crypto/aes/aes_core.c#L706) and +[Go stdlib](https://cs.opensource.google/go/go/+/refs/tags/go1.22.6:src/crypto/aes/const.go;l=90) for performance reasons. +The analysis was mentioned in [hal-04652991](https://hal.science/hal-04652991/document). + +### Supply chain security + +- **Commits** are signed with PGP keys to prevent forgery. Be sure to verify the commit signatures +- **Releases** are made transparently through token-less GitHub CI and Trusted Publishing. Be sure to verify the [provenance logs](https://docs.npmjs.com/generating-provenance-statements) for authenticity. +- **Rare releasing** is practiced to minimize the need for re-audits by end-users. +- **Dependencies** are minimized and strictly pinned to reduce supply-chain risk. + - We use as few dependencies as possible. + - Version ranges are locked, and changes are checked with npm-diff. +- **Dev dependencies** are excluded from end-user installs; they’re only used for development and build steps. + +For this package, there are 0 dependencies; and a few dev dependencies: + +- jsbt is used for benchmarking / testing / build tooling and developed by the same author +- prettier, fast-check and typescript are used for code quality / test generation / ts compilation + +### Randomness + +We rely on the built-in +[`crypto.getRandomValues`](https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues), +which is considered a cryptographically secure PRNG. + +Browsers have had weaknesses in the past - and could again - but implementing a userspace CSPRNG is even worse, as there’s no reliable userspace source of high-quality entropy. + +### Quantum computers + +Cryptographically relevant quantum computer, if built, will allow to +utilize Grover's algorithm to break ciphers in 2^n/2 operations, instead of 2^n. + +This means AES128 should be replaced with AES256. Salsa and ChaCha are already safe. + +Australian ASD prohibits AES128 [after 2030](https://www.cyber.gov.au/resources-business-and-government/essential-cyber-security/ism/cyber-security-guidelines/guidelines-cryptography). + +## Speed + +```sh +npm run bench +``` + +Benchmarks measured on Apple M4. +If you need truly exemplar performance, switch to [awasm-noble](https://github.com/paulmillr/awasm-noble). + +``` +64B +xsalsa20poly1305 x 735,835 ops/sec @ 1μs/op +chacha20poly1305 x 581,395 ops/sec @ 1μs/op +xchacha20poly1305 x 468,384 ops/sec @ 2μs/op +aes-256-gcm x 201,126 ops/sec @ 4μs/op +aes-256-gcm-siv x 162,284 ops/sec @ 6μs/op +# Unauthenticated encryption +salsa20 x 1,655,629 ops/sec @ 604ns/op +xsalsa20 x 1,400,560 ops/sec @ 714ns/op +chacha20 x 1,996,007 ops/sec @ 501ns/op +xchacha20 x 1,404,494 ops/sec @ 712ns/op +chacha8 x 2,145,922 ops/sec @ 466ns/op +chacha12 x 2,036,659 ops/sec @ 491ns/op +aes-ecb-256 x 1,019,367 ops/sec @ 981ns/op +aes-cbc-256 x 931,966 ops/sec @ 1μs/op +aes-ctr-256 x 954,198 ops/sec @ 1μs/op + +1MB +xsalsa20poly1305 x 334 ops/sec @ 2ms/op +chacha20poly1305 x 333 ops/sec @ 2ms/op +xchacha20poly1305 x 334 ops/sec @ 2ms/op +aes-256-gcm x 94 ops/sec @ 10ms/op +aes-256-gcm-siv x 90 ops/sec @ 11ms/op +# Unauthenticated encryption +salsa20 x 831 ops/sec @ 1ms/op +xsalsa20 x 830 ops/sec @ 1ms/op +chacha20 x 804 ops/sec @ 1ms/op +xchacha20 x 797 ops/sec @ 1ms/op +chacha8 x 1,495 ops/sec @ 668μs/op +chacha12 x 1,148 ops/sec @ 871μs/op +aes-ecb-256 x 289 ops/sec @ 3ms/op +aes-cbc-256 x 114 ops/sec @ 8ms/op +aes-ctr-256 x 127 ops/sec @ 7ms/op +# Wrapper over built-in webcrypto +webcrypto ctr-256 x 6,508 ops/sec @ 153μs/op +webcrypto cbc-256 x 1,820 ops/sec @ 549μs/op +webcrypto gcm-256 x 5,106 ops/sec @ 195μs/op +``` + +Compare to other implementations: + +``` +xsalsa20poly1305 (encrypt, 1MB) +├─tweetnacl x 196 mb/sec +├─awasm-noble_threads x 2,318 mb/sec +├─awasm-noble_no_threads x 1,196 mb/sec +└─noble x 305 mb/sec + +aes-ctr-256 (encrypt, 1MB) +├─stablelib x 123 mb/sec +├─aesjs x 42 mb/sec +├─awasm-noble_thread x 2,105 mb/sec +├─awasm-noble_no_threads x 272 mb/sec +├─noble_webcrypto x 5,965 mb/sec +└─noble x 124 mb/sec +``` + +## Upgrading + +Supported node.js versions: + +- v2: v20.19+ (ESM-only) +- v1: v14.21+ (ESM & CJS) + +Changelog of v2, when upgrading from ciphers v1: + +- The package is now ESM-only. ESM can finally be loaded from common.js on node v20.19+ +- `.js` extension must be used for all modules + - Old: `@noble/ciphers/aes` + - New: `@noble/ciphers/aes.js` + - This simplifies working in browsers natively without transpilers +- webcrypto: move `randomBytes` and `managedNonce` to `utils.js` +- ghash, poly1305, polyval: only allow Uint8Array as hash inputs, prohibit `string` +- utils: new abytes; remove ahash, toBytes +- Remove modules `_assert` (use `utils`), `_micro` and `crypto` (use `webcrypto`) +- Bump TS compilation target from es2020 to es2022 +- Massively improve error messages, make them more descriptive + +## Contributing & testing + +- `npm install && npm run build && npm test` will build the code and run tests. +- `npm run lint` / `npm run format` will run linter / fix linter issues. +- `npm run bench` will run benchmarks +- `npm run build:release` will build single file + +See [paulmillr.com/noble](https://paulmillr.com/noble/) +for useful resources, articles, documentation and demos +related to the library. + +## License + +The MIT License (MIT) + +Copyright (c) 2023 Paul Miller [(https://paulmillr.com)](https://paulmillr.com) +Copyright (c) 2016 Thomas Pornin + +See LICENSE file. diff --git a/node_modules/@noble/ciphers/_arx.d.ts b/node_modules/@noble/ciphers/_arx.d.ts new file mode 100644 index 0000000..e8c7931 --- /dev/null +++ b/node_modules/@noble/ciphers/_arx.d.ts @@ -0,0 +1,145 @@ +/** + * Basic utils for ARX (add-rotate-xor) salsa and chacha ciphers. + +RFC8439 requires multi-step cipher stream, where +authKey starts with counter: 0, actual msg with counter: 1. + +For this, we need a way to re-use nonce / counter: + + const counter = new Uint8Array(4); + chacha(..., counter, ...); // counter is now 1 + chacha(..., counter, ...); // counter is now 2 + +This is complicated: + +- 32-bit counters are enough, no need for 64-bit: max ArrayBuffer size in JS is 4GB +- Original papers don't allow mutating counters +- Counter overflow is undefined [^1] +- Idea A: allow providing (nonce | counter) instead of just nonce, re-use it +- Caveat: Cannot be re-used through all cases: +- * chacha has (counter | nonce) +- * xchacha has (nonce16 | counter | nonce16) +- Idea B: separate nonce / counter and provide separate API for counter re-use +- Caveat: there are different counter sizes depending on an algorithm. +- salsa & chacha also differ in structures of key & sigma: + salsa20: s[0] | k(4) | s[1] | nonce(2) | cnt(2) | s[2] | k(4) | s[3] + chacha: s(4) | k(8) | cnt(1) | nonce(3) + chacha20orig: s(4) | k(8) | cnt(2) | nonce(2) +- Idea C: helper method such as `setSalsaState(key, nonce, sigma, data)` +- Caveat: we can't re-use counter array + +xchacha uses the subkey and remaining 8 byte nonce with ChaCha20 as normal +(prefixed by 4 NUL bytes, since RFC8439 specifies a 12-byte nonce). +Counter overflow is undefined; see {@link https://mailarchive.ietf.org/arch/msg/cfrg/gsOnTJzcbgG6OqD8Sc0GO5aR_tU/ | the CFRG thread}. +Current noble policy is strict non-wrap for the shared 32-bit counter path: +exported ARX ciphers reject initial `0xffffffff` and stop before any implicit +wrap back to zero. +See {@link https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha#appendix-A.2 | the XChaCha appendix} for the extended-nonce construction. + + * @module + */ +import { type PRG, type TArg, type TRet, type XorStream } from './utils.ts'; +/** + * Rotates a 32-bit word left. + * @param a - Input word. + * @param b - Rotation count in bits. + * @returns Rotated 32-bit word. + * @example + * Moves the top byte of `0x12345678` into the low byte position. + * ```ts + * rotl(0x12345678, 8); + * ``` + */ +export declare function rotl(a: number, b: number): number; +/** + * ARX core function operating on 32-bit words. Ciphers must use u32 for efficiency. + * @param sigma - Sigma constants for the selected cipher layout. + * @param key - Expanded key words. + * @param nonce - Nonce and counter words prepared for the round function. + * @param output - Output block written in place. + * @param counter - Block counter value. + * @param rounds - Optional round count override. + */ +export type CipherCoreFn = (sigma: TArg, key: TArg, nonce: TArg, output: TArg, counter: number, rounds?: number) => void; +/** + * Nonce-extension function used by XChaCha and XSalsa. + * @param sigma - Sigma constants for the selected cipher layout. + * @param key - Expanded key words. + * @param input - Input nonce words used for subkey derivation. + * @param output - Output buffer written with the derived nonce words. + */ +export type ExtendNonceFn = (sigma: TArg, key: TArg, input: TArg, output: TArg) => void; +/** ARX cipher options. + * * `allowShortKeys` for 16-byte keys + * * `counterLength` in bytes + * * `counterRight`: right: `nonce|counter`; left: `counter|nonce` + * */ +export type CipherOpts = { + /** Whether 16-byte keys are accepted for legacy Salsa and ChaCha variants. */ + allowShortKeys?: boolean; + /** Optional nonce-expansion hook used by extended-nonce variants. */ + extendNonceFn?: ExtendNonceFn; + /** Counter length in bytes inside the nonce/counter layout. */ + counterLength?: number; + /** Whether the layout is `nonce|counter` instead of `counter|nonce`. */ + counterRight?: boolean; + /** Number of core rounds to execute. */ + rounds?: number; +}; +/** + * Creates an ARX stream cipher from a 32-bit core permutation. + * Used internally to build the exported Salsa and ChaCha stream ciphers. + * @param core - Core function that fills one keystream block. + * @param opts - Cipher layout and nonce-extension options. See {@link CipherOpts}. + * @returns Stream cipher function over byte arrays. + * @throws If the core callback, key size, counter, or output sizing is invalid. {@link Error} + */ +export declare function createCipher(core: TArg, opts: TArg): TRet; +/** Internal class which wraps chacha20 or chacha8 to create CSPRNG. */ +export declare class _XorStreamPRG implements PRG { + readonly blockLen: number; + readonly keyLen: number; + readonly nonceLen: number; + private state; + private buf; + private key; + private nonce; + private pos; + private ctr; + private cipher; + constructor(cipher: TArg, blockLen: number, keyLen: number, nonceLen: number, seed: TArg); + private reseed; + addEntropy(seed: TArg): void; + randomBytes(len: number): TRet; + clone(): _XorStreamPRG; + clean(): void; +} +/** + * PRG constructor backed by an ARX stream cipher. + * @param seed - Optional seed bytes mixed into the initial state. When omitted, exactly 32 + * random bytes are mixed in by default: larger states keep a zero tail, while smaller states + * wrap those bytes through `reseed()`'s XOR schedule. + * @returns Seeded concrete `_XorStreamPRG` instance, including `clone()`. + */ +export type XorPRG = (seed?: TArg) => TRet<_XorStreamPRG>; +/** + * Creates a PRG constructor from a stream cipher. + * @param cipher - Stream cipher used to fill output blocks. + * @param blockLen - Keystream block length in bytes. + * @param keyLen - Internal key length in bytes. + * @param nonceLen - Internal nonce length in bytes. + * @returns PRG factory for seeded concrete `_XorStreamPRG` instances. + * @example + * Builds a PRG from XChaCha20 and reads bytes from a randomly seeded instance. + * ```ts + * import { xchacha20 } from '@noble/ciphers/chacha.js'; + * import { createPRG } from '@noble/ciphers/_arx.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const seed = randomBytes(32); + * const init = createPRG(xchacha20, 64, 32, 24); + * const prg = init(seed); + * prg.randomBytes(8); + * ``` + */ +export declare const createPRG: (cipher: TArg, blockLen: number, keyLen: number, nonceLen: number) => TRet; +//# sourceMappingURL=_arx.d.ts.map \ No newline at end of file diff --git a/node_modules/@noble/ciphers/_arx.d.ts.map b/node_modules/@noble/ciphers/_arx.d.ts.map new file mode 100644 index 0000000..2d385c0 --- /dev/null +++ b/node_modules/@noble/ciphers/_arx.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"_arx.d.ts","sourceRoot":"","sources":["src/_arx.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@noble/ciphers/_arx.js b/node_modules/@noble/ciphers/_arx.js new file mode 100644 index 0000000..e182c7b --- /dev/null +++ b/node_modules/@noble/ciphers/_arx.js @@ -0,0 +1,369 @@ +/** + * Basic utils for ARX (add-rotate-xor) salsa and chacha ciphers. + +RFC8439 requires multi-step cipher stream, where +authKey starts with counter: 0, actual msg with counter: 1. + +For this, we need a way to re-use nonce / counter: + + const counter = new Uint8Array(4); + chacha(..., counter, ...); // counter is now 1 + chacha(..., counter, ...); // counter is now 2 + +This is complicated: + +- 32-bit counters are enough, no need for 64-bit: max ArrayBuffer size in JS is 4GB +- Original papers don't allow mutating counters +- Counter overflow is undefined [^1] +- Idea A: allow providing (nonce | counter) instead of just nonce, re-use it +- Caveat: Cannot be re-used through all cases: +- * chacha has (counter | nonce) +- * xchacha has (nonce16 | counter | nonce16) +- Idea B: separate nonce / counter and provide separate API for counter re-use +- Caveat: there are different counter sizes depending on an algorithm. +- salsa & chacha also differ in structures of key & sigma: + salsa20: s[0] | k(4) | s[1] | nonce(2) | cnt(2) | s[2] | k(4) | s[3] + chacha: s(4) | k(8) | cnt(1) | nonce(3) + chacha20orig: s(4) | k(8) | cnt(2) | nonce(2) +- Idea C: helper method such as `setSalsaState(key, nonce, sigma, data)` +- Caveat: we can't re-use counter array + +xchacha uses the subkey and remaining 8 byte nonce with ChaCha20 as normal +(prefixed by 4 NUL bytes, since RFC8439 specifies a 12-byte nonce). +Counter overflow is undefined; see {@link https://mailarchive.ietf.org/arch/msg/cfrg/gsOnTJzcbgG6OqD8Sc0GO5aR_tU/ | the CFRG thread}. +Current noble policy is strict non-wrap for the shared 32-bit counter path: +exported ARX ciphers reject initial `0xffffffff` and stop before any implicit +wrap back to zero. +See {@link https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha#appendix-A.2 | the XChaCha appendix} for the extended-nonce construction. + + * @module + */ +import { abool, abytes, anumber, checkOpts, clean, copyBytes, getOutput, isAligned32, isLE, randomBytes, swap32IfBE, u32, } from "./utils.js"; +// Replaces `TextEncoder` for ASCII literals, which is enough for sigma constants. +// Non-ASCII input would not match UTF-8 `TextEncoder` output. +const encodeStr = (str) => Uint8Array.from(str.split(''), (c) => c.charCodeAt(0)); +// Raw `createCipher(...)` exports consume these native-endian `u32(...)` views directly. +// Public `wrapCipher(...)` APIs reject non-little-endian platforms before reaching this path. +// RFC 8439 §2.3 / RFC 7539 §2.3 only define the 256-bit-key constants; this 16-byte sigma is +// kept for legacy allowShortKeys Salsa/ChaCha variants. +const sigma16_32 = /* @__PURE__ */ (() => swap32IfBE(u32(encodeStr('expand 16-byte k'))))(); +// RFC 8439 §2.3 / RFC 7539 §2.3 define words 0-3 as +// `0x61707865 0x3320646e 0x79622d32 0x6b206574`, i.e. `expand 32-byte k`. +const sigma32_32 = /* @__PURE__ */ (() => swap32IfBE(u32(encodeStr('expand 32-byte k'))))(); +/** + * Rotates a 32-bit word left. + * @param a - Input word. + * @param b - Rotation count in bits. + * @returns Rotated 32-bit word. + * @example + * Moves the top byte of `0x12345678` into the low byte position. + * ```ts + * rotl(0x12345678, 8); + * ``` + */ +export function rotl(a, b) { + return (a << b) | (a >>> (32 - b)); +} +// Salsa and Chacha block length is always 512-bit +const BLOCK_LEN = 64; +// RFC 8439 §2.2 / RFC 7539 §2.2: the ChaCha state has 16 32-bit words. +const BLOCK_LEN32 = 16; +// Counter policy for the shared public `counter` argument: +// - RFC/IETF ChaCha20 uses a 32-bit counter. +// - OpenSSL/Node `chacha20` instead treat the full 16-byte IV as a 128-bit +// counter state and carry into the next word. +// - Raw `chacha20orig`, `salsa20`, `xsalsa20`, and `xchacha20` use 64-bit counters in libsodium +// and libtomcrypt, while some libs (for example libtomcrypt's RFC/IETF path) reject the max +// boundary instead of carrying. +// - AEAD wrappers diverge too: libsodium `xchacha20poly1305` uses the IETF payload counter from +// block 1, while `secretstream_xchacha20poly1305` is a different protocol with rekey/reset. +// Noble intentionally throws instead of silently picking one wrap model for users. In the default +// path, even a 32-bit boundary would take 2^32 blocks * 64 bytes = 256 GiB, which is practically +// unreachable for normal JS callers; advanced users who pass `counter` explicitly can implement +// whatever wider carry / wrap policy they need on top. +const MAX_COUNTER = /* @__PURE__ */ (() => 2 ** 32 - 1)(); +const U32_EMPTY = /* @__PURE__ */ Uint32Array.of(); +function runCipher(core, sigma, key, nonce, data, output, counter, rounds) { + const len = data.length; + const block = new Uint8Array(BLOCK_LEN); + const b32 = u32(block); + // Make sure that buffers aligned to 4 bytes + const isAligned = isLE && isAligned32(data) && isAligned32(output); + const d32 = isAligned ? u32(data) : U32_EMPTY; + const o32 = isAligned ? u32(output) : U32_EMPTY; + // RFC 8439 §2.4.1 / RFC 7539 §2.4.1 allow XORing one keystream block at a time and + // truncating the final partial block instead of materializing the whole keystream. + if (!isLE) { + for (let pos = 0; pos < len; counter++) { + core(sigma, key, nonce, b32, counter, rounds); + // RFC 8439 §2.4 / RFC 7539 §2.4 serialize keystream words in little-endian order. + swap32IfBE(b32); + if (counter >= MAX_COUNTER) + throw new Error('arx: counter overflow'); + const take = Math.min(BLOCK_LEN, len - pos); + for (let j = 0, posj; j < take; j++) { + posj = pos + j; + output[posj] = data[posj] ^ block[j]; + } + pos += take; + } + return; + } + for (let pos = 0; pos < len; counter++) { + core(sigma, key, nonce, b32, counter, rounds); + // See MAX_COUNTER policy note above: never silently wrap the shared public counter. + if (counter >= MAX_COUNTER) + throw new Error('arx: counter overflow'); + const take = Math.min(BLOCK_LEN, len - pos); + // aligned to 4 bytes + if (isAligned && take === BLOCK_LEN) { + const pos32 = pos / 4; + if (pos % 4 !== 0) + throw new Error('arx: invalid block position'); + for (let j = 0, posj; j < BLOCK_LEN32; j++) { + posj = pos32 + j; + o32[posj] = d32[posj] ^ b32[j]; + } + pos += BLOCK_LEN; + continue; + } + for (let j = 0, posj; j < take; j++) { + posj = pos + j; + output[posj] = data[posj] ^ block[j]; + } + pos += take; + } +} +/** + * Creates an ARX stream cipher from a 32-bit core permutation. + * Used internally to build the exported Salsa and ChaCha stream ciphers. + * @param core - Core function that fills one keystream block. + * @param opts - Cipher layout and nonce-extension options. See {@link CipherOpts}. + * @returns Stream cipher function over byte arrays. + * @throws If the core callback, key size, counter, or output sizing is invalid. {@link Error} + */ +export function createCipher(core, opts) { + const { allowShortKeys, extendNonceFn, counterLength, counterRight, rounds } = checkOpts({ allowShortKeys: false, counterLength: 8, counterRight: false, rounds: 20 }, opts); + if (typeof core !== 'function') + throw new Error('core must be a function'); + anumber(counterLength); + anumber(rounds); + abool(counterRight); + abool(allowShortKeys); + return (key, nonce, data, output, counter = 0) => { + abytes(key, undefined, 'key'); + abytes(nonce, undefined, 'nonce'); + abytes(data, undefined, 'data'); + const len = data.length; + // Raw XorStream APIs return ciphertext/plaintext bytes directly, so caller-provided outputs + // must match the logical result length exactly instead of returning an oversized workspace. + output = getOutput(len, output, false); + anumber(counter); + // See MAX_COUNTER policy note above: reject advanced explicit-counter requests before any wrap. + if (counter < 0 || counter >= MAX_COUNTER) + throw new Error('arx: counter overflow'); + const toClean = []; + // Key & sigma + // key=16 -> sigma16, k=key|key + // key=32 -> sigma32, k=key + let l = key.length; + let k; + let sigma; + if (l === 32) { + // Copy caller keys too: big-endian normalization, extended-nonce subkey derivation, and + // final clean(...) all mutate or wipe the temporary buffer in place. + toClean.push((k = copyBytes(key))); + sigma = sigma32_32; + } + else if (l === 16 && allowShortKeys) { + k = new Uint8Array(32); + k.set(key); + k.set(key, 16); + sigma = sigma16_32; + toClean.push(k); + } + else { + abytes(key, 32, 'arx key'); + throw new Error('invalid key size'); + // throw new Error(`"arx key" expected Uint8Array of length 32, got length=${l}`); + } + // Nonce + // salsa20: 8 (8-byte counter) + // chacha20orig: 8 (8-byte counter) + // chacha20: 12 (4-byte counter) + // xsalsa20: 24 (16 -> hsalsa, 8 -> old nonce) + // xchacha20: 24 (16 -> hchacha, 8 -> old nonce) + // Copy before taking u32(...) views on misaligned inputs, and on big-endian so later + // swap32IfBE(...) never mutates caller nonce bytes in place. + if (!isLE || !isAligned32(nonce)) + toClean.push((nonce = copyBytes(nonce))); + let k32 = u32(k); + // hsalsa & hchacha: handle extended nonce + if (extendNonceFn) { + if (nonce.length !== 24) + throw new Error(`arx: extended nonce must be 24 bytes`); + const n16 = nonce.subarray(0, 16); + if (isLE) + extendNonceFn(sigma, k32, u32(n16), k32); + else { + const sigmaRaw = swap32IfBE(Uint32Array.from(sigma)); + extendNonceFn(sigmaRaw, k32, u32(n16), k32); + clean(sigmaRaw); + swap32IfBE(k32); + } + nonce = nonce.subarray(16); + } + else if (!isLE) + swap32IfBE(k32); + // Handle nonce counter + const nonceNcLen = 16 - counterLength; + if (nonceNcLen !== nonce.length) + throw new Error(`arx: nonce must be ${nonceNcLen} or 16 bytes`); + // Normalize 64-bit-nonce layouts to the 12-byte core input: ChaCha/XChaCha prefix 4 zero + // counter bytes, while Salsa/XSalsa append them after the nonce words. + if (nonceNcLen !== 12) { + const nc = new Uint8Array(12); + nc.set(nonce, counterRight ? 0 : 12 - nonce.length); + nonce = nc; + toClean.push(nonce); + } + const n32 = swap32IfBE(u32(nonce)); + // Ensure temporary key/nonce copies are wiped even if the remaining + // runtime guard in runCipher(...) throws on counter overflow. + try { + runCipher(core, sigma, k32, n32, data, output, counter, rounds); + return output; + } + finally { + clean(...toClean); + } + }; +} +/** Internal class which wraps chacha20 or chacha8 to create CSPRNG. */ +export class _XorStreamPRG { + blockLen; + keyLen; + nonceLen; + state; + buf; + key; + nonce; + pos; + ctr; + cipher; + constructor(cipher, blockLen, keyLen, nonceLen, seed) { + this.cipher = cipher; + this.blockLen = blockLen; + this.keyLen = keyLen; + this.nonceLen = nonceLen; + this.state = new Uint8Array(this.keyLen + this.nonceLen); + this.reseed(seed); + this.ctr = 0; + this.pos = this.blockLen; + this.buf = new Uint8Array(this.blockLen); + // Keep a single key||nonce backing buffer so reseed/addEntropy/clean update the live cipher + // inputs in place through these subarray views. + this.key = this.state.subarray(0, this.keyLen); + this.nonce = this.state.subarray(this.keyLen); + } + reseed(seed) { + abytes(seed); + if (!seed || seed.length === 0) + throw new Error('entropy required'); + // Mix variable-length entropy cyclically across the whole key||nonce state, then restart the + // keystream so buffered leftovers from the previous state are never reused. + for (let i = 0; i < seed.length; i++) + this.state[i % this.state.length] ^= seed[i]; + this.ctr = 0; + this.pos = this.blockLen; + } + addEntropy(seed) { + // Reject empty entropy before re-keying, otherwise a throwing call would still advance state. + abytes(seed); + if (seed.length === 0) + throw new Error('entropy required'); + // Re-key from the current stream first, then mix external entropy into the fresh key||nonce + // state through reseed() so stale buffered bytes are discarded. + this.state.set(this.randomBytes(this.state.length)); + this.reseed(seed); + } + randomBytes(len) { + anumber(len); + if (len === 0) + return new Uint8Array(0); + const avail = this.pos < this.blockLen ? this.blockLen - this.pos : 0; + const blocks = Math.ceil(Math.max(0, len - avail) / this.blockLen); + // Preflight overflow so failed reads don't partially consume keystream + // and leave the PRG repeating blocks. + if (blocks > 0 && this.ctr > MAX_COUNTER - blocks) + throw new Error('arx: counter overflow'); + const out = new Uint8Array(len); + let outPos = 0; + // `out` starts zero-filled, and `buf.fill(0)` below does the same for leftovers: XOR-stream + // ciphers then emit raw keystream bytes directly into those buffers. + // Serve buffered leftovers first so split reads stay identical to one larger read. + if (this.pos < this.blockLen) { + const take = Math.min(len, this.blockLen - this.pos); + out.set(this.buf.subarray(this.pos, this.pos + take), 0); + this.pos += take; + outPos += take; + if (outPos === len) + return out; // fast path + } + // Full blocks directly to out + const full = Math.floor((len - outPos) / this.blockLen); + if (full > 0) { + const blockBytes = full * this.blockLen; + const b = out.subarray(outPos, outPos + blockBytes); + this.cipher(this.key, this.nonce, b, b, this.ctr); + this.ctr += full; + outPos += blockBytes; + } + // Save leftovers + const left = len - outPos; + if (left > 0) { + this.buf.fill(0); + // NOTE: cipher will handle overflow + this.cipher(this.key, this.nonce, this.buf, this.buf, this.ctr++); + out.set(this.buf.subarray(0, left), outPos); + this.pos = left; + } + return out; + } + // Clone seeds the new instance from this stream, so the source PRG advances too. + clone() { + return new _XorStreamPRG(this.cipher, this.blockLen, this.keyLen, this.nonceLen, this.randomBytes(this.state.length)); + } + // Zeroes the current state and leftover buffer, but does not make the instance unusable: + // Later reads first drain zeros from the cleared buffer and then continue + // from zero key||nonce state. + clean() { + this.pos = 0; + this.ctr = 0; + this.buf.fill(0); + this.state.fill(0); + } +} +/** + * Creates a PRG constructor from a stream cipher. + * @param cipher - Stream cipher used to fill output blocks. + * @param blockLen - Keystream block length in bytes. + * @param keyLen - Internal key length in bytes. + * @param nonceLen - Internal nonce length in bytes. + * @returns PRG factory for seeded concrete `_XorStreamPRG` instances. + * @example + * Builds a PRG from XChaCha20 and reads bytes from a randomly seeded instance. + * ```ts + * import { xchacha20 } from '@noble/ciphers/chacha.js'; + * import { createPRG } from '@noble/ciphers/_arx.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const seed = randomBytes(32); + * const init = createPRG(xchacha20, 64, 32, 24); + * const prg = init(seed); + * prg.randomBytes(8); + * ``` + */ +export const createPRG = (cipher, blockLen, keyLen, nonceLen) => { + return ((seed = randomBytes(32)) => new _XorStreamPRG(cipher, blockLen, keyLen, nonceLen, seed)); +}; +//# sourceMappingURL=_arx.js.map \ No newline at end of file diff --git a/node_modules/@noble/ciphers/_arx.js.map b/node_modules/@noble/ciphers/_arx.js.map new file mode 100644 index 0000000..ac5be2d --- /dev/null +++ b/node_modules/@noble/ciphers/_arx.js.map @@ -0,0 +1 @@ +{"version":3,"file":"_arx.js","sourceRoot":"","sources":["src/_arx.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@noble/ciphers/_poly1305.d.ts b/node_modules/@noble/ciphers/_poly1305.d.ts new file mode 100644 index 0000000..479a890 --- /dev/null +++ b/node_modules/@noble/ciphers/_poly1305.d.ts @@ -0,0 +1,73 @@ +/** + * Poly1305 ({@link https://cr.yp.to/mac/poly1305-20050329.pdf | PDF}, + * {@link https://en.wikipedia.org/wiki/Poly1305 | wiki}) + * is a fast and parallel secret-key message-authentication code suitable for + * a wide variety of applications. It was standardized in + * {@link https://www.rfc-editor.org/rfc/rfc8439 | RFC 8439} and is now used in TLS 1.3. + * + * Polynomial MACs are not perfect for every situation: + * they lack Random Key Robustness: the MAC can be forged, and can't be used in PAKE schemes. + * See {@link https://keymaterial.net/2020/09/07/invisible-salamanders-in-aes-gcm-siv/ | the invisible salamanders attack writeup}. + * To combat invisible salamanders, `hash(key)` can be included in ciphertext, + * however, this would violate ciphertext indistinguishability: + * an attacker would know which key was used - so `HKDF(key, i)` + * could be used instead. + * + * Check out the {@link https://cr.yp.to/mac.html | original website}. + * Based on public-domain {@link https://github.com/floodyberry/poly1305-donna | poly1305-donna}. + * @module + */ +import { type CMac, type IHash2, type TArg, type TRet } from './utils.ts'; +/** + * Incremental Poly1305 MAC state. + * Prefer `poly1305()` for one-shot use. + * @param key - 32-byte Poly1305 one-time key. + * @example + * Feeds one chunk into an incremental Poly1305 state with a fresh one-time key. + * + * ```ts + * import { Poly1305 } from '@noble/ciphers/_poly1305.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(32); + * const mac = new Poly1305(key); + * mac.update(new Uint8Array([1, 2, 3])); + * mac.digest(); + * ``` + */ +export declare class Poly1305 implements IHash2 { + readonly blockLen = 16; + readonly outputLen = 16; + private buffer; + private r; + private h; + private pad; + private pos; + protected finished: boolean; + protected destroyed: boolean; + constructor(key: TArg); + private process; + private finalize; + update(data: TArg): this; + destroy(): void; + digestInto(out: TArg): void; + digest(): TRet; +} +/** One-shot keyed hash helper with `.create()`. */ +export type CHash = CMac; +/** + * Poly1305 MAC from RFC 8439. + * @param msg - Message bytes to authenticate. + * @param key - 32-byte Poly1305 one-time key. + * @returns 16-byte authentication tag. + * @example + * Authenticates one message with a one-shot Poly1305 call and a fresh key. + * + * ```ts + * import { poly1305 } from '@noble/ciphers/_poly1305.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(32); + * poly1305(new Uint8Array(), key); + * ``` + */ +export declare const poly1305: TRet; +//# sourceMappingURL=_poly1305.d.ts.map \ No newline at end of file diff --git a/node_modules/@noble/ciphers/_poly1305.d.ts.map b/node_modules/@noble/ciphers/_poly1305.d.ts.map new file mode 100644 index 0000000..bd03e62 --- /dev/null +++ b/node_modules/@noble/ciphers/_poly1305.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"_poly1305.d.ts","sourceRoot":"","sources":["src/_poly1305.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAGe,KAAK,IAAI,EAAE,KAAK,MAAM,EAAE,KAAK,IAAI,EAAE,KAAK,IAAI,EACjE,MAAM,YAAY,CAAC;AA2DpB;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,QAAS,YAAW,MAAM;IACrC,QAAQ,CAAC,QAAQ,MAAM;IACvB,QAAQ,CAAC,SAAS,MAAM;IACxB,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,CAAC,CAAuB;IAChC,OAAO,CAAC,CAAC,CAAuB;IAChC,OAAO,CAAC,GAAG,CAAsB;IACjC,OAAO,CAAC,GAAG,CAAK;IAChB,SAAS,CAAC,QAAQ,UAAS;IAC3B,SAAS,CAAC,SAAS,UAAS;gBAGhB,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC;IA4BjC,OAAO,CAAC,OAAO;IA+Hf,OAAO,CAAC,QAAQ;IAmDhB,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,GAAG,IAAI;IAwBpC,OAAO,IAAI,IAAI;IAKf,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,GAAG,IAAI;IAqBvC,MAAM,IAAI,IAAI,CAAC,UAAU,CAAC;CAQ3B;AAED,mDAAmD;AACnD,MAAM,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;AAEnC;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,QAAQ,EAAE,IAAI,CAAC,KAAK,CAGhC,CAAC"} \ No newline at end of file diff --git a/node_modules/@noble/ciphers/_poly1305.js b/node_modules/@noble/ciphers/_poly1305.js new file mode 100644 index 0000000..deff7b0 --- /dev/null +++ b/node_modules/@noble/ciphers/_poly1305.js @@ -0,0 +1,364 @@ +/** + * Poly1305 ({@link https://cr.yp.to/mac/poly1305-20050329.pdf | PDF}, + * {@link https://en.wikipedia.org/wiki/Poly1305 | wiki}) + * is a fast and parallel secret-key message-authentication code suitable for + * a wide variety of applications. It was standardized in + * {@link https://www.rfc-editor.org/rfc/rfc8439 | RFC 8439} and is now used in TLS 1.3. + * + * Polynomial MACs are not perfect for every situation: + * they lack Random Key Robustness: the MAC can be forged, and can't be used in PAKE schemes. + * See {@link https://keymaterial.net/2020/09/07/invisible-salamanders-in-aes-gcm-siv/ | the invisible salamanders attack writeup}. + * To combat invisible salamanders, `hash(key)` can be included in ciphertext, + * however, this would violate ciphertext indistinguishability: + * an attacker would know which key was used - so `HKDF(key, i)` + * could be used instead. + * + * Check out the {@link https://cr.yp.to/mac.html | original website}. + * Based on public-domain {@link https://github.com/floodyberry/poly1305-donna | poly1305-donna}. + * @module + */ +// prettier-ignore +import { abytes, aexists, aoutput, bytesToHex, clean, concatBytes, copyBytes, hexToNumber, numberToBytesBE, wrapMacConstructor } from "./utils.js"; +// Little-endian 2-byte load used by the Poly1305 limb decomposition. +function u8to16(a, i) { + return (a[i++] & 0xff) | ((a[i++] & 0xff) << 8); +} +function bytesToNumberLE(bytes) { + return hexToNumber(bytesToHex(Uint8Array.from(bytes).reverse())); +} +/** Small version of `poly1305` without loop unrolling. Unused, provided for auditability. */ +function poly1305_small(msg, key) { + abytes(msg); + abytes(key, 32, 'key'); + const POW_2_130_5 = BigInt(2) ** BigInt(130) - BigInt(5); // 2^130-5 + const POW_2_128_1 = BigInt(2) ** BigInt(128) - BigInt(1); // 2^128-1 + const CLAMP_R = BigInt('0x0ffffffc0ffffffc0ffffffc0fffffff'); + const r = bytesToNumberLE(key.subarray(0, 16)) & CLAMP_R; + const s = bytesToNumberLE(key.subarray(16)); + // Process by 16 byte chunks + let acc = BigInt(0); + for (let i = 0; i < msg.length; i += 16) { + const m = msg.subarray(i, i + 16); + // RFC 8439 §2.5.1 / RFC 7539 §2.5.1 append [0x01] to each chunk before multiplying by r. + const n = bytesToNumberLE(m) | (BigInt(1) << BigInt(8 * m.length)); + acc = ((acc + n) * r) % POW_2_130_5; + } + const res = (acc + s) & POW_2_128_1; + // RFC 8439 §2.5 / RFC 7539 §2.5 serialize the low 128 bits in little-endian order. + return numberToBytesBE(res, 16).reverse(); // LE +} +// Can be used to replace `computeTag` in chacha.ts. Unused, provided for auditability. +// @ts-expect-error +function poly1305_computeTag_small(authKey, +// AEAD trailer must already be the 16-byte length block: +// 8-byte little-endian AAD length || 8-byte little-endian ciphertext length. +lengths, ciphertext, AAD) { + // RFC 8439 §2.8.1 / RFC 7539 §2.8.1 MAC input is + // AAD || pad16(AAD) || ciphertext || pad16(ciphertext) || lengths. + const res = []; + const updatePadded2 = (msg) => { + res.push(msg); + const leftover = msg.length % 16; + // RFC 8439 §2.8.1 / RFC 7539 §2.8.1: pad16(x) is empty for aligned + // inputs, else 16-(len%16) zero bytes. + if (leftover) + res.push(new Uint8Array(16).slice(leftover)); + }; + if (AAD) + updatePadded2(AAD); + updatePadded2(ciphertext); + res.push(lengths); + return poly1305_small(concatBytes(...res), authKey); +} +/** + * Incremental Poly1305 MAC state. + * Prefer `poly1305()` for one-shot use. + * @param key - 32-byte Poly1305 one-time key. + * @example + * Feeds one chunk into an incremental Poly1305 state with a fresh one-time key. + * + * ```ts + * import { Poly1305 } from '@noble/ciphers/_poly1305.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(32); + * const mac = new Poly1305(key); + * mac.update(new Uint8Array([1, 2, 3])); + * mac.digest(); + * ``` + */ +export class Poly1305 { + blockLen = 16; + outputLen = 16; + buffer = new Uint8Array(16); + r = new Uint16Array(10); // Allocating 1 array with .subarray() here is slower than 3 + h = new Uint16Array(10); + pad = new Uint16Array(8); + pos = 0; + finished = false; + destroyed = false; + // Can be speed-up using BigUint64Array, at the cost of complexity + constructor(key) { + key = copyBytes(abytes(key, 32, 'key')); + const t0 = u8to16(key, 0); + const t1 = u8to16(key, 2); + const t2 = u8to16(key, 4); + const t3 = u8to16(key, 6); + const t4 = u8to16(key, 8); + const t5 = u8to16(key, 10); + const t6 = u8to16(key, 12); + const t7 = u8to16(key, 14); + // RFC 8439 §2.5.1 / RFC 7539 §2.5.1 clamp r before multiplication. + // These masks unpack that clamped value into 13-bit limbs, while pad + // keeps the raw s half for finalize(). + // {@link https://github.com/floodyberry/poly1305-donna/blob/e6ad6e091d30d7f4ec2d4f978be1fcfcbce72781/poly1305-donna-16.h#L47 | poly1305-donna reference} + this.r[0] = t0 & 0x1fff; + this.r[1] = ((t0 >>> 13) | (t1 << 3)) & 0x1fff; + this.r[2] = ((t1 >>> 10) | (t2 << 6)) & 0x1f03; + this.r[3] = ((t2 >>> 7) | (t3 << 9)) & 0x1fff; + this.r[4] = ((t3 >>> 4) | (t4 << 12)) & 0x00ff; + this.r[5] = (t4 >>> 1) & 0x1ffe; + this.r[6] = ((t4 >>> 14) | (t5 << 2)) & 0x1fff; + this.r[7] = ((t5 >>> 11) | (t6 << 5)) & 0x1f81; + this.r[8] = ((t6 >>> 8) | (t7 << 8)) & 0x1fff; + this.r[9] = (t7 >>> 5) & 0x007f; + for (let i = 0; i < 8; i++) + this.pad[i] = u8to16(key, 16 + 2 * i); + } + process(data, offset, isLast = false) { + // RFC 8439 §2.5 / §2.5.1 and RFC 7539 §2.5 / §2.5.1 add an extra high + // bit to every full 16-byte block. The final partial block gets its + // explicit `1` byte during digestInto(), so `hibit` stays zero there. + const hibit = isLast ? 0 : 1 << 11; + const { h, r } = this; + const r0 = r[0]; + const r1 = r[1]; + const r2 = r[2]; + const r3 = r[3]; + const r4 = r[4]; + const r5 = r[5]; + const r6 = r[6]; + const r7 = r[7]; + const r8 = r[8]; + const r9 = r[9]; + const t0 = u8to16(data, offset + 0); + const t1 = u8to16(data, offset + 2); + const t2 = u8to16(data, offset + 4); + const t3 = u8to16(data, offset + 6); + const t4 = u8to16(data, offset + 8); + const t5 = u8to16(data, offset + 10); + const t6 = u8to16(data, offset + 12); + const t7 = u8to16(data, offset + 14); + let h0 = h[0] + (t0 & 0x1fff); + let h1 = h[1] + (((t0 >>> 13) | (t1 << 3)) & 0x1fff); + let h2 = h[2] + (((t1 >>> 10) | (t2 << 6)) & 0x1fff); + let h3 = h[3] + (((t2 >>> 7) | (t3 << 9)) & 0x1fff); + let h4 = h[4] + (((t3 >>> 4) | (t4 << 12)) & 0x1fff); + let h5 = h[5] + ((t4 >>> 1) & 0x1fff); + let h6 = h[6] + (((t4 >>> 14) | (t5 << 2)) & 0x1fff); + let h7 = h[7] + (((t5 >>> 11) | (t6 << 5)) & 0x1fff); + let h8 = h[8] + (((t6 >>> 8) | (t7 << 8)) & 0x1fff); + let h9 = h[9] + ((t7 >>> 5) | hibit); + let c = 0; + let d0 = c + h0 * r0 + h1 * (5 * r9) + h2 * (5 * r8) + h3 * (5 * r7) + h4 * (5 * r6); + c = d0 >>> 13; + d0 &= 0x1fff; + d0 += h5 * (5 * r5) + h6 * (5 * r4) + h7 * (5 * r3) + h8 * (5 * r2) + h9 * (5 * r1); + c += d0 >>> 13; + d0 &= 0x1fff; + let d1 = c + h0 * r1 + h1 * r0 + h2 * (5 * r9) + h3 * (5 * r8) + h4 * (5 * r7); + c = d1 >>> 13; + d1 &= 0x1fff; + d1 += h5 * (5 * r6) + h6 * (5 * r5) + h7 * (5 * r4) + h8 * (5 * r3) + h9 * (5 * r2); + c += d1 >>> 13; + d1 &= 0x1fff; + let d2 = c + h0 * r2 + h1 * r1 + h2 * r0 + h3 * (5 * r9) + h4 * (5 * r8); + c = d2 >>> 13; + d2 &= 0x1fff; + d2 += h5 * (5 * r7) + h6 * (5 * r6) + h7 * (5 * r5) + h8 * (5 * r4) + h9 * (5 * r3); + c += d2 >>> 13; + d2 &= 0x1fff; + let d3 = c + h0 * r3 + h1 * r2 + h2 * r1 + h3 * r0 + h4 * (5 * r9); + c = d3 >>> 13; + d3 &= 0x1fff; + d3 += h5 * (5 * r8) + h6 * (5 * r7) + h7 * (5 * r6) + h8 * (5 * r5) + h9 * (5 * r4); + c += d3 >>> 13; + d3 &= 0x1fff; + let d4 = c + h0 * r4 + h1 * r3 + h2 * r2 + h3 * r1 + h4 * r0; + c = d4 >>> 13; + d4 &= 0x1fff; + d4 += h5 * (5 * r9) + h6 * (5 * r8) + h7 * (5 * r7) + h8 * (5 * r6) + h9 * (5 * r5); + c += d4 >>> 13; + d4 &= 0x1fff; + let d5 = c + h0 * r5 + h1 * r4 + h2 * r3 + h3 * r2 + h4 * r1; + c = d5 >>> 13; + d5 &= 0x1fff; + d5 += h5 * r0 + h6 * (5 * r9) + h7 * (5 * r8) + h8 * (5 * r7) + h9 * (5 * r6); + c += d5 >>> 13; + d5 &= 0x1fff; + let d6 = c + h0 * r6 + h1 * r5 + h2 * r4 + h3 * r3 + h4 * r2; + c = d6 >>> 13; + d6 &= 0x1fff; + d6 += h5 * r1 + h6 * r0 + h7 * (5 * r9) + h8 * (5 * r8) + h9 * (5 * r7); + c += d6 >>> 13; + d6 &= 0x1fff; + let d7 = c + h0 * r7 + h1 * r6 + h2 * r5 + h3 * r4 + h4 * r3; + c = d7 >>> 13; + d7 &= 0x1fff; + d7 += h5 * r2 + h6 * r1 + h7 * r0 + h8 * (5 * r9) + h9 * (5 * r8); + c += d7 >>> 13; + d7 &= 0x1fff; + let d8 = c + h0 * r8 + h1 * r7 + h2 * r6 + h3 * r5 + h4 * r4; + c = d8 >>> 13; + d8 &= 0x1fff; + d8 += h5 * r3 + h6 * r2 + h7 * r1 + h8 * r0 + h9 * (5 * r9); + c += d8 >>> 13; + d8 &= 0x1fff; + let d9 = c + h0 * r9 + h1 * r8 + h2 * r7 + h3 * r6 + h4 * r5; + c = d9 >>> 13; + d9 &= 0x1fff; + d9 += h5 * r4 + h6 * r3 + h7 * r2 + h8 * r1 + h9 * r0; + c += d9 >>> 13; + d9 &= 0x1fff; + c = ((c << 2) + c) | 0; + c = (c + d0) | 0; + d0 = c & 0x1fff; + c = c >>> 13; + d1 += c; + h[0] = d0; + h[1] = d1; + h[2] = d2; + h[3] = d3; + h[4] = d4; + h[5] = d5; + h[6] = d6; + h[7] = d7; + h[8] = d8; + h[9] = d9; + } + finalize() { + const { h, pad } = this; + const g = new Uint16Array(10); + let c = h[1] >>> 13; + h[1] &= 0x1fff; + for (let i = 2; i < 10; i++) { + h[i] += c; + c = h[i] >>> 13; + h[i] &= 0x1fff; + } + h[0] += c * 5; + c = h[0] >>> 13; + h[0] &= 0x1fff; + h[1] += c; + c = h[1] >>> 13; + h[1] &= 0x1fff; + h[2] += c; + // RFC 8439 §2.5 / RFC 7539 §2.5 reduce modulo 2^130-5 before repacking + // to 16-bit words and adding the raw s half. + g[0] = h[0] + 5; + c = g[0] >>> 13; + g[0] &= 0x1fff; + for (let i = 1; i < 10; i++) { + g[i] = h[i] + c; + c = g[i] >>> 13; + g[i] &= 0x1fff; + } + g[9] -= 1 << 13; + let mask = (c ^ 1) - 1; + for (let i = 0; i < 10; i++) + g[i] &= mask; + mask = ~mask; + for (let i = 0; i < 10; i++) + h[i] = (h[i] & mask) | g[i]; + h[0] = (h[0] | (h[1] << 13)) & 0xffff; + h[1] = ((h[1] >>> 3) | (h[2] << 10)) & 0xffff; + h[2] = ((h[2] >>> 6) | (h[3] << 7)) & 0xffff; + h[3] = ((h[3] >>> 9) | (h[4] << 4)) & 0xffff; + h[4] = ((h[4] >>> 12) | (h[5] << 1) | (h[6] << 14)) & 0xffff; + h[5] = ((h[6] >>> 2) | (h[7] << 11)) & 0xffff; + h[6] = ((h[7] >>> 5) | (h[8] << 8)) & 0xffff; + h[7] = ((h[8] >>> 8) | (h[9] << 5)) & 0xffff; + let f = h[0] + pad[0]; + h[0] = f & 0xffff; + for (let i = 1; i < 8; i++) { + f = (((h[i] + pad[i]) | 0) + (f >>> 16)) | 0; + h[i] = f & 0xffff; + } + clean(g); + } + update(data) { + aexists(this); + abytes(data); + data = copyBytes(data); + const { buffer, blockLen } = this; + const len = data.length; + for (let pos = 0; pos < len;) { + const take = Math.min(blockLen - this.pos, len - pos); + // Fast path: we have at least one block in input + if (take === blockLen) { + for (; blockLen <= len - pos; pos += blockLen) + this.process(data, pos); + continue; + } + buffer.set(data.subarray(pos, pos + take), this.pos); + this.pos += take; + pos += take; + if (this.pos === blockLen) { + this.process(buffer, 0, false); + this.pos = 0; + } + } + return this; + } + destroy() { + // `aexists(this)` guards update/digest paths, so destroy must mark the instance unusable too. + this.destroyed = true; + clean(this.h, this.r, this.buffer, this.pad); + } + digestInto(out) { + aexists(this); + aoutput(out, this); + this.finished = true; + const { buffer, h } = this; + let { pos } = this; + if (pos) { + // RFC 8439 §2.5 / RFC 7539 §2.5: the final short block appends a + // single `0x01` byte and zero-fills the remaining bytes before the + // last multiplication step. + buffer[pos++] = 1; + for (; pos < 16; pos++) + buffer[pos] = 0; + this.process(buffer, 0, true); + } + this.finalize(); + let opos = 0; + for (let i = 0; i < 8; i++) { + out[opos++] = h[i] >>> 0; + out[opos++] = h[i] >>> 8; + } + } + digest() { + const { buffer, outputLen } = this; + this.digestInto(buffer); + // Copy out before destroy() zeroes the internal buffer. + const res = buffer.slice(0, outputLen); + this.destroy(); + return res; + } +} +/** + * Poly1305 MAC from RFC 8439. + * @param msg - Message bytes to authenticate. + * @param key - 32-byte Poly1305 one-time key. + * @returns 16-byte authentication tag. + * @example + * Authenticates one message with a one-shot Poly1305 call and a fresh key. + * + * ```ts + * import { poly1305 } from '@noble/ciphers/_poly1305.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(32); + * poly1305(new Uint8Array(), key); + * ``` + */ +export const poly1305 = /* @__PURE__ */ wrapMacConstructor(32, (key) => new Poly1305(key)); +//# sourceMappingURL=_poly1305.js.map \ No newline at end of file diff --git a/node_modules/@noble/ciphers/_poly1305.js.map b/node_modules/@noble/ciphers/_poly1305.js.map new file mode 100644 index 0000000..d6f4f2f --- /dev/null +++ b/node_modules/@noble/ciphers/_poly1305.js.map @@ -0,0 +1 @@ +{"version":3,"file":"_poly1305.js","sourceRoot":"","sources":["src/_poly1305.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@noble/ciphers/_polyval.d.ts b/node_modules/@noble/ciphers/_polyval.d.ts new file mode 100644 index 0000000..ba5f5fb --- /dev/null +++ b/node_modules/@noble/ciphers/_polyval.d.ts @@ -0,0 +1,121 @@ +/** + * GHash from AES-GCM and its little-endian "mirror image" Polyval from AES-SIV. + * + * Implemented in terms of GHash with conversion function for keys + * GCM GHASH from + * {@link https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf | NIST SP800-38d}, + * SIV from + * {@link https://www.rfc-editor.org/rfc/rfc8452 | RFC 8452}. + * + * GHASH modulo: x^128 + x^7 + x^2 + x + 1 + * POLYVAL modulo: x^128 + x^127 + x^126 + x^121 + 1 + * + * @module + */ +import { type CMac, type IHash2, type TArg, type TRet } from './utils.ts'; +/** + * `mulX_GHASH(ByteReverse(H))` from RFC 8452 Appendix A. + * @param k mutated in place + */ +export declare function _toGHASHKey(k: TArg): TRet; +type Value = { + s0: number; + s1: number; + s2: number; + s3: number; +}; +/** + * Incremental GHASH state for AES-GCM. + * @param key - 16-byte GHASH key. + * @param expectedLength - Expected message length for table sizing. + * Chunking is segment-based, not hash-streaming: every `update()` call is zero-padded + * to the next 16-byte boundary before it is absorbed. This matches the internal AES/GCM + * use where AAD, payload, and length block are separate padded segments. + * @example + * Feeds one ciphertext block into an incremental GHASH state with a fresh hash key. + * + * ```ts + * import { GHASH } from '@noble/ciphers/_polyval.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(16); + * const mac = new GHASH(key); + * mac.update(new Uint8Array(16)); + * mac.digest(); + * ``` + */ +export declare class GHASH implements IHash2 { + readonly blockLen: number; + readonly outputLen: number; + protected s0: number; + protected s1: number; + protected s2: number; + protected s3: number; + protected finished: boolean; + protected destroyed: boolean; + protected t: Value[]; + private W; + private windowSize; + constructor(key: TArg, expectedLength?: number); + protected _updateBlock(s0: number, s1: number, s2: number, s3: number): void; + update(data: TArg): this; + destroy(): void; + digestInto(out: TArg): void; + digest(): TRet; +} +/** + * Incremental POLYVAL state for AES-SIV. + * @param key - 16-byte POLYVAL key. + * @param expectedLength - Expected message length for table sizing. + * Inherits GHASH's segment-padded `update()` behavior: each call is padded + * independently to a 16-byte boundary before absorption. + * @example + * Feeds one block into an incremental POLYVAL state with a fresh hash key. + * + * ```ts + * import { Polyval } from '@noble/ciphers/_polyval.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(16); + * const mac = new Polyval(key); + * mac.update(new Uint8Array(16)); + * mac.digest(); + * ``` + */ +export declare class Polyval extends GHASH { + constructor(key: TArg, expectedLength?: number); + update(data: TArg): this; + digestInto(out: TArg): void; +} +/** + * GHash MAC for AES-GCM. + * @param msg - Message bytes to authenticate. + * @param key - 16-byte GHASH key. + * @returns 16-byte authentication tag. + * @example + * Authenticates a short message with GHASH and a fresh hash key. + * + * ```ts + * import { ghash } from '@noble/ciphers/_polyval.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(16); + * ghash(new Uint8Array(), key); + * ``` + */ +export declare const ghash: TRet>; +/** + * POLYVAL MAC for AES-SIV. + * @param msg - Message bytes to authenticate. + * @param key - 16-byte POLYVAL key. + * @returns 16-byte authentication tag. + * @example + * Authenticates a short message with POLYVAL and a fresh hash key. + * + * ```ts + * import { polyval } from '@noble/ciphers/_polyval.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(16); + * polyval(new Uint8Array(), key); + * ``` + */ +export declare const polyval: TRet>; +export {}; +//# sourceMappingURL=_polyval.d.ts.map \ No newline at end of file diff --git a/node_modules/@noble/ciphers/_polyval.d.ts.map b/node_modules/@noble/ciphers/_polyval.d.ts.map new file mode 100644 index 0000000..ac3f9c6 --- /dev/null +++ b/node_modules/@noble/ciphers/_polyval.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"_polyval.d.ts","sourceRoot":"","sources":["src/_polyval.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAWL,KAAK,IAAI,EACT,KAAK,MAAM,EACX,KAAK,IAAI,EACT,KAAK,IAAI,EACV,MAAM,YAAY,CAAC;AAuCpB;;;GAGG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,CAcjE;AAED,KAAK,KAAK,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAUhE;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,KAAM,YAAW,MAAM;IAClC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAc;IACvC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAc;IACxC,SAAS,CAAC,EAAE,SAAK;IACjB,SAAS,CAAC,EAAE,SAAK;IACjB,SAAS,CAAC,EAAE,SAAK;IACjB,SAAS,CAAC,EAAE,SAAK;IACjB,SAAS,CAAC,QAAQ,UAAS;IAC3B,SAAS,CAAC,SAAS,UAAS;IAC5B,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;IACrB,OAAO,CAAC,CAAC,CAAS;IAClB,OAAO,CAAC,UAAU,CAAS;gBAEf,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,EAAE,cAAc,CAAC,EAAE,MAAM;IAuC1D,SAAS,CAAC,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI;IA0B5E,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,GAAG,IAAI;IA6BpC,OAAO,IAAI,IAAI;IAWf,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,GAAG,IAAI;IAiBvC,MAAM,IAAI,IAAI,CAAC,UAAU,CAAC;CAO3B;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,OAAQ,SAAQ,KAAK;gBACpB,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,EAAE,cAAc,CAAC,EAAE,MAAM;IAS1D,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,GAAG,IAAI;IA6BpC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,GAAG,IAAI;CAkBxC;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC,CAAC,CAK5D,CAAC;AAEJ;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC,CAAC,CAKhE,CAAC"} \ No newline at end of file diff --git a/node_modules/@noble/ciphers/_polyval.js b/node_modules/@noble/ciphers/_polyval.js new file mode 100644 index 0000000..38db8e4 --- /dev/null +++ b/node_modules/@noble/ciphers/_polyval.js @@ -0,0 +1,330 @@ +/** + * GHash from AES-GCM and its little-endian "mirror image" Polyval from AES-SIV. + * + * Implemented in terms of GHash with conversion function for keys + * GCM GHASH from + * {@link https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf | NIST SP800-38d}, + * SIV from + * {@link https://www.rfc-editor.org/rfc/rfc8452 | RFC 8452}. + * + * GHASH modulo: x^128 + x^7 + x^2 + x + 1 + * POLYVAL modulo: x^128 + x^127 + x^126 + x^121 + 1 + * + * @module + */ +import { abytes, aexists, aoutput, clean, copyBytes, createView, swap32IfBE, swap8IfBE, u32, wrapMacConstructor, } from "./utils.js"; +const BLOCK_SIZE = 16; +// TODO: rewrite +// temporary padding buffer +// ZEROS32 aliases these bytes, so clean(ZEROS32) also resets this shared tail-padding scratch. +const ZEROS16 = /* @__PURE__ */ new Uint8Array(16); +const ZEROS32 = /* @__PURE__ */ u32(ZEROS16); +// GHASH reduces modulo x^128 + x^7 + x^2 + x + 1, so the low-degree terms +// x^7 + x^2 + x + 1 become bits `11100001` = 0xe1 in R = 0xe1 || 0^120. +const POLY = 0xe1; +// v = 2*v % POLY +// NOTE: because x + x = 0 (add/sub is same), mul2(x) != x+x +// Montgomery ladder can multiply any field element with this doubling step; +// addition stays simple xor. +const mul2 = (s0, s1, s2, s3) => { + const hiBit = s3 & 1; + return { + s3: (s2 << 31) | (s3 >>> 1), + s2: (s1 << 31) | (s2 >>> 1), + s1: (s0 << 31) | (s1 >>> 1), + // NIST SP 800-38D §6.3 applies `V >> 1` and XORs R on carry. In this + // 4x32-bit split, R = 0xe1 || 0^120 lives in the top byte of s0. + s0: (s0 >>> 1) ^ ((POLY << 24) & -(hiBit & 1)), // reduce % poly + }; +}; +// Per-word part of RFC 8452 `ByteReverse`; callers also reverse the 32-bit word order. +const swapLE = (n) => (((n >>> 0) & 0xff) << 24) | + (((n >>> 8) & 0xff) << 16) | + (((n >>> 16) & 0xff) << 8) | + ((n >>> 24) & 0xff) | + 0; +// POLYVAL first applies RFC 8452's per-word byte reversal, then re-normalizes +// host-endian u32 loads to the little-endian word value `_updateBlock()` expects. +const swap8IfLE = (n) => swap8IfBE(swapLE(n)); +/** + * `mulX_GHASH(ByteReverse(H))` from RFC 8452 Appendix A. + * @param k mutated in place + */ +export function _toGHASHKey(k) { + // The input is the original POLYVAL key H; reverse() materializes + // RFC 8452's `ByteReverse(H)` before the GHASH mulX step. + k.reverse(); + const hiBit = k[15] & 1; + // k >>= 1 + let carry = 0; + for (let i = 0; i < k.length; i++) { + const t = k[i]; + k[i] = (t >>> 1) | carry; + carry = (t & 1) << 7; + } + k[0] ^= -hiBit & 0xe1; // if (hiBit) n ^= 0xe1000000000000000000000000000000; + return k; +} +// Precompute-window heuristic only: larger inputs trade memory for fewer table lookups. +// Any caller-provided length hint still collapses to one of the supported windows {2, 4, 8}. +const estimateWindow = (bytes) => { + if (bytes > 64 * 1024) + return 8; + if (bytes > 1024) + return 4; + return 2; +}; +/** + * Incremental GHASH state for AES-GCM. + * @param key - 16-byte GHASH key. + * @param expectedLength - Expected message length for table sizing. + * Chunking is segment-based, not hash-streaming: every `update()` call is zero-padded + * to the next 16-byte boundary before it is absorbed. This matches the internal AES/GCM + * use where AAD, payload, and length block are separate padded segments. + * @example + * Feeds one ciphertext block into an incremental GHASH state with a fresh hash key. + * + * ```ts + * import { GHASH } from '@noble/ciphers/_polyval.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(16); + * const mac = new GHASH(key); + * mac.update(new Uint8Array(16)); + * mac.digest(); + * ``` + */ +export class GHASH { + blockLen = BLOCK_SIZE; + outputLen = BLOCK_SIZE; + s0 = 0; + s1 = 0; + s2 = 0; + s3 = 0; + finished = false; + destroyed = false; + t; + W; + windowSize; + // We select bits per window adaptively based on expectedLength + constructor(key, expectedLength) { + abytes(key, 16, 'key'); + key = copyBytes(key); + const kView = createView(key); + let k0 = kView.getUint32(0, false); + let k1 = kView.getUint32(4, false); + let k2 = kView.getUint32(8, false); + let k3 = kView.getUint32(12, false); + // generate table of doubled keys (half of montgomery ladder) + const doubles = []; + for (let i = 0; i < 128; i++) { + doubles.push({ s0: swapLE(k0), s1: swapLE(k1), s2: swapLE(k2), s3: swapLE(k3) }); + ({ s0: k0, s1: k1, s2: k2, s3: k3 } = mul2(k0, k1, k2, k3)); + } + const W = estimateWindow(expectedLength || 1024); + if (![1, 2, 4, 8].includes(W)) + throw new Error('ghash: invalid window size, expected 2, 4 or 8'); + this.W = W; + const bits = 128; // always 128 bits; + const windows = bits / W; + const windowSize = (this.windowSize = 2 ** W); + const items = []; + // Create precompute table for window of W bits + for (let w = 0; w < windows; w++) { + // truth table: 00, 01, 10, 11 + for (let byte = 0; byte < windowSize; byte++) { + // prettier-ignore + let s0 = 0, s1 = 0, s2 = 0, s3 = 0; + for (let j = 0; j < W; j++) { + const bit = (byte >>> (W - j - 1)) & 1; + if (!bit) + continue; + const { s0: d0, s1: d1, s2: d2, s3: d3 } = doubles[W * w + j]; + ((s0 ^= d0), (s1 ^= d1), (s2 ^= d2), (s3 ^= d3)); + } + items.push({ s0, s1, s2, s3 }); + } + } + this.t = items; + } + _updateBlock(s0, s1, s2, s3) { + ((s0 ^= this.s0), (s1 ^= this.s1), (s2 ^= this.s2), (s3 ^= this.s3)); + const { W, t, windowSize } = this; + // prettier-ignore + let o0 = 0, o1 = 0, o2 = 0, o3 = 0; + const mask = (1 << W) - 1; // 2**W will kill performance. + let w = 0; + // NIST SP 800-38D §6.3 interprets blocks as little-endian polynomials, + // so the lookup walk consumes each word byte-by-byte from + // least-significant to most-significant bits. + for (const num of [s0, s1, s2, s3]) { + for (let bytePos = 0; bytePos < 4; bytePos++) { + const byte = (num >>> (8 * bytePos)) & 0xff; + for (let bitPos = 8 / W - 1; bitPos >= 0; bitPos--) { + const bit = (byte >>> (W * bitPos)) & mask; + const { s0: e0, s1: e1, s2: e2, s3: e3 } = t[w * windowSize + bit]; + ((o0 ^= e0), (o1 ^= e1), (o2 ^= e2), (o3 ^= e3)); + w += 1; + } + } + } + this.s0 = o0; + this.s1 = o1; + this.s2 = o2; + this.s3 = o3; + } + update(data) { + aexists(this); + abytes(data); + data = copyBytes(data); + const b32 = u32(data); + const blocks = Math.floor(data.length / BLOCK_SIZE); + const left = data.length % BLOCK_SIZE; + for (let i = 0; i < blocks; i++) { + this._updateBlock(swap8IfBE(b32[i * 4 + 0]), swap8IfBE(b32[i * 4 + 1]), swap8IfBE(b32[i * 4 + 2]), swap8IfBE(b32[i * 4 + 3])); + } + if (left) { + ZEROS16.set(data.subarray(blocks * BLOCK_SIZE)); + // Tail blocks go through the shared ZEROS32 scratch, so they need the same host-endian + // normalization as full blocks; otherwise segmented GHASH/POLYVAL updates diverge on BE. + this._updateBlock(swap8IfBE(ZEROS32[0]), swap8IfBE(ZEROS32[1]), swap8IfBE(ZEROS32[2]), swap8IfBE(ZEROS32[3])); + clean(ZEROS32); // clean tmp buffer + } + return this; + } + destroy() { + // `aexists(this)` guards update/digest paths, so destroy must mark the instance unusable too. + this.destroyed = true; + const { t } = this; + // Wipe the key-derived precompute table; scalar accumulator words remain, + // but the destroyed guard blocks further use. + // clean precompute table + for (const elm of t) { + ((elm.s0 = 0), (elm.s1 = 0), (elm.s2 = 0), (elm.s3 = 0)); + } + } + digestInto(out) { + aexists(this); + // `digestInto(out)` is the no-allocation fast path, so callers must pass a + // 32-bit-aligned buffer before we reinterpret it with `u32(out)`. + aoutput(out, this, true); + this.finished = true; + // NIST SP 800-38D §6.4 returns the final 128-bit block Y_m. + // `digestInto()` follows the relaxed `aoutput()` contract, so only + // out[0..15] may be touched. + const { s0, s1, s2, s3 } = this; + const o32 = u32(out); + o32[0] = s0; + o32[1] = s1; + o32[2] = s2; + o32[3] = s3; + swap32IfBE(o32); + } + digest() { + const res = new Uint8Array(BLOCK_SIZE); + this.digestInto(res); + // `res` is independent of internal state, so it stays valid after destroy() wipes the table. + this.destroy(); + return res; + } +} +/** + * Incremental POLYVAL state for AES-SIV. + * @param key - 16-byte POLYVAL key. + * @param expectedLength - Expected message length for table sizing. + * Inherits GHASH's segment-padded `update()` behavior: each call is padded + * independently to a 16-byte boundary before absorption. + * @example + * Feeds one block into an incremental POLYVAL state with a fresh hash key. + * + * ```ts + * import { Polyval } from '@noble/ciphers/_polyval.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(16); + * const mac = new Polyval(key); + * mac.update(new Uint8Array(16)); + * mac.digest(); + * ``` + */ +export class Polyval extends GHASH { + constructor(key, expectedLength) { + abytes(key); + // RFC 8452 Appendix A converts the POLYVAL key with + // `mulX_GHASH(ByteReverse(H))`; copy first because `_toGHASHKey(...)` + // mutates in place. + const ghKey = _toGHASHKey(copyBytes(key)); + super(ghKey, expectedLength); + clean(ghKey); + } + update(data) { + aexists(this); + abytes(data); + data = copyBytes(data); + const b32 = u32(data); + const left = data.length % BLOCK_SIZE; + const blocks = Math.floor(data.length / BLOCK_SIZE); + for (let i = 0; i < blocks; i++) { + // RFC 8452 Appendix A feeds `ByteReverse(X_i)` into GHASH, so POLYVAL + // reverses the 32-bit word order in addition to the per-word byte swap. + this._updateBlock(swap8IfLE(b32[i * 4 + 3]), swap8IfLE(b32[i * 4 + 2]), swap8IfLE(b32[i * 4 + 1]), swap8IfLE(b32[i * 4 + 0])); + } + if (left) { + ZEROS16.set(data.subarray(blocks * BLOCK_SIZE)); + this._updateBlock(swap8IfLE(ZEROS32[3]), swap8IfLE(ZEROS32[2]), swap8IfLE(ZEROS32[1]), swap8IfLE(ZEROS32[0])); + clean(ZEROS32); + } + return this; + } + digestInto(out) { + aexists(this); + // `digestInto(out)` is the no-allocation fast path, so callers must pass a + // 32-bit-aligned buffer before we reinterpret the output prefix with `u32(view)`. + aoutput(out, this, true); + this.finished = true; + // RFC 8452 Appendix A maps POLYVAL output back through `ByteReverse(...)`. + // `digestInto()` follows the relaxed `aoutput()` contract, so only out[0..15] may be touched. + const view = out.subarray(0, this.outputLen); + const { s0, s1, s2, s3 } = this; + const o32 = u32(view); + o32[0] = s0; + o32[1] = s1; + o32[2] = s2; + o32[3] = s3; + swap32IfBE(o32); + view.reverse(); + } +} +/** + * GHash MAC for AES-GCM. + * @param msg - Message bytes to authenticate. + * @param key - 16-byte GHASH key. + * @returns 16-byte authentication tag. + * @example + * Authenticates a short message with GHASH and a fresh hash key. + * + * ```ts + * import { ghash } from '@noble/ciphers/_polyval.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(16); + * ghash(new Uint8Array(), key); + * ``` + */ +export const ghash = +/* @__PURE__ */ wrapMacConstructor(16, (key, expectedLength) => new GHASH(key, expectedLength), (msg) => [msg.length]); +/** + * POLYVAL MAC for AES-SIV. + * @param msg - Message bytes to authenticate. + * @param key - 16-byte POLYVAL key. + * @returns 16-byte authentication tag. + * @example + * Authenticates a short message with POLYVAL and a fresh hash key. + * + * ```ts + * import { polyval } from '@noble/ciphers/_polyval.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(16); + * polyval(new Uint8Array(), key); + * ``` + */ +export const polyval = +/* @__PURE__ */ wrapMacConstructor(16, (key, expectedLength) => new Polyval(key, expectedLength), (msg) => [msg.length]); +//# sourceMappingURL=_polyval.js.map \ No newline at end of file diff --git a/node_modules/@noble/ciphers/_polyval.js.map b/node_modules/@noble/ciphers/_polyval.js.map new file mode 100644 index 0000000..bb454fd --- /dev/null +++ b/node_modules/@noble/ciphers/_polyval.js.map @@ -0,0 +1 @@ +{"version":3,"file":"_polyval.js","sourceRoot":"","sources":["src/_polyval.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@noble/ciphers/aes.d.ts b/node_modules/@noble/ciphers/aes.d.ts new file mode 100644 index 0000000..1dab65f --- /dev/null +++ b/node_modules/@noble/ciphers/aes.d.ts @@ -0,0 +1,462 @@ +import { type Cipher, type CipherWithOutput, type CMac, type IHash2, type PRG, type TArg, type TRet, type Uint8ArrayBuffer } from './utils.ts'; +/** + * Increments a counter block with wrap around. + * AES call sites here currently use the big-endian branch, but the helper supports both layouts. + * NIST SP 800-38A Appendix B.1 and SP 800-38D §6.2 increment the + * least-significant/rightmost bits. + * `isLE=false` matches that standard counter-block layout, while `isLE=true` + * is a generic extension for non-AES callers. + * The implementation keeps a 32-bit bitwise carry path, so `carry` is capped at `0xffffff00`; + * larger values throw instead of silently overflowing before the next-byte propagation step. + */ +declare const incBytes: (data: TArg, isLE: boolean, carry?: number) => void; +/** Forward AES key expansion used across ECB/CBC/CTR/GCM/CMAC/KW-style paths. */ +declare function expandKeyLE(key: TArg): TRet; +declare function expandKeyDecLE(key: TArg): TRet; +declare function encrypt(xk: TArg, s0: number, s1: number, s2: number, s3: number): { + s0: number; + s1: number; + s2: number; + s3: number; +}; +declare function decrypt(xk: TArg, s0: number, s1: number, s2: number, s3: number): { + s0: number; + s1: number; + s2: number; + s3: number; +}; +declare function ctrCounter(xk: TArg, nonce: TArg, src: TArg, dst?: TArg): TRet; +declare function ctr32(xk: TArg, isLE: boolean, nonce: TArg, src: TArg, dst?: TArg): TRet; +/** + * **CTR** (Counter Mode): turns a block cipher into a stream cipher using a + * full 16-byte counter block. + * Efficient and parallelizable. Requires a unique nonce per encryption. Unauthenticated: needs MAC. + * @param key - AES key bytes. + * @param nonce - 16-byte counter block, incremented as a full AES block. + * @returns Cipher instance with `encrypt()` and `decrypt()`. + * @example + * Encrypts a short payload with a fresh AES key and counter block. + * + * ```ts + * import { ctr } from '@noble/ciphers/aes.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(16); + * const nonce = randomBytes(16); + * const cipher = ctr(key, nonce); + * cipher.encrypt(new Uint8Array([1, 2, 3])); + * ``` + */ +export declare const ctr: TRet<((key: TArg, nonce: TArg) => CipherWithOutput) & { + blockSize: number; + nonceLength: number; +}>; +/** Options for ECB and CBC. */ +export type BlockOpts = { + /** Disable the library's PKCS#7 padding/unpadding layer and require exact-block inputs. */ + disablePadding?: boolean; +}; +/** + * **ECB** (Electronic Codebook): Deterministic encryption; identical plaintext blocks yield + * identical ciphertexts. Not secure due to pattern leakage. + * See {@link https://words.filippo.io/the-ecb-penguin/ | the AES Penguin}. + * @param key - AES key bytes. + * @param opts - Padding options. See {@link BlockOpts}. + * @returns Cipher instance with `encrypt()` and `decrypt()`. + * @example + * Shows the basic ECB encrypt call shape with a fresh key; avoid ECB in new designs. + * + * ```ts + * import { ecb } from '@noble/ciphers/aes.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(16); + * const cipher = ecb(key); + * cipher.encrypt(new Uint8Array([1, 2, 3])); + * ``` + */ +export declare const ecb: TRet<((key: TArg, opts?: BlockOpts) => CipherWithOutput) & { + blockSize: number; +}>; +/** + * **CBC** (Cipher Block Chaining): Each plaintext block is XORed with the + * previous block of ciphertext before encryption. + * Hard to use: requires proper padding and an unpredictable IV. Unauthenticated: needs MAC. + * @param key - AES key bytes. + * @param iv - 16-byte unpredictable initialization vector. + * @param opts - Padding options. See {@link BlockOpts}. + * @returns Cipher instance with `encrypt()` and `decrypt()`. + * @example + * Encrypts a padded message with a fresh key and 16-byte IV. + * + * ```ts + * import { cbc } from '@noble/ciphers/aes.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(16); + * const iv = randomBytes(16); + * const cipher = cbc(key, iv); + * cipher.encrypt(new Uint8Array([1, 2, 3])); + * ``` + */ +export declare const cbc: TRet<((key: TArg, iv: TArg, opts?: BlockOpts) => CipherWithOutput) & { + blockSize: number; + nonceLength: number; +}>; +/** + * CFB (CFB-128): Cipher Feedback Mode with 128-bit segments. The input for the + * block cipher is the previous cipher output. + * Unauthenticated: needs MAC. + * @param key - AES key bytes. + * @param iv - 16-byte unpredictable initialization vector. + * @returns Cipher instance with `encrypt()` and `decrypt()`. + * @example + * Encrypts a short message with feedback mode and a fresh key/IV pair. + * + * ```ts + * import { cfb } from '@noble/ciphers/aes.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(16); + * const iv = randomBytes(16); + * const cipher = cfb(key, iv); + * cipher.encrypt(new Uint8Array([1, 2, 3])); + * ``` + */ +export declare const cfb: TRet<((key: TArg, iv: TArg) => CipherWithOutput) & { + blockSize: number; + nonceLength: number; +}>; +/** + * **GCM** (Galois/Counter Mode): Combines CTR mode with polynomial MAC. Efficient and widely used. + * Not perfect: + * a) conservative key wear-out is `2**32` (4B) msgs. + * b) key wear-out under random nonces is even smaller: `2**23` (8M) messages for `2**-50` chance. + * c) MAC can be forged: see Poly1305 documentation. + * @param key - AES key bytes. + * @param nonce - Nonce bytes (12 recommended, minimum 8; other lengths use GHASH J0 derivation). + * @param AAD - Additional authenticated data. + * @returns AEAD cipher instance with a fixed 16-byte tag. + * @example + * Encrypts and authenticates plaintext with a fresh key and 12-byte nonce. + * + * ```ts + * import { gcm } from '@noble/ciphers/aes.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(16); + * const nonce = randomBytes(12); + * const cipher = gcm(key, nonce); + * cipher.encrypt(new Uint8Array([1, 2, 3])); + * ``` + */ +export declare const gcm: TRet<((key: TArg, nonce: TArg, AAD?: TArg) => Cipher) & { + blockSize: number; + nonceLength: number; + tagLength: number; + varSizeNonce: true; +}>; +/** + * **SIV** (Synthetic IV): GCM with nonce-misuse resistance. + * Repeating nonces reveal only the fact plaintexts are identical. + * Also suffers from GCM issues: key wear-out limits & MAC forging. + * See {@link https://www.rfc-editor.org/rfc/rfc8452 | RFC 8452}. + * RFC 8452 defines 16-byte and 32-byte AES keys for this mode. + * This implementation also accepts 24-byte AES-192 keys as a local + * extension; see the inline comment next to `validateKeyLength(key)` below + * for the exact scope note. + * @param key - AES key bytes. + * @param nonce - 12-byte nonce. + * @param AAD - Additional authenticated data. + * @returns AEAD cipher instance. + * @example + * Encrypts and authenticates plaintext with a fresh key and nonce, while tolerating reuse. + * + * ```ts + * import { gcmsiv } from '@noble/ciphers/aes.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(16); + * const nonce = randomBytes(12); + * const cipher = gcmsiv(key, nonce); + * cipher.encrypt(new Uint8Array([1, 2, 3])); + * ``` + */ +export declare const gcmsiv: TRet<((key: TArg, nonce: TArg, AAD?: TArg) => Cipher) & { + blockSize: number; + nonceLength: number; + tagLength: number; + varSizeNonce: true; +}>; +declare function encryptBlock(xk: TArg, block: TArg): TRet; +declare function decryptBlock(xk: TArg, block: TArg): TRet; +/** + * AES-KW (key-wrap). Injects static IV into plaintext, adds counter, encrypts 6 times. + * Reduces block size from 16 to 8 bytes. + * Plaintext must be a non-empty multiple of 8 bytes with minimum 16 bytes. + * 8-byte inputs use aeskwp. + * Wrapped ciphertext must be a multiple of 8 bytes with minimum 24 bytes. + * For padded version, use aeskwp. + * See {@link https://www.rfc-editor.org/rfc/rfc3394/ | RFC 3394} and + * {@link https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38F.pdf | NIST SP 800-38F}. + * @param kek - AES key-encryption key. + * @returns Key-wrap cipher instance. + * As with other `wrapCipher(...)` wrappers, `encrypt()` is single-use per + * instance. + * @example + * Wraps a 128-bit content-encryption key with a fresh key-encryption key. + * + * ```ts + * import { aeskw } from '@noble/ciphers/aes.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const kek = randomBytes(16); + * const cek = randomBytes(16); + * const wrap = aeskw(kek); + * wrap.encrypt(cek); + * ``` + */ +export declare const aeskw: TRet<((kek: TArg) => Cipher) & { + blockSize: number; +}>; +/** + * AES-KW, but with padding and allows random keys. + * Uses the RFC 5649 alternative initial value; the second u32 stores the + * 32-bit MLI in network order. + * Wrapped ciphertext must be at least 16 bytes; malformed lengths are + * rejected during AIV/padding checks. + * See {@link https://www.rfc-editor.org/rfc/rfc5649 | RFC 5649}. + * @param kek - AES key-encryption key. + * @returns Padded key-wrap cipher instance. + * @example + * Wraps a short key blob using the padded variant and a fresh key-encryption key. + * + * ```ts + * import { aeskwp } from '@noble/ciphers/aes.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const kek = randomBytes(16); + * const wrap = aeskwp(kek); + * wrap.encrypt(new Uint8Array([1, 2, 3])); + * ``` + */ +export declare const aeskwp: TRet<((kek: TArg) => Cipher) & { + blockSize: number; +}>; +declare class _AesCtrDRBG implements PRG { + readonly blockLen: number; + private key; + private nonce; + private state; + private reseedCnt; + constructor(keyLen: number, seed: TArg, personalization?: TArg); + private update; + addEntropy(seed: TArg, info?: TArg): void; + randomBytes(len: number, info?: TArg): TRet; + clean(): void; +} +/** + * Factory for AES-CTR DRBG instances. + * @param seed - Initial entropy input. + * @param personalization - Optional personalization string mixed into the state. + * @returns Seeded AES-CTR DRBG instance. + */ +export type AesCtrDrbg = (seed: TArg, personalization?: TArg) => TRet<_AesCtrDRBG>; +/** + * AES-CTR DRBG 128-bit - CSPRNG (cryptographically secure pseudorandom number generator). + * It's best to limit usage to non-production, non-critical cases: for example, test-only. + * @param seed - Initial 32-byte entropy input. + * @param personalization - Optional personalization string. + * @returns Seeded DRBG instance. The concrete methods also accept optional additional-input bytes. + * @example + * Seeds the test-only AES-CTR DRBG from fresh entropy and reads bytes from it. + * + * ```ts + * import { rngAesCtrDrbg128 } from '@noble/ciphers/aes.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const seed = randomBytes(32); + * const prg = rngAesCtrDrbg128(seed); + * prg.randomBytes(8); + * ``` + */ +export declare const rngAesCtrDrbg128: TRet; +/** + * AES-CTR DRBG 256-bit - CSPRNG (cryptographically secure pseudorandom number generator). + * It's best to limit usage to non-production, non-critical cases: for example, test-only. + * @param seed - Initial 48-byte entropy input. + * @param personalization - Optional personalization string. + * @returns Seeded DRBG instance. The concrete methods also accept optional additional-input bytes. + * @example + * Seeds the test-only AES-CTR DRBG from fresh entropy and reads bytes from it. + * + * ```ts + * import { rngAesCtrDrbg256 } from '@noble/ciphers/aes.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const seed = randomBytes(48); + * const prg = rngAesCtrDrbg256(seed); + * prg.randomBytes(8); + * ``` + */ +export declare const rngAesCtrDrbg256: TRet; +/** + * Left-shift by one bit and conditionally XOR with 0x87: + * ``` + * if MSB(L) is equal to 0 + * then K1 := L << 1; + * else K1 := (L << 1) XOR const_Rb; + * ``` + * + * Specs: + * {@link https://www.rfc-editor.org/rfc/rfc4493.html#section-2.3 | RFC 4493 Section 2.3}, + * {@link https://datatracker.ietf.org/doc/html/rfc5297.html#section-2.3 | RFC 5297 Section 2.3} + * + * @returns modified `block` (for chaining) + */ +declare function dbl(block: T): T; +/** + * `a XOR b`, running in-place on `a`. + * @param a left operand and output + * @param b right operand + * @returns `a` (for chaining) + */ +declare function xorBlock>(a: T, b: TArg): T; +/** + * xorend as defined in + * {@link https://datatracker.ietf.org/doc/html/rfc5297.html#section-2.1 | RFC 5297 Section 2.1}. + * + * ``` + * leftmost(A, len(A)-len(B)) || (rightmost(A, len(B)) xor B) + * ``` + * + * Mutates `a` in place so the left prefix stays untouched and only the + * rightmost `len(B)` bytes are xored with `b`. + */ +declare function xorend>(a: T, b: TArg): T; +/** + * Internal CMAC class. + */ +declare class _CMAC implements IHash2 { + readonly blockLen: number; + readonly outputLen: number; + private buffer; + private pos; + private finished; + private destroyed; + private k1; + private k2; + private x; + private xk; + constructor(key: TArg); + private process; + update(data: TArg): this; + digestInto(out: TArg): void; + digest(): Uint8ArrayBuffer; + destroy(): void; +} +/** + * AES-CMAC (Cipher-based Message Authentication Code). + * Specs: {@link https://www.rfc-editor.org/rfc/rfc4493.html | RFC 4493}. + * @param msg - Message bytes to authenticate. + * @param key - AES key bytes. + * @returns 16-byte authentication tag. `cmac.create(...)` follows the same incremental MAC shape as + * the other keyed helpers in this repo, including `blockLen`, + * `outputLen`, `digestInto()` and `destroy()`. + * @example + * Authenticates a message with AES-CMAC and a fresh key. + * + * ```ts + * import { cmac } from '@noble/ciphers/aes.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(16); + * cmac(new Uint8Array(), key); + * ``` + */ +export declare const cmac: TRet>; +/** + * S2V (Synthetic Initialization Vector) function as described in + * {@link https://datatracker.ietf.org/doc/html/rfc5297.html#section-2.4 | RFC 5297 Section 2.4}. + * + * ``` + * S2V(K, S1, ..., Sn) { + * if n = 0 then + * return V = AES-CMAC(K, ) + * fi + * D = AES-CMAC(K, ) + * for i = 1 to n-1 do + * D = dbl(D) xor AES-CMAC(K, Si) + * done + * if len(Sn) >= 128 then + * T = Sn xorend D + * else + * T = dbl(D) xor pad(Sn) + * fi + * return V = AES-CMAC(K, T) + * } + * ``` + * + * S2V takes a key and a vector of strings S1, S2, ..., Sn and returns a 128-bit string. + * The S2V function is used to generate a synthetic IV for AES-SIV. + * + * @param key - AES key (128, 192, or 256 bits) + * @param strings - Array of byte arrays to process + * @returns 128-bit synthetic IV + */ +declare function s2v(key: TArg, strings: TArg): TRet; +/** + * Use `gcmsiv` or `aessiv`. + * @returns Never; always throws with the migration hint. + * @throws If called; `siv()` is a removed v1 alias. {@link Error} + * @example + * `siv()` was removed in v2; use `gcmsiv()` for nonce-based SIV instead. + * + * ```ts + * import { gcmsiv } from '@noble/ciphers/aes.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(16); + * const nonce = randomBytes(12); + * const cipher = gcmsiv(key, nonce); + * cipher.encrypt(new Uint8Array([1, 2, 3])); + * ``` + */ +export declare const siv: () => never; +/** + * **SIV**: Synthetic Initialization Vector (SIV) Authenticated Encryption + * Nonce is derived from the plaintext and AAD using the S2V function. + * Supports at most 126 AAD components. RFC 5297 nonce-based use is expressed by + * passing the nonce as the final AAD component before the plaintext. + * See {@link https://datatracker.ietf.org/doc/html/rfc5297.html | RFC 5297}. + * @param key - 32-byte, 48-byte, or 64-byte key. + * @param AAD - Additional authenticated data chunks (up to 126). + * @returns AEAD cipher instance. + * @example + * Authenticates and encrypts plaintext with a fresh key without requiring unique nonces. + * + * ```ts + * import { aessiv } from '@noble/ciphers/aes.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(32); + * const cipher = aessiv(key); + * cipher.encrypt(new Uint8Array([1, 2, 3])); + * ``` + */ +export declare const aessiv: TRet<((key: TArg, ...AAD: TArg) => Cipher) & { + blockSize: number; + tagLength: number; +}>; +/** + * Unsafe low-level internal methods. May change at any time. + * Callers are expected to use reviewed expanded-key outputs, pass mutable and + * aligned 16-byte blocks where required, and treat several helpers as in-place + * mutations of their input buffers or counters. + */ +export declare const unsafe: { + expandKeyLE: typeof expandKeyLE; + expandKeyDecLE: typeof expandKeyDecLE; + encrypt: typeof encrypt; + decrypt: typeof decrypt; + encryptBlock: typeof encryptBlock; + decryptBlock: typeof decryptBlock; + ctrCounter: typeof ctrCounter; + ctr32: typeof ctr32; + dbl: typeof dbl; + xorBlock: typeof xorBlock; + xorend: typeof xorend; + s2v: typeof s2v; +}; +export declare const __TESTS: { + incBytes: typeof incBytes; +}; +export {}; +//# sourceMappingURL=aes.d.ts.map \ No newline at end of file diff --git a/node_modules/@noble/ciphers/aes.d.ts.map b/node_modules/@noble/ciphers/aes.d.ts.map new file mode 100644 index 0000000..f1ce7e8 --- /dev/null +++ b/node_modules/@noble/ciphers/aes.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"aes.d.ts","sourceRoot":"","sources":["src/aes.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@noble/ciphers/aes.js b/node_modules/@noble/ciphers/aes.js new file mode 100644 index 0000000..fdd85a5 --- /dev/null +++ b/node_modules/@noble/ciphers/aes.js @@ -0,0 +1,1765 @@ +/** + * {@link https://en.wikipedia.org/wiki/Advanced_Encryption_Standard | AES} + * a.k.a. Advanced Encryption Standard + * is a variant of Rijndael block cipher, standardized by NIST in 2001. + * We provide the fastest available pure JS implementation. + * + * `cipher = encrypt(block, key)` + * + * Data is split into 128-bit blocks. + * Encrypted in 10/12/14 rounds (128/192/256 bits). In every round: + * 1. **S-box**, table substitution + * 2. **Shift rows**, cyclic shift left of all rows of data array + * 3. **Mix columns**, multiplying every column by fixed polynomial + * 4. **Add round key**, round_key xor i-th column of array + * + * Check out + * {@link https://csrc.nist.gov/files/pubs/fips/197/final/docs/fips-197.pdf | FIPS-197}, + * {@link https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38G.pdf | NIST 800-38G}, + * and {@link https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/aes-development/rijndael-ammended.pdf | original proposal}. + * @module + */ +import { ghash, polyval } from "./_polyval.js"; +// prettier-ignore +import { abytes, anumber, aoutput, byteSwap, clean, complexOverlapBytes, concatBytes, copyBytes, createView, equalBytes, getOutput, isAligned32, isLE, overlapBytes, swap32IfBE, swap8IfBE, u32, u64Lengths, u8, wrapCipher, wrapMacConstructor } from "./utils.js"; +const BLOCK_SIZE = 16; +// AES operates on 16-byte blocks, i.e. 4 32-bit words. +const BLOCK_SIZE32 = 4; +// Shared zero block (`0^128`) used by GCM's `H = CIPH_K(0^128)` / J0 scratch +// and by CMAC / SIV helpers; callers take `.slice()` before mutating it. +const EMPTY_BLOCK = /* @__PURE__ */ new Uint8Array(BLOCK_SIZE); +// RFC 5297 §2.1 / §2.4: S2V uses ` = 0^127 || 1` for the `n = 0` special case. +const ONE_BLOCK = /* @__PURE__ */ Uint8Array.from([ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, +]); +const POLY = 0x11b; // 1 + x + x**3 + x**4 + x**8 +// Validates plain AES key sizes only; AES-SIV's doubled-key contract is checked elsewhere. +function validateKeyLength(key) { + if (![16, 24, 32].includes(key.length)) + throw new Error('"aes key" expected Uint8Array of length 16/24/32, got length=' + key.length); +} +// TODO: remove multiplication, binary ops only +// Doubles one GF(2^8) field element; callers are expected to stay in byte range. +// FIPS 197 upd1 §4.3 equation (4.5): XTIMES(b) left-shifts by one and, when +// b7=1, reduces by m(x); using POLY=0x11b here yields the same byte result +// as XORing with {1b} after the shift. +function mul2(n) { + return (n << 1) ^ (POLY & -(n >> 7)); +} +// Shift-and-add multiplication in GF(2^8); callers are expected to pass byte values. +// FIPS 197 upd1 §4.3 equation (4.7): general products are XORs of repeated +// XTIMES() multiples, e.g. {57}•{13} = {57}⊕{ae}⊕{07}. +function mul(a, b) { + let res = 0; + for (; b > 0; b >>= 1) { + // Usual shift-and-add step in GF(2^8), not a scalar-multiplication ladder. + res ^= a & -(b & 1); // if (b&1) res ^=a (but const-time). + a = mul2(a); // a = 2*a + } + return res; +} +/** + * Increments a counter block with wrap around. + * AES call sites here currently use the big-endian branch, but the helper supports both layouts. + * NIST SP 800-38A Appendix B.1 and SP 800-38D §6.2 increment the + * least-significant/rightmost bits. + * `isLE=false` matches that standard counter-block layout, while `isLE=true` + * is a generic extension for non-AES callers. + * The implementation keeps a 32-bit bitwise carry path, so `carry` is capped at `0xffffff00`; + * larger values throw instead of silently overflowing before the next-byte propagation step. + */ +// Keep the helper explicitly typed so `--isolatedDeclarations` can expose it +// through the test-only `__TESTS` export without inference errors. +const incBytes = (data, isLE, carry = 1) => { + // Keep `carry + byte <= 0xffffffff` so the `| 0` / `>>> 8` path below + // never truncates a real carry bit. + if (!Number.isSafeInteger(carry) || carry > 0xffffff00) + throw new Error('incBytes: wrong carry ' + carry); + abytes(data); + for (let i = 0; i < data.length; i++) { + const pos = !isLE ? data.length - 1 - i : i; + carry = (carry + (data[pos] & 0xff)) | 0; + data[pos] = carry & 0xff; + carry >>>= 8; + } +}; +// AES S-box is generated using finite field inversion, +// an affine transform, and xor of a constant 0x63. +const sbox = /* @__PURE__ */ (() => { + const t = new Uint8Array(256); + // Repeated multiplication by {03} walks all 255 nonzero field elements + // once, so t[255 - i] is the multiplicative inverse of t[i] for the + // affine step. + for (let i = 0, x = 1; i < 256; i++, x ^= mul2(x)) + t[i] = x; + const box = new Uint8Array(256); + // FIPS 197 upd1 §5.1.1: SBOX({00}) = {63} because the inverse step leaves + // {00} at {00}, then the affine transform xors in c = {63}. + box[0] = 0x63; + for (let i = 0; i < 255; i++) { + let x = t[255 - i]; + x |= x << 8; + box[t[i]] = (x ^ (x >> 4) ^ (x >> 5) ^ (x >> 6) ^ (x >> 7) ^ 0x63) & 0xff; + } + clean(t); + return box; +})(); +// FIPS 197 upd1 §5.3.2: INVSBOX() is derived from SBOX() by swapping input +// and output roles (Table 6). +// `indexOf` is only used once at module init, so the quadratic setup cost stays off hot paths. +const invSbox = /* @__PURE__ */ sbox.map((_, j) => sbox.indexOf(j)); +// FIPS 197 upd1 §5.2: ROTWORD([a0,a1,a2,a3]) = [a1,a2,a3,a0]; with this LE +// word packing that is a right rotate by 8 bits. +const rotr32_8 = (n) => (n << 24) | (n >>> 8); +// LE T-table helper: rotates one precomputed word by one byte so T1/T2/T3 +// reuse T0's substitution/mix result in the other byte lanes. +const rotl32_8 = (n) => (n << 8) | (n >>> 24); +// T-table is optimization suggested in 5.2 of original proposal (missed from FIPS-197). Changes: +// - LE instead of BE +// - bigger tables: T0 and T1 are merged into T01 table and T2 & T3 into T23; +// so index is u16, instead of u8. This speeds up things, unexpectedly +function genTtable(sbox, fn) { + if (sbox.length !== 256) + throw new Error('Wrong sbox length'); + const T0 = new Uint32Array(256).map((_, j) => fn(sbox[j])); + const T1 = T0.map(rotl32_8); + const T2 = T1.map(rotl32_8); + const T3 = T2.map(rotl32_8); + // Pre-xor adjacent lanes so apply0123/applySbox can fetch two substituted + // byte lanes per lookup in the LE round layout. + const T01 = new Uint32Array(256 * 256); + const T23 = new Uint32Array(256 * 256); + const sbox2 = new Uint16Array(256 * 256); + for (let i = 0; i < 256; i++) { + for (let j = 0; j < 256; j++) { + const idx = i * 256 + j; + T01[idx] = T0[i] ^ T1[j]; + T23[idx] = T2[i] ^ T3[j]; + sbox2[idx] = (sbox[i] << 8) | sbox[j]; + } + } + return { sbox, sbox2, T0, T1, T2, T3, T01, T23 }; +} +// Forward round precompute: the packed word stores the MIXCOLUMNS row +// [{02},{01},{01},{03}] in LE byte-lane order, and the returned `sbox2` +// is also reused by key expansion and the final round. +const tableEncoding = /* @__PURE__ */ genTtable(sbox, (s) => (mul(s, 3) << 24) | (s << 16) | (s << 8) | mul(s, 2)); +// Inverse round precompute: the packed word stores the INVMIXCOLUMNS row +// [{0e},{09},{0d},{0b}] in LE byte-lane order, and the tables are reused +// by decrypt() and expandKeyDecLE(). +const tableDecoding = /* @__PURE__ */ genTtable(invSbox, (s) => (mul(s, 11) << 24) | (mul(s, 13) << 16) | (mul(s, 9) << 8) | mul(s, 14)); +// FIPS 197 upd1 §5.2 Table 5: left-most bytes of Rcon[j] = x^(j-1), generated by repeated XTIMES(). +const xPowers = /* @__PURE__ */ (() => { + const p = new Uint8Array(16); + for (let i = 0, x = 1; i < 16; i++, x = mul2(x)) + p[i] = x; + return p; +})(); +/** Forward AES key expansion used across ECB/CBC/CTR/GCM/CMAC/KW-style paths. */ +function expandKeyLE(key) { + abytes(key); + const len = key.length; + validateKeyLength(key); + const { sbox2 } = tableEncoding; + const toClean = []; + // Copy on BE or misaligned inputs so the LE word normalization below never + // mutates caller key bytes in place. + if (!isLE || !isAligned32(key)) + toClean.push((key = copyBytes(key))); + const k32 = swap32IfBE(u32(key)); + const Nk = k32.length; + // `applySbox` normally reads one byte lane from each argument; repeating + // `n` across all four lanes turns it into SUBWORD(n). + const subByte = (n) => applySbox(sbox2, n, n, n, n); + // AES key sizes are 16/24/32 bytes, so len + 28 yields the 44/52/60 + // schedule words from FIPS 197 §5.2 / Table 3. + const xk = new Uint32Array(len + 28); // expanded key + xk.set(k32); + // 4.3.1 Key expansion + for (let i = Nk; i < xk.length; i++) { + let t = xk[i - 1]; + if (i % Nk === 0) + t = subByte(rotr32_8(t)) ^ xPowers[i / Nk - 1]; + else if (Nk > 6 && i % Nk === 4) + t = subByte(t); + xk[i] = xk[i - Nk] ^ t; + } + clean(...toClean); + return xk; +} +function expandKeyDecLE(key) { + const encKey = expandKeyLE(key); + const xk = encKey.slice(); + const Nk = encKey.length; + const { sbox2 } = tableEncoding; + const { T0, T1, T2, T3 } = tableDecoding; + // Local decrypt() walks round keys forward from xk[0], so reverse the + // encryption round-key blocks first before applying the equivalent-inverse + // middle-round transform. + for (let i = 0; i < Nk; i += 4) { + for (let j = 0; j < 4; j++) + xk[i + j] = encKey[Nk - i - 4 + j]; + } + clean(encKey); + // Apply InvMixColumn to the reversed round keys using the same LE sbox2 + // packing as the forward path. + // apply InvMixColumn except first & last round + for (let i = 4; i < Nk - 4; i++) { + const x = xk[i]; + const w = applySbox(sbox2, x, x, x, x); + xk[i] = T0[w & 0xff] ^ T1[(w >>> 8) & 0xff] ^ T2[(w >>> 16) & 0xff] ^ T3[w >>> 24]; + } + return xk; +} +// Apply tables +function apply0123(T01, T23, s0, s1, s2, s3) { + // `T01` takes the low byte lane from `s0` plus the next lane from `s1`; + // `T23` does the same for `s2`/`s3`. + // Equivalent to `T0[s0&0xff] ^ T1[(s1>>>8)&0xff] ^ T2[(s2>>>16)&0xff] ^ + // T3[s3>>>24]`, but with two merged-table fetches. + return (T01[((s0 << 8) & 0xff00) | ((s1 >>> 8) & 0xff)] ^ + T23[((s2 >>> 8) & 0xff00) | ((s3 >>> 24) & 0xff)]); +} +function applySbox(sbox2, s0, s1, s2, s3) { + // `sbox2` packs two substituted byte lanes at a time in the same LE + // layout used by the round code. + // Equivalent to `SBOX(byte0(s0)) | SBOX(byte1(s1))<<8 | + // SBOX(byte2(s2))<<16 | SBOX(byte3(s3))<<24`. + return (sbox2[(s0 & 0xff) | (s1 & 0xff00)] | + (sbox2[((s2 >>> 16) & 0xff) | ((s3 >>> 16) & 0xff00)] << 16)); +} +function encrypt(xk, s0, s1, s2, s3) { + const { sbox2, T01, T23 } = tableEncoding; + let k = 0; + ((s0 ^= xk[k++]), (s1 ^= xk[k++]), (s2 ^= xk[k++]), (s3 ^= xk[k++])); + // `xk` has Nr+1 round-key blocks, so after the initial AddRoundKey and the + // final S-box-only round there are Nr-1 full table/MixColumns rounds left. + const rounds = xk.length / 4 - 2; + for (let i = 0; i < rounds; i++) { + const t0 = xk[k++] ^ apply0123(T01, T23, s0, s1, s2, s3); + const t1 = xk[k++] ^ apply0123(T01, T23, s1, s2, s3, s0); + const t2 = xk[k++] ^ apply0123(T01, T23, s2, s3, s0, s1); + const t3 = xk[k++] ^ apply0123(T01, T23, s3, s0, s1, s2); + ((s0 = t0), (s1 = t1), (s2 = t2), (s3 = t3)); + } + // last round (without mixcolumns, so using SBOX2 table) + const t0 = xk[k++] ^ applySbox(sbox2, s0, s1, s2, s3); + const t1 = xk[k++] ^ applySbox(sbox2, s1, s2, s3, s0); + const t2 = xk[k++] ^ applySbox(sbox2, s2, s3, s0, s1); + const t3 = xk[k++] ^ applySbox(sbox2, s3, s0, s1, s2); + return { s0: t0, s1: t1, s2: t2, s3: t3 }; +} +// Can't be merged with encrypt: arg positions for apply0123 / applySbox are different +function decrypt(xk, s0, s1, s2, s3) { + const { sbox2, T01, T23 } = tableDecoding; + let k = 0; + ((s0 ^= xk[k++]), (s1 ^= xk[k++]), (s2 ^= xk[k++]), (s3 ^= xk[k++])); + // With `expandKeyDecLE()` the round keys are already reversed and middle + // rounds are InvMixColumns-adjusted, so this loop follows the equivalent + // inverse cipher order directly. + const rounds = xk.length / 4 - 2; + for (let i = 0; i < rounds; i++) { + const t0 = xk[k++] ^ apply0123(T01, T23, s0, s3, s2, s1); + const t1 = xk[k++] ^ apply0123(T01, T23, s1, s0, s3, s2); + const t2 = xk[k++] ^ apply0123(T01, T23, s2, s1, s0, s3); + const t3 = xk[k++] ^ apply0123(T01, T23, s3, s2, s1, s0); + ((s0 = t0), (s1 = t1), (s2 = t2), (s3 = t3)); + } + // Final equivalent-inverse round omits InvMixColumns, so use inverse + // S-box lanes in InvShiftRows order. + const t0 = xk[k++] ^ applySbox(sbox2, s0, s3, s2, s1); + const t1 = xk[k++] ^ applySbox(sbox2, s1, s0, s3, s2); + const t2 = xk[k++] ^ applySbox(sbox2, s2, s1, s0, s3); + const t3 = xk[k++] ^ applySbox(sbox2, s3, s2, s1, s0); + return { s0: t0, s1: t1, s2: t2, s3: t3 }; +} +function ctrCounter(xk, nonce, src, dst) { + abytes(nonce, BLOCK_SIZE, 'nonce'); + abytes(src); + const srcLen = src.length; + dst = getOutput(srcLen, dst); + complexOverlapBytes(src, dst); + // Internal helper: mutate `nonce` in place as the live counter block so + // each encrypted block uses the next CTR value. + const ctr = nonce; + const c32 = u32(ctr); + const src32 = u32(src); + const dst32 = u32(dst); + // Fill block (empty, ctr=0) + let { s0, s1, s2, s3 } = encrypt(xk, swap8IfBE(c32[0]), swap8IfBE(c32[1]), swap8IfBE(c32[2]), swap8IfBE(c32[3])); + // process blocks + for (let i = 0; i + 4 <= src32.length; i += 4) { + dst32[i + 0] = src32[i + 0] ^ swap8IfBE(s0); + dst32[i + 1] = src32[i + 1] ^ swap8IfBE(s1); + dst32[i + 2] = src32[i + 2] ^ swap8IfBE(s2); + dst32[i + 3] = src32[i + 3] ^ swap8IfBE(s3); + incBytes(ctr, false, 1); // Full 128 bit counter with wrap around + ({ s0, s1, s2, s3 } = encrypt(xk, swap8IfBE(c32[0]), swap8IfBE(c32[1]), swap8IfBE(c32[2]), swap8IfBE(c32[3]))); + } + // NIST SP 800-38A CTR mode uses the leading `u` bits of the next output + // block for the final short block. + // It's possible to handle > u32 fast, but is it worth it? + const start = BLOCK_SIZE * Math.floor(src32.length / BLOCK_SIZE32); + if (start < srcLen) { + const b32 = new Uint32Array([s0, s1, s2, s3]); + swap32IfBE(b32); + const buf = u8(b32); + for (let i = start, pos = 0; i < srcLen; i++, pos++) + dst[i] = src[i] ^ buf[pos]; + clean(b32); + } + // Unsafe mutable-counter API only advances whole blocks. Callers that want to + // resume after consuming part of this block must re-run from the same counter + // with left-padding and strip the already-consumed prefix themselves. + return dst; +} +// AES CTR with overflowing 32 bit counter +// It's possible to do 32le significantly simpler (and probably faster) by using u32. +// But, we need both, and perf bottleneck is in ghash anyway. +// Unsafe 32-bit CTR helper: mutates `nonce` in place, expects aligned `src`/`dst`, +// and uses `isLE` to choose which 32-bit counter word is incremented. +function ctr32(xk, isLE, nonce, src, dst) { + abytes(nonce, BLOCK_SIZE, 'nonce'); + abytes(src); + dst = getOutput(src.length, dst); + const ctr = nonce; // write new value to nonce, so it can be re-used + const c32 = u32(ctr); + const view = createView(ctr); + const src32 = u32(src); + const dst32 = u32(dst); + // NIST SP 800-38D GCTR increments the rightmost 32 bits of J0, while + // RFC 8452 AES-GCM-SIV increments the first 32 bits as a little-endian u32. + const ctrPos = isLE ? 0 : 12; + const srcLen = src.length; + // Fill block (empty, ctr=0) + let ctrNum = view.getUint32(ctrPos, isLE); // read current counter value + let { s0, s1, s2, s3 } = encrypt(xk, swap8IfBE(c32[0]), swap8IfBE(c32[1]), swap8IfBE(c32[2]), swap8IfBE(c32[3])); + // process blocks + for (let i = 0; i + 4 <= src32.length; i += 4) { + dst32[i + 0] = src32[i + 0] ^ swap8IfBE(s0); + dst32[i + 1] = src32[i + 1] ^ swap8IfBE(s1); + dst32[i + 2] = src32[i + 2] ^ swap8IfBE(s2); + dst32[i + 3] = src32[i + 3] ^ swap8IfBE(s3); + ctrNum = (ctrNum + 1) >>> 0; // u32 wrap + view.setUint32(ctrPos, ctrNum, isLE); + ({ s0, s1, s2, s3 } = encrypt(xk, swap8IfBE(c32[0]), swap8IfBE(c32[1]), swap8IfBE(c32[2]), swap8IfBE(c32[3]))); + } + // leftovers (less than a block) + const start = BLOCK_SIZE * Math.floor(src32.length / BLOCK_SIZE32); + if (start < srcLen) { + const b32 = new Uint32Array([s0, s1, s2, s3]); + swap32IfBE(b32); + const buf = u8(b32); + for (let i = start, pos = 0; i < srcLen; i++, pos++) + dst[i] = src[i] ^ buf[pos]; + clean(b32); + } + // Same unsafe contract as ctrCounter(): only full blocks advance the stored + // mutable counter state; partial-block continuation is caller-managed. + return dst; +} +/** + * **CTR** (Counter Mode): turns a block cipher into a stream cipher using a + * full 16-byte counter block. + * Efficient and parallelizable. Requires a unique nonce per encryption. Unauthenticated: needs MAC. + * @param key - AES key bytes. + * @param nonce - 16-byte counter block, incremented as a full AES block. + * @returns Cipher instance with `encrypt()` and `decrypt()`. + * @example + * Encrypts a short payload with a fresh AES key and counter block. + * + * ```ts + * import { ctr } from '@noble/ciphers/aes.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(16); + * const nonce = randomBytes(16); + * const cipher = ctr(key, nonce); + * cipher.encrypt(new Uint8Array([1, 2, 3])); + * ``` + */ +export const ctr = /* @__PURE__ */ wrapCipher({ blockSize: 16, nonceLength: 16 }, function aesctr(key, nonce) { + function processCtr(buf, dst) { + abytes(buf); + if (dst !== undefined) { + abytes(dst); + // Optional output buffers must stay 4-byte aligned because + // ctrCounter() reinterprets them as Uint32Array words. + if (!isAligned32(dst)) + throw new Error('unaligned destination'); + } + const xk = expandKeyLE(key); + // Public CTR keeps caller nonce bytes immutable even though ctrCounter() + // advances the live 16-byte counter block in place. + const n = copyBytes(nonce); // align + avoid changing + const toClean = [xk, n]; + if (!isAligned32(buf)) + toClean.push((buf = copyBytes(buf))); + const out = ctrCounter(xk, n, buf, dst); + clean(...toClean); + return out; + } + return { + encrypt: (plaintext, dst) => processCtr(plaintext, dst), + decrypt: (ciphertext, dst) => processCtr(ciphertext, dst), + }; +}); +function validateBlockDecrypt(data) { + abytes(data); + // ECB/CBC decryption always consumes whole ciphertext blocks; PKCS#7/CMS + // padding, when enabled, is removed only after decrypting the final block. + if (data.length % BLOCK_SIZE !== 0) { + throw new Error('aes-(cbc/ecb).decrypt ciphertext should consist of blocks with size ' + BLOCK_SIZE); + } +} +// ECB/CBC core modes operate on whole blocks; `pkcs5` enables the library's +// PKCS#7/CMS-compatible final-block padding convenience before encryption. +function validateBlockEncrypt(plaintext, pkcs5, dst) { + abytes(plaintext); + let outLen = plaintext.length; + const remaining = outLen % BLOCK_SIZE; + if (!pkcs5 && remaining !== 0) + throw new Error('aec/(cbc-ecb): unpadded plaintext with disabled padding'); + if (pkcs5) { + let left = BLOCK_SIZE - remaining; + // RFC 5652 pads even already-aligned inputs, so a full extra block is + // appended when the plaintext length is already a multiple of 16 bytes. + if (!left) + left = BLOCK_SIZE; // if no bytes left, create empty padding block + outLen = outLen + left; + } + dst = getOutput(outLen, dst); + complexOverlapBytes(plaintext, dst); + // Copy on BE or misaligned inputs so u32()/swap32IfBE() normalization never + // mutates caller plaintext bytes in place before ECB/CBC processing. + if (!isLE || !isAligned32(plaintext)) + plaintext = copyBytes(plaintext); + const b = u32(plaintext); + swap32IfBE(b); + const o = u32(dst); + return { b, o, out: dst }; +} +// `pkcs5` is the historical option name; for AES's 16-byte block this is the +// generic PKCS#7/CMS-style block-padding rule on decrypt. +function validatePKCS(data, pkcs5) { + if (!pkcs5) + return data; + const len = data.length; + // RFC 5652 pads even empty / already-aligned inputs, so a valid padded + // ECB/CBC ciphertext is never empty when PKCS#7/CMS unpadding is enabled. + // AES-CBC/ECB ciphertext should be full blocks before unpadding + if (len === 0) + throw new Error('aes/pkcs7: empty ciphertext not allowed'); + const lastByte = data[len - 1]; + let valid = 1; + valid &= ((lastByte - 1) >>> 31) ^ 1; // pad >= 1 + valid &= ((16 - lastByte) >>> 31) ^ 1; // pad <= 16 + // Check exactly 16 tail bytes in constant-shape loop + // For i < pad: byte must equal pad + // For i >= pad: ignore byte + for (let i = 0; i < 16; i++) { + // const b = data[len - 1 - i]; + const shouldCheck = (i - lastByte) >>> 31; // 1 if i < pad else 0 + const eq = (data[len - 1 - i] ^ lastByte) === 0 ? 1 : 0; // 1 if equal + valid &= eq | (shouldCheck ^ 1); // pass if equal OR not checked + } + // if (invalidLen) throw new Error('aes/pkcs7: ciphertext length must be multiple of 16'); + if (!valid) + throw new Error('aes/pkcs7: wrong padding'); + return data.subarray(0, len - lastByte); +} +// ECB/CBC callers only pass the final short block here, so `left.length` is +// 0..15 and the helper always emits exactly one padded 16-byte block. +function padPCKS(left) { + const tmp = new Uint8Array(16); + const tmp32 = u32(tmp); + tmp.set(left); + const paddingByte = BLOCK_SIZE - left.length; + // RFC 5652 §6.3 fills the whole suffix with the padding length byte: + // e.g. `aa 0f..0f` for a 1-byte tail, or `10..10` for a full extra block. + for (let i = BLOCK_SIZE - paddingByte; i < BLOCK_SIZE; i++) + tmp[i] = paddingByte; + return tmp32; +} +/** + * **ECB** (Electronic Codebook): Deterministic encryption; identical plaintext blocks yield + * identical ciphertexts. Not secure due to pattern leakage. + * See {@link https://words.filippo.io/the-ecb-penguin/ | the AES Penguin}. + * @param key - AES key bytes. + * @param opts - Padding options. See {@link BlockOpts}. + * @returns Cipher instance with `encrypt()` and `decrypt()`. + * @example + * Shows the basic ECB encrypt call shape with a fresh key; avoid ECB in new designs. + * + * ```ts + * import { ecb } from '@noble/ciphers/aes.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(16); + * const cipher = ecb(key); + * cipher.encrypt(new Uint8Array([1, 2, 3])); + * ``` + */ +export const ecb = /* @__PURE__ */ wrapCipher({ blockSize: 16 }, function aesecb(key, opts = {}) { + const pkcs5 = !opts.disablePadding; + return { + encrypt(plaintext, dst) { + const { b, o, out: _out } = validateBlockEncrypt(plaintext, pkcs5, dst); + const xk = expandKeyLE(key); + let i = 0; + for (; i + 4 <= b.length;) { + const { s0, s1, s2, s3 } = encrypt(xk, b[i + 0], b[i + 1], b[i + 2], b[i + 3]); + ((o[i++] = s0), (o[i++] = s1), (o[i++] = s2), (o[i++] = s3)); + } + if (pkcs5) { + const tmp32 = padPCKS(plaintext.subarray(i * 4)); + swap32IfBE(tmp32); + const { s0, s1, s2, s3 } = encrypt(xk, tmp32[0], tmp32[1], tmp32[2], tmp32[3]); + ((o[i++] = s0), (o[i++] = s1), (o[i++] = s2), (o[i++] = s3)); + } + swap32IfBE(o); + clean(xk); + return _out; + }, + decrypt(ciphertext, dst) { + validateBlockDecrypt(ciphertext); + const xk = expandKeyDecLE(key); + dst = getOutput(ciphertext.length, dst); + const toClean = [xk]; + complexOverlapBytes(ciphertext, dst); + // Copy on BE or misaligned ciphertext so u32()/swap32IfBE() + // normalization never mutates caller bytes in place before decrypt(). + if (!isLE || !isAligned32(ciphertext)) + toClean.push((ciphertext = copyBytes(ciphertext))); + const b = u32(ciphertext); + const o = u32(dst); + swap32IfBE(b); + for (let i = 0; i + 4 <= b.length;) { + const { s0, s1, s2, s3 } = decrypt(xk, b[i + 0], b[i + 1], b[i + 2], b[i + 3]); + ((o[i++] = s0), (o[i++] = s1), (o[i++] = s2), (o[i++] = s3)); + } + swap32IfBE(o); + clean(...toClean); + return validatePKCS(dst, pkcs5); + }, + }; +}); +/** + * **CBC** (Cipher Block Chaining): Each plaintext block is XORed with the + * previous block of ciphertext before encryption. + * Hard to use: requires proper padding and an unpredictable IV. Unauthenticated: needs MAC. + * @param key - AES key bytes. + * @param iv - 16-byte unpredictable initialization vector. + * @param opts - Padding options. See {@link BlockOpts}. + * @returns Cipher instance with `encrypt()` and `decrypt()`. + * @example + * Encrypts a padded message with a fresh key and 16-byte IV. + * + * ```ts + * import { cbc } from '@noble/ciphers/aes.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(16); + * const iv = randomBytes(16); + * const cipher = cbc(key, iv); + * cipher.encrypt(new Uint8Array([1, 2, 3])); + * ``` + */ +export const cbc = /* @__PURE__ */ wrapCipher({ blockSize: 16, nonceLength: 16 }, function aescbc(key, iv, opts = {}) { + const pkcs5 = !opts.disablePadding; + return { + encrypt(plaintext, dst) { + const xk = expandKeyLE(key); + const { b, o, out: _out } = validateBlockEncrypt(plaintext, pkcs5, dst); + let _iv = iv; + const toClean = [xk]; + // Copy on BE or misaligned inputs so IV normalization and the mutable + // local chaining state never write back into caller IV bytes. + if (!isLE || !isAligned32(_iv)) + toClean.push((_iv = copyBytes(_iv))); + const n32 = u32(_iv); + swap32IfBE(n32); + // prettier-ignore + let s0 = n32[0], s1 = n32[1], s2 = n32[2], s3 = n32[3]; + let i = 0; + for (; i + 4 <= b.length;) { + ((s0 ^= b[i + 0]), (s1 ^= b[i + 1]), (s2 ^= b[i + 2]), (s3 ^= b[i + 3])); + ({ s0, s1, s2, s3 } = encrypt(xk, s0, s1, s2, s3)); + ((o[i++] = s0), (o[i++] = s1), (o[i++] = s2), (o[i++] = s3)); + } + if (pkcs5) { + const tmp32 = padPCKS(plaintext.subarray(i * 4)); + swap32IfBE(tmp32); + ((s0 ^= tmp32[0]), (s1 ^= tmp32[1]), (s2 ^= tmp32[2]), (s3 ^= tmp32[3])); + ({ s0, s1, s2, s3 } = encrypt(xk, s0, s1, s2, s3)); + ((o[i++] = s0), (o[i++] = s1), (o[i++] = s2), (o[i++] = s3)); + } + swap32IfBE(o); + clean(...toClean); + return _out; + }, + decrypt(ciphertext, dst) { + validateBlockDecrypt(ciphertext); + const xk = expandKeyDecLE(key); + let _iv = iv; + const toClean = [xk]; + // Copy on BE or misaligned inputs so IV normalization and the mutable + // local chaining state never write back into caller IV bytes. + if (!isLE || !isAligned32(_iv)) + toClean.push((_iv = copyBytes(_iv))); + const n32 = u32(_iv); + swap32IfBE(n32); + dst = getOutput(ciphertext.length, dst); + complexOverlapBytes(ciphertext, dst); + // Copy on BE or misaligned ciphertext so u32()/swap32IfBE() + // normalization never mutates caller bytes in place before decrypt(). + if (!isLE || !isAligned32(ciphertext)) + toClean.push((ciphertext = copyBytes(ciphertext))); + const b = u32(ciphertext); + const o = u32(dst); + swap32IfBE(b); + // prettier-ignore + let s0 = n32[0], s1 = n32[1], s2 = n32[2], s3 = n32[3]; + for (let i = 0; i + 4 <= b.length;) { + // prettier-ignore + const ps0 = s0, ps1 = s1, ps2 = s2, ps3 = s3; + ((s0 = b[i + 0]), (s1 = b[i + 1]), (s2 = b[i + 2]), (s3 = b[i + 3])); + const { s0: o0, s1: o1, s2: o2, s3: o3 } = decrypt(xk, s0, s1, s2, s3); + ((o[i++] = o0 ^ ps0), (o[i++] = o1 ^ ps1), (o[i++] = o2 ^ ps2), (o[i++] = o3 ^ ps3)); + } + swap32IfBE(o); + clean(...toClean); + return validatePKCS(dst, pkcs5); + }, + }; +}); +/** + * CFB (CFB-128): Cipher Feedback Mode with 128-bit segments. The input for the + * block cipher is the previous cipher output. + * Unauthenticated: needs MAC. + * @param key - AES key bytes. + * @param iv - 16-byte unpredictable initialization vector. + * @returns Cipher instance with `encrypt()` and `decrypt()`. + * @example + * Encrypts a short message with feedback mode and a fresh key/IV pair. + * + * ```ts + * import { cfb } from '@noble/ciphers/aes.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(16); + * const iv = randomBytes(16); + * const cipher = cfb(key, iv); + * cipher.encrypt(new Uint8Array([1, 2, 3])); + * ``` + */ +export const cfb = /* @__PURE__ */ wrapCipher({ blockSize: 16, nonceLength: 16 }, function aescfb(key, iv) { + function processCfb(src, isEncrypt, dst) { + abytes(src); + const srcLen = src.length; + dst = getOutput(srcLen, dst); + // CFB feeds back previous ciphertext, so overlapping src/dst could + // overwrite bytes that are still needed as the next feedback block. + if (overlapBytes(src, dst)) + throw new Error('overlapping src and dst not supported.'); + const xk = expandKeyLE(key); + let _iv = iv; + const toClean = [xk]; + // Copy on BE or misaligned inputs so u32()/swap32IfBE() normalization + // never mutates caller IV/src bytes in place before CFB processing. + if (!isLE || !isAligned32(_iv)) + toClean.push((_iv = copyBytes(_iv))); + if (!isLE || !isAligned32(src)) + toClean.push((src = copyBytes(src))); + const src32 = u32(src); + const dst32 = u32(dst); + // NIST SP 800-38A §6.3 feeds back the previous ciphertext segment in + // both directions: encrypt reuses freshly written dst words, decrypt + // reuses the source ciphertext words. + const next32 = isEncrypt ? dst32 : src32; + const n32 = u32(_iv); + swap32IfBE(src32); + swap32IfBE(n32); + // prettier-ignore + let s0 = n32[0], s1 = n32[1], s2 = n32[2], s3 = n32[3]; + for (let i = 0; i + 4 <= src32.length;) { + const { s0: e0, s1: e1, s2: e2, s3: e3 } = encrypt(xk, s0, s1, s2, s3); + dst32[i + 0] = src32[i + 0] ^ e0; + dst32[i + 1] = src32[i + 1] ^ e1; + dst32[i + 2] = src32[i + 2] ^ e2; + dst32[i + 3] = src32[i + 3] ^ e3; + ((s0 = next32[i++]), (s1 = next32[i++]), (s2 = next32[i++]), (s3 = next32[i++])); + } + // leftovers (less than block) + const start = BLOCK_SIZE * Math.floor(src32.length / BLOCK_SIZE32); + if (start < srcLen) { + // Byte-oriented API: for a final short tail, reuse the next CFB-128 + // output block and XOR only the needed prefix. RFC 3826 §3.1.3 / + // §3.1.4 describes the same no-padding rule at bit granularity for a + // final r<=128 segment. + ({ s0, s1, s2, s3 } = encrypt(xk, s0, s1, s2, s3)); + const tmp = new Uint32Array([s0, s1, s2, s3]); + swap32IfBE(tmp); + const buf = u8(tmp); + for (let i = start, pos = 0; i < srcLen; i++, pos++) + dst[i] = src[i] ^ buf[pos]; + clean(buf); + } + swap32IfBE(dst32); + clean(...toClean); + return dst; + } + return { + encrypt: (plaintext, dst) => processCfb(plaintext, true, dst), + decrypt: (ciphertext, dst) => processCfb(ciphertext, false, dst), + }; +}); +// TODO: merge with chacha, however gcm has bitLen while chacha has byteLen +// `data` is the payload covered by the polynomial MAC: ciphertext for GCM, +// plaintext for GCM-SIV. Keep AAD/data/length as separate updates because +// GHASH/POLYVAL pad each call to block boundaries, so the chunks must match the +// spec-defined segments instead of arbitrary concatenation boundaries. +function computeTag(fn, isLE, key, data, AAD) { + const aadLength = AAD ? AAD.length : 0; + const h = fn.create(key, data.length + aadLength); + if (AAD) + h.update(AAD); + // u64Lengths() takes (dataBits, aadBits) but still serializes the final + // block as len(AAD) || len(data), matching both GCM and GCM-SIV. + const num = u64Lengths(8 * data.length, 8 * aadLength, isLE); + h.update(data); + h.update(num); + const res = h.digest(); + clean(num); + return res; +} +/** + * **GCM** (Galois/Counter Mode): Combines CTR mode with polynomial MAC. Efficient and widely used. + * Not perfect: + * a) conservative key wear-out is `2**32` (4B) msgs. + * b) key wear-out under random nonces is even smaller: `2**23` (8M) messages for `2**-50` chance. + * c) MAC can be forged: see Poly1305 documentation. + * @param key - AES key bytes. + * @param nonce - Nonce bytes (12 recommended, minimum 8; other lengths use GHASH J0 derivation). + * @param AAD - Additional authenticated data. + * @returns AEAD cipher instance with a fixed 16-byte tag. + * @example + * Encrypts and authenticates plaintext with a fresh key and 12-byte nonce. + * + * ```ts + * import { gcm } from '@noble/ciphers/aes.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(16); + * const nonce = randomBytes(12); + * const cipher = gcm(key, nonce); + * cipher.encrypt(new Uint8Array([1, 2, 3])); + * ``` + */ +export const gcm = /* @__PURE__ */ wrapCipher({ blockSize: 16, nonceLength: 12, tagLength: 16, varSizeNonce: true }, function aesgcm(key, nonce, AAD) { + // SP 800-38D lets implementations narrow supported IV lengths. + // This wrapper intentionally requires at least 8 bytes; OpenSSL accepts shorter IVs too. + // 12-byte nonces take the fast path; other allowed lengths use GHASH to derive J0. + if (nonce.length < 8) + throw new Error('aes/gcm: invalid nonce length'); + const tagLength = 16; + function _computeTag(authKey, tagMask, data) { + const tag = computeTag(ghash, false, authKey, data, AAD); + for (let i = 0; i < tagMask.length; i++) + tag[i] ^= tagMask[i]; + return tag; + } + function deriveKeys() { + const xk = expandKeyLE(key); + const authKey = EMPTY_BLOCK.slice(); + const counter = EMPTY_BLOCK.slice(); + ctr32(xk, false, counter, counter, authKey); + // NIST 800-38d, page 15: different behavior for 96-bit and non-96-bit nonces + if (nonce.length === 12) { + counter.set(nonce); + } + else { + const nonceLen = EMPTY_BLOCK.slice(); + const view = createView(nonceLen); + view.setBigUint64(8, BigInt(nonce.length * 8), false); + // GHASH.update() pads each call to 16 bytes, so + // update(nonce).update(nonceLen) realizes + // IV || 0^s || 0^64 || [len(IV)]_64 for non-96-bit nonces. + // ghash(nonce || u64be(0) || u64be(nonceLen*8)) + const g = ghash.create(authKey).update(nonce).update(nonceLen); + g.digestInto(counter); // digestInto doesn't trigger '.destroy' + g.destroy(); + } + // GCTR_K(J0, 0^128) = E_K(J0); reusing ctr32() here extracts that tag + // mask and leaves `counter` advanced to inc32(J0) for payload GCTR. + const tagMask = ctr32(xk, false, counter, EMPTY_BLOCK); + return { xk, authKey, counter, tagMask }; + } + return { + encrypt(plaintext) { + const { xk, authKey, counter, tagMask } = deriveKeys(); + const out = new Uint8Array(plaintext.length + tagLength); + const toClean = [xk, authKey, counter, tagMask]; + if (!isAligned32(plaintext)) + toClean.push((plaintext = copyBytes(plaintext))); + ctr32(xk, false, counter, plaintext, out.subarray(0, plaintext.length)); + const tag = _computeTag(authKey, tagMask, out.subarray(0, out.length - tagLength)); + toClean.push(tag); + out.set(tag, plaintext.length); + clean(...toClean); + return out; + }, + decrypt(ciphertext) { + const { xk, authKey, counter, tagMask } = deriveKeys(); + const toClean = [xk, authKey, tagMask, counter]; + if (!isAligned32(ciphertext)) + toClean.push((ciphertext = copyBytes(ciphertext))); + const data = ciphertext.subarray(0, -tagLength); + const passedTag = ciphertext.subarray(-tagLength); + const tag = _computeTag(authKey, tagMask, data); + toClean.push(tag); + // NIST SP 800-38D §7.2 permits equivalent step orderings; verify the + // tag before CTR so unauthenticated plaintext is never materialized. + if (!equalBytes(tag, passedTag)) { + clean(...toClean); + throw new Error('aes/gcm: invalid ghash tag'); + } + const out = ctr32(xk, false, counter, data); + clean(...toClean); + return out; + }, + }; +}); +const limit = (name, min, max) => (value) => { + // Current AES-SIV/GCM-SIV callers pass protocol limits from RFC 8452 / RFC 5297, + // not arbitrary library-preference bounds. + // Callers feed Uint8Array.length values here, so safe-integer rejection + // does not exclude any representable input even when an RFC bound is larger. + if (!Number.isSafeInteger(value) || min > value || value > max) { + const minmax = '[' + min + '..' + max + ']'; + throw new Error('' + name + ': expected value in range ' + minmax + ', got ' + value); + } +}; +/** + * **SIV** (Synthetic IV): GCM with nonce-misuse resistance. + * Repeating nonces reveal only the fact plaintexts are identical. + * Also suffers from GCM issues: key wear-out limits & MAC forging. + * See {@link https://www.rfc-editor.org/rfc/rfc8452 | RFC 8452}. + * RFC 8452 defines 16-byte and 32-byte AES keys for this mode. + * This implementation also accepts 24-byte AES-192 keys as a local + * extension; see the inline comment next to `validateKeyLength(key)` below + * for the exact scope note. + * @param key - AES key bytes. + * @param nonce - 12-byte nonce. + * @param AAD - Additional authenticated data. + * @returns AEAD cipher instance. + * @example + * Encrypts and authenticates plaintext with a fresh key and nonce, while tolerating reuse. + * + * ```ts + * import { gcmsiv } from '@noble/ciphers/aes.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(16); + * const nonce = randomBytes(12); + * const cipher = gcmsiv(key, nonce); + * cipher.encrypt(new Uint8Array([1, 2, 3])); + * ``` + */ +export const gcmsiv = /* @__PURE__ */ wrapCipher({ blockSize: 16, nonceLength: 12, tagLength: 16, varSizeNonce: true }, function aessiv(key, nonce, AAD) { + const tagLength = 16; + // From RFC 8452: Section 6 + const AAD_LIMIT = limit('AAD', 0, 2 ** 36); + const PLAIN_LIMIT = limit('plaintext', 0, 2 ** 36); + const NONCE_LIMIT = limit('nonce', 12, 12); + const CIPHER_LIMIT = limit('ciphertext', 16, 2 ** 36 + 16); + abytes(key); + // RFC 8452 only standardizes 16-byte and 32-byte key-generating keys. + // The accepted 24-byte path is a local AES-192 extension outside the RFC-defined AEADs. + validateKeyLength(key); + NONCE_LIMIT(nonce.length); + if (AAD !== undefined) + AAD_LIMIT(AAD.length); + function deriveKeys() { + const xk = expandKeyLE(key); + const encKey = new Uint8Array(key.length); + const authKey = new Uint8Array(16); + const toClean = [xk, encKey]; + let _nonce = nonce; + // Copy on BE or misaligned nonce so u32()/swap32IfBE() normalization + // never mutates caller nonce bytes before RFC 8452 key derivation. + if (!isLE || !isAligned32(_nonce)) + toClean.push((_nonce = copyBytes(_nonce))); + const n32 = u32(_nonce); + swap32IfBE(n32); + // prettier-ignore + let s0 = 0, s1 = n32[0], s2 = n32[1], s3 = n32[2]; + let counter = 0; + for (const derivedKey of [authKey, encKey].map(u32)) { + const d32 = u32(derivedKey); + for (let i = 0; i < d32.length; i += 2) { + // aes(u32le(0) || nonce)[:8] || aes(u32le(1) || nonce)[:8] ... + const { s0: o0, s1: o1 } = encrypt(xk, s0, s1, s2, s3); + d32[i + 0] = o0; + d32[i + 1] = o1; + s0 = ++counter; // increment counter inside state + } + swap32IfBE(d32); + } + const res = { authKey, encKey: expandKeyLE(encKey) }; + // Cleanup + clean(...toClean); + return res; + } + function _computeTag(encKey, authKey, data) { + const tag = computeTag(polyval, true, authKey, data, AAD); + // Compute the expected tag by XORing S_s and the nonce, clearing the + // most significant bit of the last byte and encrypting with the + // message-encryption key. + for (let i = 0; i < 12; i++) + tag[i] ^= nonce[i]; + tag[15] &= 0x7f; // Clear the highest bit + // encrypt tag as block + const t32 = u32(tag); + swap32IfBE(t32); + // prettier-ignore + let s0 = t32[0], s1 = t32[1], s2 = t32[2], s3 = t32[3]; + ({ s0, s1, s2, s3 } = encrypt(encKey, s0, s1, s2, s3)); + ((t32[0] = s0), (t32[1] = s1), (t32[2] = s2), (t32[3] = s3)); + swap32IfBE(t32); + return tag; + } + // actual decrypt/encrypt of message. + function processSiv(encKey, tag, input) { + let block = copyBytes(tag); + // RFC 8452 §4 / §5 use the tag with the highest bit of the last byte + // forced to one as the initial AES-CTR counter block. + block[15] |= 0x80; // Force highest bit + const res = ctr32(encKey, true, block, input); + // Cleanup + clean(block); + return res; + } + return { + encrypt(plaintext) { + PLAIN_LIMIT(plaintext.length); + const { encKey, authKey } = deriveKeys(); + const tag = _computeTag(encKey, authKey, plaintext); + const toClean = [encKey, authKey, tag]; + if (!isAligned32(plaintext)) + toClean.push((plaintext = copyBytes(plaintext))); + const out = new Uint8Array(plaintext.length + tagLength); + out.set(tag, plaintext.length); + out.set(processSiv(encKey, tag, plaintext)); + // Cleanup + clean(...toClean); + return out; + }, + decrypt(ciphertext) { + CIPHER_LIMIT(ciphertext.length); + const tag = ciphertext.subarray(-tagLength); + const { encKey, authKey } = deriveKeys(); + const toClean = [encKey, authKey]; + if (!isAligned32(ciphertext)) + toClean.push((ciphertext = copyBytes(ciphertext))); + const plaintext = processSiv(encKey, tag, ciphertext.subarray(0, -tagLength)); + const expectedTag = _computeTag(encKey, authKey, plaintext); + toClean.push(expectedTag); + // RFC 8452 §5: plaintext is unauthenticated here and MUST NOT be + // returned until the expected-tag check completes successfully. + if (!equalBytes(tag, expectedTag)) { + clean(...toClean); + throw new Error('invalid polyval tag'); + } + // Cleanup + clean(...toClean); + return plaintext; + }, + }; +}); +function isBytes32(a) { + // Plain `instanceof Uint32Array` is too strict for cross-realm expanded-key views. + // This is only a best-effort unsafe-export guard, not a provenance proof for `expandKeyLE`. + return (a instanceof Uint32Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint32Array')); +} +// Unsafe single-block helpers: mutate `block` in place and require its 16-byte +// Uint8Array view to be 4-byte aligned because `u32(block)` reinterprets it. +function encryptBlock(xk, block) { + abytes(block, 16, 'block'); + if (!isBytes32(xk)) + throw new Error('_encryptBlock accepts result of expandKeyLE'); + const b32 = u32(block); + swap32IfBE(b32); + let { s0, s1, s2, s3 } = encrypt(xk, b32[0], b32[1], b32[2], b32[3]); + ((b32[0] = s0), (b32[1] = s1), (b32[2] = s2), (b32[3] = s3)); + swap32IfBE(b32); + return block; +} +function decryptBlock(xk, block) { + abytes(block, 16, 'block'); + if (!isBytes32(xk)) + throw new Error('_decryptBlock accepts result of expandKeyLE'); + const b32 = u32(block); + swap32IfBE(b32); + let { s0, s1, s2, s3 } = decrypt(xk, b32[0], b32[1], b32[2], b32[3]); + ((b32[0] = s0), (b32[1] = s1), (b32[2] = s2), (b32[3] = s3)); + swap32IfBE(b32); + return block; +} +/** + * AES-W (base for AESKW/AESKWP). + * Specs: + * {@link https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38F.pdf | SP800-38F}, + * {@link https://www.rfc-editor.org/rfc/rfc3394 | RFC 3394}, + * {@link https://www.rfc-editor.org/rfc/rfc5649 | RFC 5649}. + * Shared core mutates `out` in place; callers are responsible for prepending + * the right IV/AIV and checking the recovered value after decrypt. + */ +const AESW = { + /* + High-level pseudocode: + ``` + A: u64 = IV + out = [] + for (let i=0, ctr = 0; i<6; i++) { + for (const chunk of chunks(plaintext, 8)) { + A ^= swapEndianess(ctr++) + [A, res] = chunks(encrypt(A || chunk), 8); + out ||= res + } + } + out = A || out + ``` + Decrypt is the same, but reversed. + */ + encrypt(kek, out) { + // Current implementation keeps RFC 3394/5649 `t` in a u32-shaped counter, + // so the shared core caps plaintext below 4 GiB even though the specs allow more. + if (out.length >= 2 ** 32) + throw new Error('plaintext should be less than 4gb'); + const xk = expandKeyLE(kek); + // 16-byte `S = A || P[1]` is the RFC 5649 KWP special case for n=1; + // KW callers never reach it because KW requires at least two plaintext semiblocks. + if (out.length === 16) + encryptBlock(xk, out); + else { + const o32 = u32(out); + swap32IfBE(o32); + // prettier-ignore + let a0 = o32[0], a1 = o32[1]; // A + for (let j = 0, ctr = 1; j < 6; j++) { + for (let pos = 2; pos < o32.length; pos += 2, ctr++) { + const { s0, s1, s2, s3 } = encrypt(xk, a0, a1, o32[pos], o32[pos + 1]); + // A = MSB(64, B) ^ t where t = (n*j)+i. Under the 32-bit length cap + // above, `t` fits in the low half of `[t]_64`, so xor only the low + // 32 bits of A after converting `ctr` to network order. + ((a0 = s0), (a1 = s1 ^ byteSwap(ctr)), (o32[pos] = s2), (o32[pos + 1] = s3)); + } + } + ((o32[0] = a0), (o32[1] = a1)); // out = A || out + swap32IfBE(o32); + } + xk.fill(0); + }, + decrypt(kek, out) { + // Same implementation cap on the recovered plaintext length after + // removing the 8-byte A/IV prefix. + if (out.length - 8 >= 2 ** 32) + throw new Error('ciphertext should be less than 4gb'); + const xk = expandKeyDecLE(kek); + const chunks = out.length / 8 - 1; // first chunk is IV + // `n = 2` semiblocks is the RFC 5649 KWP special case; KW ciphertexts + // always have at least three semiblocks and therefore use the W^-1 loop. + if (chunks === 1) + decryptBlock(xk, out); + else { + const o32 = u32(out); + swap32IfBE(o32); + // prettier-ignore + let a0 = o32[0], a1 = o32[1]; // A + for (let j = 0, ctr = chunks * 6; j < 6; j++) { + for (let pos = chunks * 2; pos >= 1; pos -= 2, ctr--) { + a1 ^= byteSwap(ctr); + const { s0, s1, s2, s3 } = decrypt(xk, a0, a1, o32[pos], o32[pos + 1]); + ((a0 = s0), (a1 = s1), (o32[pos] = s2), (o32[pos + 1] = s3)); + } + } + ((o32[0] = a0), (o32[1] = a1)); + swap32IfBE(o32); + } + xk.fill(0); + }, +}; +// RFC 3394 §2.2.3.1 / NIST SP 800-38F Algorithm 3 / Algorithm 4: KW prepends +// the default 64-bit ICV1 and unwrap must verify the same value. +const AESKW_IV = /* @__PURE__ */ new Uint8Array(8).fill(0xa6); // A6A6A6A6A6A6A6A6 +/** + * AES-KW (key-wrap). Injects static IV into plaintext, adds counter, encrypts 6 times. + * Reduces block size from 16 to 8 bytes. + * Plaintext must be a non-empty multiple of 8 bytes with minimum 16 bytes. + * 8-byte inputs use aeskwp. + * Wrapped ciphertext must be a multiple of 8 bytes with minimum 24 bytes. + * For padded version, use aeskwp. + * See {@link https://www.rfc-editor.org/rfc/rfc3394/ | RFC 3394} and + * {@link https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38F.pdf | NIST SP 800-38F}. + * @param kek - AES key-encryption key. + * @returns Key-wrap cipher instance. + * As with other `wrapCipher(...)` wrappers, `encrypt()` is single-use per + * instance. + * @example + * Wraps a 128-bit content-encryption key with a fresh key-encryption key. + * + * ```ts + * import { aeskw } from '@noble/ciphers/aes.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const kek = randomBytes(16); + * const cek = randomBytes(16); + * const wrap = aeskw(kek); + * wrap.encrypt(cek); + * ``` + */ +export const aeskw = /* @__PURE__ */ wrapCipher({ blockSize: 8 }, (kek) => ({ + encrypt(plaintext) { + if (!plaintext.length || plaintext.length % 8 !== 0) + throw new Error('invalid plaintext length'); + // RFC 3394 / NIST SP 800-38F define KW only for >=2 plaintext + // semiblocks; the 1-semiblock case belongs to RFC 5649 KWP. + if (plaintext.length === 8) + throw new Error('8-byte keys not allowed in AESKW, use AESKWP instead'); + const out = concatBytes(AESKW_IV, plaintext); + AESW.encrypt(kek, out); + return out; + }, + decrypt(ciphertext) { + // ciphertext must be at least 24 bytes and a multiple of 8 bytes + // 24 because should have at least two block (1 iv + 2). + // Replace with 16 to enable '8-byte keys' + if (ciphertext.length % 8 !== 0 || ciphertext.length < 3 * 8) + throw new Error('invalid ciphertext length'); + // AESW.decrypt() mutates its buffer in place, so keep caller ciphertext + // immutable across the unwrap, ICV1 check, and IV scrubbing below. + const out = copyBytes(ciphertext); + AESW.decrypt(kek, out); + if (!equalBytes(out.subarray(0, 8), AESKW_IV)) + throw new Error('integrity check failed'); + out.subarray(0, 8).fill(0); // ciphertext.subarray(0, 8) === IV, but we clean it anyway + return out.subarray(8); + }, +})); +/* +We don't support 8-byte keys. The rabbit hole: + +- Wycheproof says: "NIST SP 800-38F does not define the wrapping of 8 byte keys. + RFC 3394 Section 2 on the other hand specifies that 8 byte keys are wrapped + by directly encrypting one block with AES." + - {@link https://github.com/C2SP/wycheproof/blob/master/doc/key_wrap.md | Wycheproof key-wrap note} + - "RFC 3394 specifies in Section 2, that the input for the key wrap + algorithm must be at least two blocks and otherwise the constant + field and key are simply encrypted with ECB as a single block" +- What RFC 3394 actually says (in Section 2): + - "Before being wrapped, the key data is parsed into n blocks of 64 bits. + The only restriction the key wrap algorithm places on n is that n be + at least two" + - "For key data with length less than or equal to 64 bits, the constant + field used in this specification and the key data form a single + 128-bit codebook input making this key wrap unnecessary." +- Which means "assert(n >= 2)" and "use something else for 8 byte keys" +- NIST SP800-38F actually prohibits 8-byte in "5.3.1 Mandatory Limits". + It states that plaintext for KW should be "2 to 2^54 -1 semiblocks". +- So, where does "directly encrypt single block with AES" come from? + - Not RFC 3394. Pseudocode of key wrap in 2.2 explicitly uses + loop of 6 for any code path + - There is a weird W3C spec: + {@link https://www.w3.org/TR/2002/REC-xmlenc-core-20021210/Overview.html#kw-aes128 | XML Encryption AES key-wrap section} + - This spec is outdated, as admitted by Wycheproof authors + - There is RFC 5649 for padded key wrap, which is padding construction on + top of AESKW. In '4.1.2' it says: "If the padded plaintext contains exactly + eight octets, then prepend the AIV as defined in Section 3 above to P[1] and + encrypt the resulting 128-bit block using AES in ECB mode [Modes] with key + K (the KEK). In this case, the output is two 64-bit blocks C[0] and C[1]:" + - Browser subtle crypto is actually crashes on wrapping keys less than 16 bytes: + `Error: error:1C8000E6:Provider routines::invalid input length] + { opensslErrorStack: [ 'error:030000BD:digital envelope routines::update error' ]` + +In the end, seems like a bug in Wycheproof. +The 8-byte check can be easily disabled inside of AES_W. +*/ +// RFC 5649 §3 / NIST SP 800-38F Algorithm 5 / Algorithm 6: KWP uses ICV2 as +// the high 32 bits of the AIV; the low 32 bits carry the MLI in network order. +const AESKWP_IV = 0xa65959a6; // single u32le value +/** + * AES-KW, but with padding and allows random keys. + * Uses the RFC 5649 alternative initial value; the second u32 stores the + * 32-bit MLI in network order. + * Wrapped ciphertext must be at least 16 bytes; malformed lengths are + * rejected during AIV/padding checks. + * See {@link https://www.rfc-editor.org/rfc/rfc5649 | RFC 5649}. + * @param kek - AES key-encryption key. + * @returns Padded key-wrap cipher instance. + * @example + * Wraps a short key blob using the padded variant and a fresh key-encryption key. + * + * ```ts + * import { aeskwp } from '@noble/ciphers/aes.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const kek = randomBytes(16); + * const wrap = aeskwp(kek); + * wrap.encrypt(new Uint8Array([1, 2, 3])); + * ``` + */ +export const aeskwp = /* @__PURE__ */ wrapCipher({ blockSize: 8 }, (kek) => ({ + encrypt(plaintext) { + if (!plaintext.length) + throw new Error('invalid plaintext length'); + const padded = Math.ceil(plaintext.length / 8) * 8; + const out = new Uint8Array(8 + padded); + out.set(plaintext, 8); + const out32 = u32(out); + out32[0] = swap8IfBE(AESKWP_IV); + // RFC 5649 §3: the low 32 bits of the AIV carry the octet-length MLI in + // network order, even though this buffer is addressed through LE u32s. + out32[1] = swap8IfBE(byteSwap(plaintext.length)); + AESW.encrypt(kek, out); + return out; + }, + decrypt(ciphertext) { + // 16 because should have at least one block + if (ciphertext.length < 16) + throw new Error('invalid ciphertext length'); + // AESW.decrypt() mutates its buffer in place, so keep caller ciphertext + // immutable across the unwrap, AIV checks, and IV scrubbing below. + const out = copyBytes(ciphertext); + const o32 = u32(out); + AESW.decrypt(kek, out); + const len = byteSwap(swap8IfBE(o32[1])) >>> 0; + const padded = Math.ceil(len / 8) * 8; + if (swap8IfBE(o32[0]) !== AESKWP_IV || out.length - 8 !== padded) + throw new Error('integrity check failed'); + // RFC 5649 §3 / NIST SP 800-38F Algorithm 6: recovered padding length + // must be in [0,7], and every recovered pad octet must be zero. + for (let i = len; i < padded; i++) + if (out[8 + i] !== 0) + throw new Error('integrity check failed'); + out.subarray(0, 8).fill(0); // ciphertext.subarray(0, 8) === IV, but we clean it anyway + return out.subarray(8, 8 + len); + }, +})); +class _AesCtrDRBG { + blockLen; + key; + nonce; + state; + reseedCnt; + constructor(keyLen, seed, personalization) { + this.blockLen = ctr.blockSize; + const keyLenBytes = keyLen / 8; + const nonceLen = 16; + // Store the full seedlen state as key || V so CTR_DRBG_Update-style steps + // can rewrite the entire internal state in place. + this.state = new Uint8Array(keyLenBytes + nonceLen); + this.key = this.state.subarray(0, keyLenBytes); + this.nonce = this.state.subarray(keyLenBytes, keyLenBytes + nonceLen); + this.reseedCnt = 1; + // Keep the stored counter one step ahead of SP 800-90A's formal V so + // ctr(key, nonce) uses the next counter block directly. + incBytes(this.nonce, false, 1); + this.addEntropy(seed, personalization); + } + update(data) { + // cannot re-use state here, because we will wipe current key + ctr(this.key, this.nonce).encrypt(new Uint8Array(this.state.length), this.state); + if (data) { + abytes(data); + // CTR_DRBG without a derivation function pads shorter additional_input + // with zeros to seedlen, so XOR only the provided prefix here. + for (let i = 0; i < data.length; i++) + this.state[i] ^= data[i]; + } + // Keep storing V+1 so the next ctr(key, nonce) call starts from the + // spec's post-update counter state. + incBytes(this.nonce, false, 1); + } + // Optional `info` is additional input XORed into the reseed block and is + // limited to the internal state width. + addEntropy(seed, info) { + abytes(seed, this.state.length, 'seed'); + // Copy caller entropy before XORing in personalization/additional input, + // then wipe the mixed seed material after CTR_DRBG_Update consumes it. + const _seed = seed.slice(); + if (info) { + abytes(info); + if (info.length > _seed.length) + throw new Error('info length is too big'); + for (let i = 0; i < info.length; i++) + _seed[i] ^= info[i]; + } + this.update(_seed); + _seed.fill(0); + this.reseedCnt = 1; + } + // Optional `info` is additional input for the pre/post-update steps; bytes + // SP 800-90A Rev. 1 CTR_DRBG without a derivation function limits + // additional_input to seedlen, which is exactly this internal state width. + randomBytes(len, info) { + anumber(len); + // SP 800-90A Table 3 caps AES CTR_DRBG requests at 2^16 bits = 65536 bytes. + if (len > 2 ** 16) + throw new Error('requested output is too big'); + // The spec allows generate while reseed_counter == reseed_interval and increments afterwards. + if (this.reseedCnt > 2 ** 48) + throw new Error('entropy exhausted'); + if (info) { + abytes(info); + if (info.length > this.state.length) + throw new Error('info length is too big'); + this.update(info); + } + const res = new Uint8Array(len); + ctr(this.key, this.nonce).encrypt(res, res); + incBytes(this.nonce, false, Math.ceil(len / this.blockLen)); + this.update(info); + this.reseedCnt++; + return res; + } + // Zeroes the current state and resets the counter, but does not make the + // instance unusable: later calls continue from the zeroed state. + clean() { + // `key` and `nonce` alias this backing buffer, so one fill wipes the full + // secret state in place. + this.state.fill(0); + this.reseedCnt = 0; + } +} +// Internal helper for the exported 128-bit and 256-bit aliases; other key +// lengths are not validated here. +const createAesDrbg = (keyLen) => { + return (seed, personalization = undefined) => new _AesCtrDRBG(keyLen, seed, personalization); +}; +/** + * AES-CTR DRBG 128-bit - CSPRNG (cryptographically secure pseudorandom number generator). + * It's best to limit usage to non-production, non-critical cases: for example, test-only. + * @param seed - Initial 32-byte entropy input. + * @param personalization - Optional personalization string. + * @returns Seeded DRBG instance. The concrete methods also accept optional additional-input bytes. + * @example + * Seeds the test-only AES-CTR DRBG from fresh entropy and reads bytes from it. + * + * ```ts + * import { rngAesCtrDrbg128 } from '@noble/ciphers/aes.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const seed = randomBytes(32); + * const prg = rngAesCtrDrbg128(seed); + * prg.randomBytes(8); + * ``` + */ +export const rngAesCtrDrbg128 = /* @__PURE__ */ createAesDrbg(128); +/** + * AES-CTR DRBG 256-bit - CSPRNG (cryptographically secure pseudorandom number generator). + * It's best to limit usage to non-production, non-critical cases: for example, test-only. + * @param seed - Initial 48-byte entropy input. + * @param personalization - Optional personalization string. + * @returns Seeded DRBG instance. The concrete methods also accept optional additional-input bytes. + * @example + * Seeds the test-only AES-CTR DRBG from fresh entropy and reads bytes from it. + * + * ```ts + * import { rngAesCtrDrbg256 } from '@noble/ciphers/aes.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const seed = randomBytes(48); + * const prg = rngAesCtrDrbg256(seed); + * prg.randomBytes(8); + * ``` + */ +export const rngAesCtrDrbg256 = /* @__PURE__ */ createAesDrbg(256); +//#region CMAC +/** + * Left-shift by one bit and conditionally XOR with 0x87: + * ``` + * if MSB(L) is equal to 0 + * then K1 := L << 1; + * else K1 := (L << 1) XOR const_Rb; + * ``` + * + * Specs: + * {@link https://www.rfc-editor.org/rfc/rfc4493.html#section-2.3 | RFC 4493 Section 2.3}, + * {@link https://datatracker.ietf.org/doc/html/rfc5297.html#section-2.3 | RFC 5297 Section 2.3} + * + * @returns modified `block` (for chaining) + */ +function dbl(block) { + let carry = 0; + // Left shift by 1 bit + for (let i = BLOCK_SIZE - 1; i >= 0; i--) { + const newCarry = (block[i] & 0x80) >>> 7; + block[i] = (block[i] << 1) | carry; + carry = newCarry; + } + // XOR with 0x87 if there was a carry from the most significant bit + if (carry) { + // RFC 4493 §2.3 / RFC 5297 §2.1: 0x87 is const_Rb for doubling in the + // CMAC/S2V finite field with primitive polynomial x^128 + x^7 + x^2 + x + 1. + block[BLOCK_SIZE - 1] ^= 0x87; + } + return block; +} +/** + * `a XOR b`, running in-place on `a`. + * @param a left operand and output + * @param b right operand + * @returns `a` (for chaining) + */ +function xorBlock(a, b) { + if (a.length !== b.length) + throw new Error('xorBlock: blocks must have same length'); + for (let i = 0; i < a.length; i++) { + a[i] = a[i] ^ b[i]; + } + return a; +} +/** + * xorend as defined in + * {@link https://datatracker.ietf.org/doc/html/rfc5297.html#section-2.1 | RFC 5297 Section 2.1}. + * + * ``` + * leftmost(A, len(A)-len(B)) || (rightmost(A, len(B)) xor B) + * ``` + * + * Mutates `a` in place so the left prefix stays untouched and only the + * rightmost `len(B)` bytes are xored with `b`. + */ +function xorend(a, b) { + if (b.length > a.length) { + throw new Error('xorend: len(B) must be less than or equal to len(A)'); + } + // keep leftmost part of `a` unchanged + // and xor only the rightmost part: + const offset = a.length - b.length; + for (let i = 0; i < b.length; i++) { + a[offset + i] = a[offset + i] ^ b[i]; + } + return a; +} +/** + * Internal CMAC class. + */ +class _CMAC { + blockLen = BLOCK_SIZE; + outputLen = BLOCK_SIZE; + // CMAC can only decide between `K1` and `K2` once the true final block is known, + // so updates process older blocks eagerly but keep one pending block buffered. + buffer; + pos; + finished; + destroyed; + k1; + k2; + x; + xk; + constructor(key) { + abytes(key); + validateKeyLength(key); + this.xk = expandKeyLE(key); + this.buffer = new Uint8Array(BLOCK_SIZE); + this.pos = 0; + this.finished = false; + this.destroyed = false; + this.x = new Uint8Array(BLOCK_SIZE); + // L = AES_encrypt(K, const_Zero) + const L = new Uint8Array(BLOCK_SIZE); + encryptBlock(this.xk, L); + // Generate subkeys K1 and K2 from the main key according to + // {@link https://www.rfc-editor.org/rfc/rfc4493.html#section-2.3 | RFC 4493 Section 2.3} + // K1 + this.k1 = dbl(L); + this.k2 = dbl(new Uint8Array(this.k1)); + } + process(data) { + // RFC 4493 §2.4 step 6 loop body: Y := X XOR M_i; X := AES-128(K, Y). + xorBlock(this.x, data); + encryptBlock(this.xk, this.x); + } + update(data) { + if (this.destroyed) + throw new Error('Hash instance has been destroyed'); + if (this.finished) + throw new Error('Hash#digest() has already been called'); + abytes(data); + let pos = 0; + if (this.pos) { + const take = Math.min(BLOCK_SIZE - this.pos, data.length); + this.buffer.set(data.subarray(0, take), this.pos); + this.pos += take; + pos = take; + if (this.pos === BLOCK_SIZE && pos < data.length) { + this.process(this.buffer); + this.pos = 0; + } + } + // Keep one complete block buffered: an exact 16-byte tail may still be + // M_n, and digestInto() must decide there whether RFC 4493 uses K1 or K2. + while (pos + BLOCK_SIZE < data.length) { + this.process(data.subarray(pos, pos + BLOCK_SIZE)); + pos += BLOCK_SIZE; + } + if (pos < data.length) { + this.buffer.set(data.subarray(pos), 0); + this.pos = data.length - pos; + } + return this; + } + // See {@link https://www.rfc-editor.org/rfc/rfc4493.html#section-2.4 | RFC 4493 Section 2.4}. + digestInto(out) { + if (this.destroyed) + throw new Error('Hash instance has been destroyed'); + if (this.finished) + throw new Error('Hash#digest() has already been called'); + // `digestInto(out)` is the no-allocation fast path, so AES block re-use below + // requires a 32-bit-aligned caller buffer instead of hidden temp copies. + aoutput(out, this, true); + this.finished = true; + // `digestInto()` accepts out.length >= outputLen, so only the first block stores the tag. + const view = out.subarray(0, this.outputLen); + let last = new Uint8Array(BLOCK_SIZE); + if (this.pos === BLOCK_SIZE) { + // M_last := M_n XOR K1; + last.set(this.buffer); + xorBlock(last, this.k1); + } + else { + // M_last := padding(M_n) XOR K2; + // + // [...] padding(x) is the concatenation of x and a single '1', + // followed by the minimum number of '0's, so that the total length is + // equal to 128 bits. + last.set(this.buffer.subarray(0, this.pos)); + last[this.pos] = 0x80; // single '1' bit + xorBlock(last, this.k2); + } + view.set(this.x); // X := AES_CBC(K, M_1..M_{n-1}) + xorBlock(view, last); // Y := X XOR M_last + encryptBlock(this.xk, view); // T := AES-128(K, Y) + clean(last); + } + digest() { + const { buffer, outputLen } = this; + this.digestInto(buffer); + // Copy out before destroy() wipes the internal digest buffer in place. + const res = buffer.slice(0, outputLen); + this.destroy(); + return res; + } + destroy() { + const { buffer, destroyed, x, xk, k1, k2 } = this; + if (destroyed) + return; + this.destroyed = true; + // Wipe the buffered tail, chaining value, expanded AES key, and both CMAC subkeys. + clean(buffer, x, xk, k1, k2); + } +} +/** + * AES-CMAC (Cipher-based Message Authentication Code). + * Specs: {@link https://www.rfc-editor.org/rfc/rfc4493.html | RFC 4493}. + * @param msg - Message bytes to authenticate. + * @param key - AES key bytes. + * @returns 16-byte authentication tag. `cmac.create(...)` follows the same incremental MAC shape as + * the other keyed helpers in this repo, including `blockLen`, + * `outputLen`, `digestInto()` and `destroy()`. + * @example + * Authenticates a message with AES-CMAC and a fresh key. + * + * ```ts + * import { cmac } from '@noble/ciphers/aes.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(16); + * cmac(new Uint8Array(), key); + * ``` + */ +// The 16-byte probe key is only used to read static metadata; runtime CMAC +// still accepts AES-128/192/256 keys. +export const cmac = /* @__PURE__ */ wrapMacConstructor(16, (key) => new _CMAC(key)); +/** + * S2V (Synthetic Initialization Vector) function as described in + * {@link https://datatracker.ietf.org/doc/html/rfc5297.html#section-2.4 | RFC 5297 Section 2.4}. + * + * ``` + * S2V(K, S1, ..., Sn) { + * if n = 0 then + * return V = AES-CMAC(K, ) + * fi + * D = AES-CMAC(K, ) + * for i = 1 to n-1 do + * D = dbl(D) xor AES-CMAC(K, Si) + * done + * if len(Sn) >= 128 then + * T = Sn xorend D + * else + * T = dbl(D) xor pad(Sn) + * fi + * return V = AES-CMAC(K, T) + * } + * ``` + * + * S2V takes a key and a vector of strings S1, S2, ..., Sn and returns a 128-bit string. + * The S2V function is used to generate a synthetic IV for AES-SIV. + * + * @param key - AES key (128, 192, or 256 bits) + * @param strings - Array of byte arrays to process + * @returns 128-bit synthetic IV + */ +function s2v(key, strings) { + validateKeyLength(key); + const len = strings.length; + if (len > 127) { + // RFC 5297 §7 only proves S2V secure for at most 127 components; SIV + // spends one of those on the plaintext, leaving at most 126 AAD inputs. + throw new Error('s2v: number of input strings must be less than or equal to 127'); + } + if (len === 0) + return cmac(ONE_BLOCK, key); + // D = AES-CMAC(K, ) + let d = cmac(EMPTY_BLOCK, key); + // for i = 1 to n-1 do + // D = dbl(D) xor AES-CMAC(K, Si) + for (let i = 0; i < len - 1; i++) { + dbl(d); + const cmacResult = cmac(strings[i], key); + xorBlock(d, cmacResult); + clean(cmacResult); + } + const s_n = strings[len - 1]; + // Earlier components are validated through cmac(...); validate the final one explicitly because + // the Uint8Array.from()/set() paths below would otherwise coerce array-like inputs silently. + abytes(s_n); + let t; + // if len(Sn) >= 128 then + if (s_n.byteLength >= BLOCK_SIZE) { + // T = Sn xorend D + t = xorend(Uint8Array.from(s_n), d); + } + else { + // pad(Sn): + const paddedSn = new Uint8Array(BLOCK_SIZE); + paddedSn.set(s_n); + paddedSn[s_n.length] = 0x80; // padding: 0x80 followed by zeros + // T = dbl(D) xor pad(Sn) + t = xorBlock(dbl(d), paddedSn); + clean(paddedSn); + } + // V = AES-CMAC(K, T) + const result = cmac(t, key); + clean(d, t); + return result; +} +/** + * Use `gcmsiv` or `aessiv`. + * @returns Never; always throws with the migration hint. + * @throws If called; `siv()` is a removed v1 alias. {@link Error} + * @example + * `siv()` was removed in v2; use `gcmsiv()` for nonce-based SIV instead. + * + * ```ts + * import { gcmsiv } from '@noble/ciphers/aes.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(16); + * const nonce = randomBytes(12); + * const cipher = gcmsiv(key, nonce); + * cipher.encrypt(new Uint8Array([1, 2, 3])); + * ``` + */ +export const siv = () => { + throw new Error('"siv" from v1 is now "gcmsiv"'); +}; +/** + * **SIV**: Synthetic Initialization Vector (SIV) Authenticated Encryption + * Nonce is derived from the plaintext and AAD using the S2V function. + * Supports at most 126 AAD components. RFC 5297 nonce-based use is expressed by + * passing the nonce as the final AAD component before the plaintext. + * See {@link https://datatracker.ietf.org/doc/html/rfc5297.html | RFC 5297}. + * @param key - 32-byte, 48-byte, or 64-byte key. + * @param AAD - Additional authenticated data chunks (up to 126). + * @returns AEAD cipher instance. + * @example + * Authenticates and encrypts plaintext with a fresh key without requiring unique nonces. + * + * ```ts + * import { aessiv } from '@noble/ciphers/aes.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(32); + * const cipher = aessiv(key); + * cipher.encrypt(new Uint8Array([1, 2, 3])); + * ``` + */ +export const aessiv = /* @__PURE__ */ wrapCipher({ blockSize: 16, tagLength: 16 }, function aessiv(key, ...AAD) { + // From RFC 5297: Section 6.1, 6.2, 6.3: + const PLAIN_LIMIT = limit('plaintext', 0, 2 ** 132); + const CIPHER_LIMIT = limit('ciphertext', 16, 2 ** 132 + 16); + if (AAD.length > 126) { + // RFC 5297 §2.6 / §2.7 / §7: SIV passes the plaintext as the last S2V + // component, so callers only get 126 associated-data components. + throw new Error('"AAD" number of elements must be less than or equal to 126'); + } + AAD.forEach((aad) => abytes(aad)); + abytes(key); + if (![32, 48, 64].includes(key.length)) + throw new Error('"aes key" expected Uint8Array of length 32/48/64, got length=' + key.length); + // The key is split into equal halves, K1 = leftmost(K, len(K)/2) and + // K2 = rightmost(K, len(K)/2). K1 is used for S2V and K2 is used for CTR. + // This borrows caller key/AAD buffers by reference; mutating them after + // construction changes future encrypt/decrypt results. + const k1 = key.subarray(0, key.length / 2); + const k2 = key.subarray(key.length / 2); + return { + // {@link https://datatracker.ietf.org/doc/html/rfc5297.html#section-2.6 | RFC 5297 Section 2.6} + encrypt(plaintext) { + PLAIN_LIMIT(plaintext.length); + const v = s2v(k1, [...AAD, plaintext]); + // clear out the 31st and 63rd (rightmost) bit: + const q = Uint8Array.from(v); + q[8] &= 0x7f; + q[12] &= 0x7f; + // encrypt: + const c = ctr(k2, q).encrypt(plaintext); + return concatBytes(v, c); + }, + // {@link https://datatracker.ietf.org/doc/html/rfc5297.html#section-2.7 | RFC 5297 Section 2.7} + decrypt(ciphertext) { + CIPHER_LIMIT(ciphertext.length); + const v = ciphertext.subarray(0, BLOCK_SIZE); + const c = ciphertext.subarray(BLOCK_SIZE); + // clear out the 31st and 63rd (rightmost) bit: + const q = Uint8Array.from(v); + q[8] &= 0x7f; + q[12] &= 0x7f; + // decrypt: + const p = ctr(k2, q).decrypt(c); + // verify tag: + const t = s2v(k1, [...AAD, p]); + if (equalBytes(t, v)) { + return p; + } + else { + throw new Error('invalid siv tag'); + } + }, + }; +}); +//#endregion +/** + * Unsafe low-level internal methods. May change at any time. + * Callers are expected to use reviewed expanded-key outputs, pass mutable and + * aligned 16-byte blocks where required, and treat several helpers as in-place + * mutations of their input buffers or counters. + */ +export const unsafe = /* @__PURE__ */ Object.freeze({ + expandKeyLE, + expandKeyDecLE, + encrypt, + decrypt, + encryptBlock, + decryptBlock, + ctrCounter, + ctr32, + dbl, + xorBlock, + xorend, + s2v, +}); +export const __TESTS = /* @__PURE__ */ Object.freeze({ + incBytes: incBytes, +}); +//# sourceMappingURL=aes.js.map \ No newline at end of file diff --git a/node_modules/@noble/ciphers/aes.js.map b/node_modules/@noble/ciphers/aes.js.map new file mode 100644 index 0000000..3a71e27 --- /dev/null +++ b/node_modules/@noble/ciphers/aes.js.map @@ -0,0 +1 @@ +{"version":3,"file":"aes.js","sourceRoot":"","sources":["src/aes.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@noble/ciphers/chacha.d.ts b/node_modules/@noble/ciphers/chacha.d.ts new file mode 100644 index 0000000..55c5983 --- /dev/null +++ b/node_modules/@noble/ciphers/chacha.d.ts @@ -0,0 +1,249 @@ +/** + * ChaCha stream cipher, released + * in 2008. Developed after Salsa20, ChaCha aims to increase diffusion per round. + * It was standardized in + * {@link https://www.rfc-editor.org/rfc/rfc8439 | RFC 8439} and + * is now used in TLS 1.3. + * + * {@link https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha | XChaCha20} + * extended-nonce variant is also provided. Similar to XSalsa, it's safe to use with + * randomly-generated nonces. + * + * Check out + * {@link http://cr.yp.to/chacha/chacha-20080128.pdf | PDF}, + * {@link https://en.wikipedia.org/wiki/Salsa20 | wiki}, and + * {@link https://cr.yp.to/chacha.html | website}. + * + * @module + */ +import { type XorPRG } from './_arx.ts'; +import { type ARXCipher, type CipherWithOutput, type TArg, type TRet, type XorStream } from './utils.ts'; +/** Identical to `chachaCore`. Reached only through the test-only `__TESTS` export. */ +declare const chachaCore_small: typeof chachaCore; +/** RFC 8439 §2.3 block core for `state = constants | key | counter | nonce`. */ +declare function chachaCore(s: TArg, k: TArg, n: TArg, out: TArg, cnt: number, rounds?: number): void; +/** + * hchacha hashes key and nonce into key' and nonce' for xchacha20. + * Algorithmically identical to `hchacha_small`, but this exported path + * normalizes word order on big-endian hosts. + * Need to find a way to merge it with `chachaCore` without 25% performance hit. + * @param s - Sigma constants as 32-bit words. + * @param k - Key words. + * @param i - Nonce-prefix words. + * @param out - Output buffer for the derived subkey. + * @example + * Derives the XChaCha subkey from sigma, key, and nonce-prefix words. + * + * ```ts + * const sigma = new Uint32Array(4); + * const key = new Uint32Array(8); + * const nonce = new Uint32Array(4); + * const out = new Uint32Array(8); + * hchacha(sigma, key, nonce, out); + * ``` + */ +export declare function hchacha(s: TArg, k: TArg, i: TArg, out: TArg): void; +/** + * Original, non-RFC chacha20 from DJB. 8-byte nonce, 8-byte counter. + * The nonce/counter layout still reserves 8 counter bytes internally, but the shared public + * `counter` argument follows noble's strict non-wrapping 32-bit policy. See `src/_arx.ts` + * near `MAX_COUNTER` for the full counter-policy rationale. + * @param key - 16-byte or 32-byte key. + * @param nonce - 8-byte nonce. + * @param data - Input bytes to xor with the keystream. + * @param output - Optional destination buffer. + * @param counter - Initial block counter. + * @returns Encrypted or decrypted bytes. + * @example + * Encrypts bytes with the original 8-byte-nonce ChaCha variant and a fresh key/nonce. + * + * ```ts + * import { chacha20orig } from '@noble/ciphers/chacha.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(32); + * const nonce = randomBytes(8); + * chacha20orig(key, nonce, new Uint8Array(4)); + * ``` + */ +export declare const chacha20orig: TRet; +/** + * ChaCha stream cipher. Conforms to RFC 8439 (IETF, TLS). 12-byte nonce, 4-byte counter. + * With smaller nonce, it's not safe to make it random (CSPRNG), due to collision chance. + * @param key - 32-byte key. + * @param nonce - 12-byte nonce. + * @param data - Input bytes to xor with the keystream. + * @param output - Optional destination buffer. + * @param counter - Initial block counter. + * @returns Encrypted or decrypted bytes. + * @example + * Encrypts bytes with the RFC 8439 ChaCha20 stream cipher and a fresh key/nonce. + * + * ```ts + * import { chacha20 } from '@noble/ciphers/chacha.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(32); + * const nonce = randomBytes(12); + * chacha20(key, nonce, new Uint8Array(4)); + * ``` + */ +export declare const chacha20: TRet; +/** + * XChaCha eXtended-nonce ChaCha. With 24-byte nonce, it's safe to make it random (CSPRNG). + * See {@link https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha | the IRTF draft}. + * The nonce/counter layout still reserves 8 counter bytes internally, but the shared public + * `counter` argument follows noble's strict non-wrapping 32-bit policy. See `src/_arx.ts` + * near `MAX_COUNTER` for the full counter-policy rationale. + * @param key - 32-byte key. + * @param nonce - 24-byte extended nonce. + * @param data - Input bytes to xor with the keystream. + * @param output - Optional destination buffer. + * @param counter - Initial block counter. + * @returns Encrypted or decrypted bytes. + * @example + * Encrypts bytes with XChaCha20 using a fresh key and random 24-byte nonce. + * + * ```ts + * import { xchacha20 } from '@noble/ciphers/chacha.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(32); + * const nonce = randomBytes(24); + * xchacha20(key, nonce, new Uint8Array(4)); + * ``` + */ +export declare const xchacha20: TRet; +/** + * Reduced 8-round chacha, described in original paper. + * @param key - 32-byte key. + * @param nonce - 12-byte nonce. + * @param data - Input bytes to xor with the keystream. + * @param output - Optional destination buffer. + * @param counter - Initial block counter. + * @returns Encrypted or decrypted bytes. + * @example + * Uses the reduced 8-round variant for non-critical workloads with a fresh key/nonce. + * + * ```ts + * import { chacha8 } from '@noble/ciphers/chacha.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(32); + * const nonce = randomBytes(12); + * chacha8(key, nonce, new Uint8Array(4)); + * ``` + */ +export declare const chacha8: TRet; +/** + * Reduced 12-round chacha, described in original paper. + * @param key - 32-byte key. + * @param nonce - 12-byte nonce. + * @param data - Input bytes to xor with the keystream. + * @param output - Optional destination buffer. + * @param counter - Initial block counter. + * @returns Encrypted or decrypted bytes. + * @example + * Uses the reduced 12-round variant for non-critical workloads with a fresh key/nonce. + * + * ```ts + * import { chacha12 } from '@noble/ciphers/chacha.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(32); + * const nonce = randomBytes(12); + * chacha12(key, nonce, new Uint8Array(4)); + * ``` + */ +export declare const chacha12: TRet; +export declare const __TESTS: { + chachaCore_small: typeof chachaCore_small; + chachaCore: typeof chachaCore; +}; +/** + * AEAD algorithm from RFC 8439. + * Salsa20 and chacha (RFC 8439) use poly1305 differently. + * We could have composed them, but it's hard because of authKey: + * In salsa20, authKey changes position in salsa stream. + * In chacha, authKey can't be computed inside computeTag, it modifies the counter. + */ +export declare const _poly1305_aead: (xorStream: TArg) => (key: TArg, nonce: TArg, AAD?: TArg) => CipherWithOutput; +/** + * ChaCha20-Poly1305 from RFC 8439. + * + * Unsafe to use random nonces under the same key, due to collision chance. + * Prefer XChaCha instead. + * @param key - 32-byte key. + * @param nonce - 12-byte nonce. + * @param AAD - Additional authenticated data. + * @returns AEAD cipher instance. + * @example + * Encrypts and authenticates plaintext with a fresh key and nonce. + * + * ```ts + * import { chacha20poly1305 } from '@noble/ciphers/chacha.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(32); + * const nonce = randomBytes(12); + * const cipher = chacha20poly1305(key, nonce); + * cipher.encrypt(new Uint8Array([1, 2, 3])); + * ``` + */ +export declare const chacha20poly1305: TRet; +/** + * XChaCha20-Poly1305 extended-nonce chacha. + * + * Can be safely used with random nonces (CSPRNG). + * See {@link https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha | the IRTF draft}. + * @param key - 32-byte key. + * @param nonce - 24-byte nonce. + * @param AAD - Additional authenticated data. + * @returns AEAD cipher instance. + * @example + * Encrypts and authenticates plaintext with a fresh key and random 24-byte nonce. + * + * ```ts + * import { xchacha20poly1305 } from '@noble/ciphers/chacha.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(32); + * const nonce = randomBytes(24); + * const cipher = xchacha20poly1305(key, nonce); + * cipher.encrypt(new Uint8Array([1, 2, 3])); + * ``` + */ +export declare const xchacha20poly1305: TRet; +/** + * Chacha20 CSPRNG (cryptographically secure pseudorandom number generator). + * It's best to limit usage to non-production, non-critical cases: for example, test-only. + * Compatible with libtomcrypt. It does not have a specification, so unclear how secure it is. + * @param seed - Optional seed bytes mixed into the internal `key || nonce` state. When omitted, + * only 32 random bytes are mixed into the 40-byte state. + * @returns Seeded concrete `_XorStreamPRG` instance, including `clone()`. + * @example + * Seeds the test-only ChaCha20 DRBG from fresh entropy. + * + * ```ts + * import { rngChacha20 } from '@noble/ciphers/chacha.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const seed = randomBytes(32); + * const prg = rngChacha20(seed); + * prg.randomBytes(8); + * ``` + */ +export declare const rngChacha20: TRet; +/** + * Chacha20/8 CSPRNG (cryptographically secure pseudorandom number generator). + * It's best to limit usage to non-production, non-critical cases: for example, test-only. + * Faster than `rngChacha20`. + * @param seed - Optional seed bytes mixed into the internal `key || nonce` state. When omitted, + * only 32 random bytes are mixed into the 44-byte state. + * @returns Seeded concrete `_XorStreamPRG` instance, including `clone()`. + * @example + * Seeds the faster test-only ChaCha8 DRBG from fresh entropy. + * + * ```ts + * import { rngChacha8 } from '@noble/ciphers/chacha.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const seed = randomBytes(32); + * const prg = rngChacha8(seed); + * prg.randomBytes(8); + * ``` + */ +export declare const rngChacha8: TRet; +export {}; +//# sourceMappingURL=chacha.d.ts.map \ No newline at end of file diff --git a/node_modules/@noble/ciphers/chacha.d.ts.map b/node_modules/@noble/ciphers/chacha.d.ts.map new file mode 100644 index 0000000..4d37373 --- /dev/null +++ b/node_modules/@noble/ciphers/chacha.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"chacha.d.ts","sourceRoot":"","sources":["src/chacha.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,KAAK,MAAM,EAAiC,MAAM,WAAW,CAAC;AAEvE,OAAO,EACL,KAAK,SAAS,EACd,KAAK,gBAAgB,EACrB,KAAK,IAAI,EACT,KAAK,IAAI,EACT,KAAK,SAAS,EASf,MAAM,YAAY,CAAC;AAkEpB,sFAAsF;AAEtF,QAAA,MAAM,gBAAgB,EAAE,OAAO,UAE8C,CAAC;AAK9E,gFAAgF;AAEhF,iBAAS,UAAU,CACjB,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,WAAW,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,SAAK,GACjH,IAAI,CA6DN;AACD;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,wBAAgB,OAAO,CACrB,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,WAAW,CAAC,GACvF,IAAI,CAqDN;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,YAAY,EAAE,IAAI,CAAC,SAAS,CAIvC,CAAC;AACH;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,QAAQ,EAAE,IAAI,CAAC,SAAS,CAInC,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,SAAS,EAAE,IAAI,CAAC,SAAS,CAKpC,CAAC;AAEH;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,OAAO,EAAE,IAAI,CAAC,SAAS,CAIlC,CAAC;AAEH;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,QAAQ,EAAE,IAAI,CAAC,SAAS,CAInC,CAAC;AAGH,eAAO,MAAM,OAAO,EAAE;IACpB,gBAAgB,EAAE,OAAO,gBAAgB,CAAC;IAC1C,UAAU,EAAE,OAAO,UAAU,CAAC;CACmC,CAAC;AA0CpE;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,GACxB,WAAW,IAAI,CAAC,SAAS,CAAC,MAC1B,KAAK,IAAI,CAAC,UAAU,CAAC,EAAE,OAAO,IAAI,CAAC,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC,UAAU,CAAC,KAAG,gBA+CzE,CAAC;AAEJ;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,gBAAgB,EAAE,IAAI,CAAC,SAAS,CAG5C,CAAC;AACF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,iBAAiB,EAAE,IAAI,CAAC,SAAS,CAG7C,CAAC;AAEF;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,WAAW,EAAE,IAAI,CAAC,MAAM,CAAsD,CAAC;AAC5F;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,UAAU,EAAE,IAAI,CAAC,MAAM,CAAkD,CAAC"} \ No newline at end of file diff --git a/node_modules/@noble/ciphers/chacha.js b/node_modules/@noble/ciphers/chacha.js new file mode 100644 index 0000000..97ecca2 --- /dev/null +++ b/node_modules/@noble/ciphers/chacha.js @@ -0,0 +1,575 @@ +/** + * ChaCha stream cipher, released + * in 2008. Developed after Salsa20, ChaCha aims to increase diffusion per round. + * It was standardized in + * {@link https://www.rfc-editor.org/rfc/rfc8439 | RFC 8439} and + * is now used in TLS 1.3. + * + * {@link https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha | XChaCha20} + * extended-nonce variant is also provided. Similar to XSalsa, it's safe to use with + * randomly-generated nonces. + * + * Check out + * {@link http://cr.yp.to/chacha/chacha-20080128.pdf | PDF}, + * {@link https://en.wikipedia.org/wiki/Salsa20 | wiki}, and + * {@link https://cr.yp.to/chacha.html | website}. + * + * @module + */ +import { createCipher, createPRG, rotl } from "./_arx.js"; +import { poly1305 } from "./_poly1305.js"; +import { abytes, clean, equalBytes, getOutput, swap8IfBE, swap32IfBE, u64Lengths, wrapCipher, } from "./utils.js"; +/** + * ChaCha core function. It is implemented twice: + * 1. Simple loop (chachaCore_small, hchacha_small) + * 2. Unrolled loop (chachaCore, hchacha) - 4x faster, but larger & harder to read + * The specific implementation is selected in `createCipher` below. + */ +/** RFC 8439 §2.1 quarter round on words a, b, c, d. */ +// prettier-ignore +function chachaQR(x, a, b, c, d) { + x[a] = (x[a] + x[b]) | 0; + x[d] = rotl(x[d] ^ x[a], 16); + x[c] = (x[c] + x[d]) | 0; + x[b] = rotl(x[b] ^ x[c], 12); + x[a] = (x[a] + x[b]) | 0; + x[d] = rotl(x[d] ^ x[a], 8); + x[c] = (x[c] + x[d]) | 0; + x[b] = rotl(x[b] ^ x[c], 7); +} +/** Repeated ChaCha double rounds; callers are expected to pass an even round count. */ +function chachaRound(x, rounds = 20) { + for (let r = 0; r < rounds; r += 2) { + // RFC 8439 §2.3 / §2.3.1 inner_block: four column rounds, then four diagonal rounds. + chachaQR(x, 0, 4, 8, 12); + chachaQR(x, 1, 5, 9, 13); + chachaQR(x, 2, 6, 10, 14); + chachaQR(x, 3, 7, 11, 15); + chachaQR(x, 0, 5, 10, 15); + chachaQR(x, 1, 6, 11, 12); + chachaQR(x, 2, 7, 8, 13); + chachaQR(x, 3, 4, 9, 14); + } +} +// Shared scratch for the auditability-only helper below; only the test-only +// __TESTS.chachaCore_small hook reaches it, so production exports stay reentrant. +const ctmp = /* @__PURE__ */ new Uint32Array(16); +/** Small version of chacha without loop unrolling. Unused, provided for auditability. */ +// prettier-ignore +function chacha(s, k, i, out, isHChacha = true, rounds = 20) { + // `i` is either `[counter, nonce0, nonce1, nonce2]` for the ChaCha block + // function or the full 128-bit nonce prefix for the HChaCha subkey path. + // Create initial array using common pattern + const y = Uint32Array.from([ + s[0], s[1], s[2], s[3], // "expa" "nd 3" "2-by" "te k" + k[0], k[1], k[2], k[3], // Key Key Key Key + k[4], k[5], k[6], k[7], // Key Key Key Key + i[0], i[1], i[2], i[3], // Counter Counter Nonce Nonce + ]); + const x = ctmp; + x.set(y); + chachaRound(x, rounds); + // HChaCha writes words 0..3 and 12..15 after the rounds; the ChaCha + // block path adds the original state word-by-word. + if (isHChacha) { + const xindexes = [0, 1, 2, 3, 12, 13, 14, 15]; + for (let i = 0; i < 8; i++) + out[i] = x[xindexes[i]]; + } + else { + for (let i = 0; i < 16; i++) + out[i] = (y[i] + x[i]) | 0; + } +} +/** Identical to `chachaCore`. Reached only through the test-only `__TESTS` export. */ +// @ts-ignore +const chachaCore_small = (s, k, n, out, cnt, rounds) => +// Keep the reference wrapper on the same [counter, nonce0, nonce1, nonce2] layout as chacha(). +chacha(s, k, Uint32Array.from([cnt, n[0], n[1], n[2]]), out, false, rounds); +/** Identical to `hchacha`. Unused. */ +// @ts-ignore +const hchacha_small = chacha; +/** RFC 8439 §2.3 block core for `state = constants | key | counter | nonce`. */ +// prettier-ignore +function chachaCore(s, k, n, out, cnt, rounds = 20) { + let y00 = s[0], y01 = s[1], y02 = s[2], y03 = s[3], // "expa" "nd 3" "2-by" "te k" + y04 = k[0], y05 = k[1], y06 = k[2], y07 = k[3], // Key Key Key Key + y08 = k[4], y09 = k[5], y10 = k[6], y11 = k[7], // Key Key Key Key + y12 = cnt, y13 = n[0], y14 = n[1], y15 = n[2]; // Counter Nonce Nonce Nonce + // Save state to temporary variables + let x00 = y00, x01 = y01, x02 = y02, x03 = y03, x04 = y04, x05 = y05, x06 = y06, x07 = y07, x08 = y08, x09 = y09, x10 = y10, x11 = y11, x12 = y12, x13 = y13, x14 = y14, x15 = y15; + for (let r = 0; r < rounds; r += 2) { + x00 = (x00 + x04) | 0; + x12 = rotl(x12 ^ x00, 16); + x08 = (x08 + x12) | 0; + x04 = rotl(x04 ^ x08, 12); + x00 = (x00 + x04) | 0; + x12 = rotl(x12 ^ x00, 8); + x08 = (x08 + x12) | 0; + x04 = rotl(x04 ^ x08, 7); + x01 = (x01 + x05) | 0; + x13 = rotl(x13 ^ x01, 16); + x09 = (x09 + x13) | 0; + x05 = rotl(x05 ^ x09, 12); + x01 = (x01 + x05) | 0; + x13 = rotl(x13 ^ x01, 8); + x09 = (x09 + x13) | 0; + x05 = rotl(x05 ^ x09, 7); + x02 = (x02 + x06) | 0; + x14 = rotl(x14 ^ x02, 16); + x10 = (x10 + x14) | 0; + x06 = rotl(x06 ^ x10, 12); + x02 = (x02 + x06) | 0; + x14 = rotl(x14 ^ x02, 8); + x10 = (x10 + x14) | 0; + x06 = rotl(x06 ^ x10, 7); + x03 = (x03 + x07) | 0; + x15 = rotl(x15 ^ x03, 16); + x11 = (x11 + x15) | 0; + x07 = rotl(x07 ^ x11, 12); + x03 = (x03 + x07) | 0; + x15 = rotl(x15 ^ x03, 8); + x11 = (x11 + x15) | 0; + x07 = rotl(x07 ^ x11, 7); + x00 = (x00 + x05) | 0; + x15 = rotl(x15 ^ x00, 16); + x10 = (x10 + x15) | 0; + x05 = rotl(x05 ^ x10, 12); + x00 = (x00 + x05) | 0; + x15 = rotl(x15 ^ x00, 8); + x10 = (x10 + x15) | 0; + x05 = rotl(x05 ^ x10, 7); + x01 = (x01 + x06) | 0; + x12 = rotl(x12 ^ x01, 16); + x11 = (x11 + x12) | 0; + x06 = rotl(x06 ^ x11, 12); + x01 = (x01 + x06) | 0; + x12 = rotl(x12 ^ x01, 8); + x11 = (x11 + x12) | 0; + x06 = rotl(x06 ^ x11, 7); + x02 = (x02 + x07) | 0; + x13 = rotl(x13 ^ x02, 16); + x08 = (x08 + x13) | 0; + x07 = rotl(x07 ^ x08, 12); + x02 = (x02 + x07) | 0; + x13 = rotl(x13 ^ x02, 8); + x08 = (x08 + x13) | 0; + x07 = rotl(x07 ^ x08, 7); + x03 = (x03 + x04) | 0; + x14 = rotl(x14 ^ x03, 16); + x09 = (x09 + x14) | 0; + x04 = rotl(x04 ^ x09, 12); + x03 = (x03 + x04) | 0; + x14 = rotl(x14 ^ x03, 8); + x09 = (x09 + x14) | 0; + x04 = rotl(x04 ^ x09, 7); + } + // RFC 8439 §2.3 / §2.3.1: add the original state words back in state order. + let oi = 0; + out[oi++] = (y00 + x00) | 0; + out[oi++] = (y01 + x01) | 0; + out[oi++] = (y02 + x02) | 0; + out[oi++] = (y03 + x03) | 0; + out[oi++] = (y04 + x04) | 0; + out[oi++] = (y05 + x05) | 0; + out[oi++] = (y06 + x06) | 0; + out[oi++] = (y07 + x07) | 0; + out[oi++] = (y08 + x08) | 0; + out[oi++] = (y09 + x09) | 0; + out[oi++] = (y10 + x10) | 0; + out[oi++] = (y11 + x11) | 0; + out[oi++] = (y12 + x12) | 0; + out[oi++] = (y13 + x13) | 0; + out[oi++] = (y14 + x14) | 0; + out[oi++] = (y15 + x15) | 0; +} +/** + * hchacha hashes key and nonce into key' and nonce' for xchacha20. + * Algorithmically identical to `hchacha_small`, but this exported path + * normalizes word order on big-endian hosts. + * Need to find a way to merge it with `chachaCore` without 25% performance hit. + * @param s - Sigma constants as 32-bit words. + * @param k - Key words. + * @param i - Nonce-prefix words. + * @param out - Output buffer for the derived subkey. + * @example + * Derives the XChaCha subkey from sigma, key, and nonce-prefix words. + * + * ```ts + * const sigma = new Uint32Array(4); + * const key = new Uint32Array(8); + * const nonce = new Uint32Array(4); + * const out = new Uint32Array(8); + * hchacha(sigma, key, nonce, out); + * ``` + */ +// prettier-ignore +export function hchacha(s, k, i, out) { + let x00 = swap8IfBE(s[0]), x01 = swap8IfBE(s[1]), x02 = swap8IfBE(s[2]), x03 = swap8IfBE(s[3]), x04 = swap8IfBE(k[0]), x05 = swap8IfBE(k[1]), x06 = swap8IfBE(k[2]), x07 = swap8IfBE(k[3]), x08 = swap8IfBE(k[4]), x09 = swap8IfBE(k[5]), x10 = swap8IfBE(k[6]), x11 = swap8IfBE(k[7]), x12 = swap8IfBE(i[0]), x13 = swap8IfBE(i[1]), x14 = swap8IfBE(i[2]), x15 = swap8IfBE(i[3]); + for (let r = 0; r < 20; r += 2) { + x00 = (x00 + x04) | 0; + x12 = rotl(x12 ^ x00, 16); + x08 = (x08 + x12) | 0; + x04 = rotl(x04 ^ x08, 12); + x00 = (x00 + x04) | 0; + x12 = rotl(x12 ^ x00, 8); + x08 = (x08 + x12) | 0; + x04 = rotl(x04 ^ x08, 7); + x01 = (x01 + x05) | 0; + x13 = rotl(x13 ^ x01, 16); + x09 = (x09 + x13) | 0; + x05 = rotl(x05 ^ x09, 12); + x01 = (x01 + x05) | 0; + x13 = rotl(x13 ^ x01, 8); + x09 = (x09 + x13) | 0; + x05 = rotl(x05 ^ x09, 7); + x02 = (x02 + x06) | 0; + x14 = rotl(x14 ^ x02, 16); + x10 = (x10 + x14) | 0; + x06 = rotl(x06 ^ x10, 12); + x02 = (x02 + x06) | 0; + x14 = rotl(x14 ^ x02, 8); + x10 = (x10 + x14) | 0; + x06 = rotl(x06 ^ x10, 7); + x03 = (x03 + x07) | 0; + x15 = rotl(x15 ^ x03, 16); + x11 = (x11 + x15) | 0; + x07 = rotl(x07 ^ x11, 12); + x03 = (x03 + x07) | 0; + x15 = rotl(x15 ^ x03, 8); + x11 = (x11 + x15) | 0; + x07 = rotl(x07 ^ x11, 7); + x00 = (x00 + x05) | 0; + x15 = rotl(x15 ^ x00, 16); + x10 = (x10 + x15) | 0; + x05 = rotl(x05 ^ x10, 12); + x00 = (x00 + x05) | 0; + x15 = rotl(x15 ^ x00, 8); + x10 = (x10 + x15) | 0; + x05 = rotl(x05 ^ x10, 7); + x01 = (x01 + x06) | 0; + x12 = rotl(x12 ^ x01, 16); + x11 = (x11 + x12) | 0; + x06 = rotl(x06 ^ x11, 12); + x01 = (x01 + x06) | 0; + x12 = rotl(x12 ^ x01, 8); + x11 = (x11 + x12) | 0; + x06 = rotl(x06 ^ x11, 7); + x02 = (x02 + x07) | 0; + x13 = rotl(x13 ^ x02, 16); + x08 = (x08 + x13) | 0; + x07 = rotl(x07 ^ x08, 12); + x02 = (x02 + x07) | 0; + x13 = rotl(x13 ^ x02, 8); + x08 = (x08 + x13) | 0; + x07 = rotl(x07 ^ x08, 7); + x03 = (x03 + x04) | 0; + x14 = rotl(x14 ^ x03, 16); + x09 = (x09 + x14) | 0; + x04 = rotl(x04 ^ x09, 12); + x03 = (x03 + x04) | 0; + x14 = rotl(x14 ^ x03, 8); + x09 = (x09 + x14) | 0; + x04 = rotl(x04 ^ x09, 7); + } + // HChaCha derives the subkey from state words 0..3 and 12..15 after 20 rounds. + let oi = 0; + out[oi++] = x00; + out[oi++] = x01; + out[oi++] = x02; + out[oi++] = x03; + out[oi++] = x12; + out[oi++] = x13; + out[oi++] = x14; + out[oi++] = x15; + swap32IfBE(out); +} +/** + * Original, non-RFC chacha20 from DJB. 8-byte nonce, 8-byte counter. + * The nonce/counter layout still reserves 8 counter bytes internally, but the shared public + * `counter` argument follows noble's strict non-wrapping 32-bit policy. See `src/_arx.ts` + * near `MAX_COUNTER` for the full counter-policy rationale. + * @param key - 16-byte or 32-byte key. + * @param nonce - 8-byte nonce. + * @param data - Input bytes to xor with the keystream. + * @param output - Optional destination buffer. + * @param counter - Initial block counter. + * @returns Encrypted or decrypted bytes. + * @example + * Encrypts bytes with the original 8-byte-nonce ChaCha variant and a fresh key/nonce. + * + * ```ts + * import { chacha20orig } from '@noble/ciphers/chacha.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(32); + * const nonce = randomBytes(8); + * chacha20orig(key, nonce, new Uint8Array(4)); + * ``` + */ +export const chacha20orig = /* @__PURE__ */ createCipher(chachaCore, { + counterRight: false, + counterLength: 8, + allowShortKeys: true, +}); +/** + * ChaCha stream cipher. Conforms to RFC 8439 (IETF, TLS). 12-byte nonce, 4-byte counter. + * With smaller nonce, it's not safe to make it random (CSPRNG), due to collision chance. + * @param key - 32-byte key. + * @param nonce - 12-byte nonce. + * @param data - Input bytes to xor with the keystream. + * @param output - Optional destination buffer. + * @param counter - Initial block counter. + * @returns Encrypted or decrypted bytes. + * @example + * Encrypts bytes with the RFC 8439 ChaCha20 stream cipher and a fresh key/nonce. + * + * ```ts + * import { chacha20 } from '@noble/ciphers/chacha.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(32); + * const nonce = randomBytes(12); + * chacha20(key, nonce, new Uint8Array(4)); + * ``` + */ +export const chacha20 = /* @__PURE__ */ createCipher(chachaCore, { + counterRight: false, + counterLength: 4, + allowShortKeys: false, +}); +/** + * XChaCha eXtended-nonce ChaCha. With 24-byte nonce, it's safe to make it random (CSPRNG). + * See {@link https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha | the IRTF draft}. + * The nonce/counter layout still reserves 8 counter bytes internally, but the shared public + * `counter` argument follows noble's strict non-wrapping 32-bit policy. See `src/_arx.ts` + * near `MAX_COUNTER` for the full counter-policy rationale. + * @param key - 32-byte key. + * @param nonce - 24-byte extended nonce. + * @param data - Input bytes to xor with the keystream. + * @param output - Optional destination buffer. + * @param counter - Initial block counter. + * @returns Encrypted or decrypted bytes. + * @example + * Encrypts bytes with XChaCha20 using a fresh key and random 24-byte nonce. + * + * ```ts + * import { xchacha20 } from '@noble/ciphers/chacha.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(32); + * const nonce = randomBytes(24); + * xchacha20(key, nonce, new Uint8Array(4)); + * ``` + */ +export const xchacha20 = /* @__PURE__ */ createCipher(chachaCore, { + counterRight: false, + counterLength: 8, + extendNonceFn: hchacha, + allowShortKeys: false, +}); +/** + * Reduced 8-round chacha, described in original paper. + * @param key - 32-byte key. + * @param nonce - 12-byte nonce. + * @param data - Input bytes to xor with the keystream. + * @param output - Optional destination buffer. + * @param counter - Initial block counter. + * @returns Encrypted or decrypted bytes. + * @example + * Uses the reduced 8-round variant for non-critical workloads with a fresh key/nonce. + * + * ```ts + * import { chacha8 } from '@noble/ciphers/chacha.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(32); + * const nonce = randomBytes(12); + * chacha8(key, nonce, new Uint8Array(4)); + * ``` + */ +export const chacha8 = /* @__PURE__ */ createCipher(chachaCore, { + counterRight: false, + counterLength: 4, + rounds: 8, +}); +/** + * Reduced 12-round chacha, described in original paper. + * @param key - 32-byte key. + * @param nonce - 12-byte nonce. + * @param data - Input bytes to xor with the keystream. + * @param output - Optional destination buffer. + * @param counter - Initial block counter. + * @returns Encrypted or decrypted bytes. + * @example + * Uses the reduced 12-round variant for non-critical workloads with a fresh key/nonce. + * + * ```ts + * import { chacha12 } from '@noble/ciphers/chacha.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(32); + * const nonce = randomBytes(12); + * chacha12(key, nonce, new Uint8Array(4)); + * ``` + */ +export const chacha12 = /* @__PURE__ */ createCipher(chachaCore, { + counterRight: false, + counterLength: 4, + rounds: 12, +}); +// Test-only hooks for keeping the simple/reference core aligned with the unrolled production core. +export const __TESTS = /* @__PURE__ */ Object.freeze({ chachaCore_small, chachaCore }); +// RFC 8439 §2.8.1 pad16(x): shared zero block for AAD/ciphertext padding. +const ZEROS16 = /* @__PURE__ */ new Uint8Array(16); +// RFC 8439 §2.8 / §2.8.1: aligned inputs add nothing, otherwise append 16-(len%16) zero bytes. +const updatePadded = (h, msg) => { + h.update(msg); + const leftover = msg.length % 16; + if (leftover) + h.update(ZEROS16.subarray(leftover)); +}; +// RFC 8439 §2.6.1 poly1305_key_gen returns `block[0..31]`, so AEAD key +// generation only needs 32 zero bytes. +const ZEROS32 = /* @__PURE__ */ new Uint8Array(32); +function computeTag(fn, key, nonce, ciphertext, AAD) { + if (AAD !== undefined) + abytes(AAD, undefined, 'AAD'); + // RFC 8439 §2.6 / §2.8: derive the Poly1305 one-time key from counter 0, + // then MAC AAD || pad16(AAD) || ciphertext || pad16(ciphertext) || len(AAD) || len(ciphertext). + const authKey = fn(key, nonce, ZEROS32); + const lengths = u64Lengths(ciphertext.length, AAD ? AAD.length : 0, true); + // Methods below can be replaced with + // return poly1305_computeTag_small(authKey, lengths, ciphertext, AAD) + const h = poly1305.create(authKey); + if (AAD) + updatePadded(h, AAD); + updatePadded(h, ciphertext); + h.update(lengths); + const res = h.digest(); + clean(authKey, lengths); + return res; +} +/** + * AEAD algorithm from RFC 8439. + * Salsa20 and chacha (RFC 8439) use poly1305 differently. + * We could have composed them, but it's hard because of authKey: + * In salsa20, authKey changes position in salsa stream. + * In chacha, authKey can't be computed inside computeTag, it modifies the counter. + */ +export const _poly1305_aead = (xorStream) => (key, nonce, AAD) => { + // This borrows caller key/nonce/AAD buffers by reference; mutating them after construction + // changes future encrypt/decrypt results. + const tagLength = 16; + return { + encrypt(plaintext, output) { + const plength = plaintext.length; + output = getOutput(plength + tagLength, output, false); + output.set(plaintext); + const oPlain = output.subarray(0, -tagLength); + // RFC 8439 §2.8: payload encryption starts at counter 1 because counter 0 produced the OTK. + xorStream(key, nonce, oPlain, oPlain, 1); + const tag = computeTag(xorStream, key, nonce, oPlain, AAD); + output.set(tag, plength); // append tag + clean(tag); + return output; + }, + decrypt(ciphertext, output) { + output = getOutput(ciphertext.length - tagLength, output, false); + const data = ciphertext.subarray(0, -tagLength); + const passedTag = ciphertext.subarray(-tagLength); + const tag = computeTag(xorStream, key, nonce, data, AAD); + // RFC 8439 §2.8 / §4: authenticate ciphertext before decrypting it, and compare tags with + // the constant-time equalBytes() helper rather than decrypting speculative plaintext first. + if (!equalBytes(passedTag, tag)) { + clean(tag); + throw new Error('invalid tag'); + } + output.set(ciphertext.subarray(0, -tagLength)); + // Actual decryption + xorStream(key, nonce, output, output, 1); // start stream with i=1 + clean(tag); + return output; + }, + }; +}; +/** + * ChaCha20-Poly1305 from RFC 8439. + * + * Unsafe to use random nonces under the same key, due to collision chance. + * Prefer XChaCha instead. + * @param key - 32-byte key. + * @param nonce - 12-byte nonce. + * @param AAD - Additional authenticated data. + * @returns AEAD cipher instance. + * @example + * Encrypts and authenticates plaintext with a fresh key and nonce. + * + * ```ts + * import { chacha20poly1305 } from '@noble/ciphers/chacha.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(32); + * const nonce = randomBytes(12); + * const cipher = chacha20poly1305(key, nonce); + * cipher.encrypt(new Uint8Array([1, 2, 3])); + * ``` + */ +export const chacha20poly1305 = /* @__PURE__ */ wrapCipher({ blockSize: 64, nonceLength: 12, tagLength: 16 }, +/* @__PURE__ */ _poly1305_aead(chacha20)); +/** + * XChaCha20-Poly1305 extended-nonce chacha. + * + * Can be safely used with random nonces (CSPRNG). + * See {@link https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha | the IRTF draft}. + * @param key - 32-byte key. + * @param nonce - 24-byte nonce. + * @param AAD - Additional authenticated data. + * @returns AEAD cipher instance. + * @example + * Encrypts and authenticates plaintext with a fresh key and random 24-byte nonce. + * + * ```ts + * import { xchacha20poly1305 } from '@noble/ciphers/chacha.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(32); + * const nonce = randomBytes(24); + * const cipher = xchacha20poly1305(key, nonce); + * cipher.encrypt(new Uint8Array([1, 2, 3])); + * ``` + */ +export const xchacha20poly1305 = /* @__PURE__ */ wrapCipher({ blockSize: 64, nonceLength: 24, tagLength: 16 }, +/* @__PURE__ */ _poly1305_aead(xchacha20)); +/** + * Chacha20 CSPRNG (cryptographically secure pseudorandom number generator). + * It's best to limit usage to non-production, non-critical cases: for example, test-only. + * Compatible with libtomcrypt. It does not have a specification, so unclear how secure it is. + * @param seed - Optional seed bytes mixed into the internal `key || nonce` state. When omitted, + * only 32 random bytes are mixed into the 40-byte state. + * @returns Seeded concrete `_XorStreamPRG` instance, including `clone()`. + * @example + * Seeds the test-only ChaCha20 DRBG from fresh entropy. + * + * ```ts + * import { rngChacha20 } from '@noble/ciphers/chacha.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const seed = randomBytes(32); + * const prg = rngChacha20(seed); + * prg.randomBytes(8); + * ``` + */ +export const rngChacha20 = /* @__PURE__ */ createPRG(chacha20orig, 64, 32, 8); +/** + * Chacha20/8 CSPRNG (cryptographically secure pseudorandom number generator). + * It's best to limit usage to non-production, non-critical cases: for example, test-only. + * Faster than `rngChacha20`. + * @param seed - Optional seed bytes mixed into the internal `key || nonce` state. When omitted, + * only 32 random bytes are mixed into the 44-byte state. + * @returns Seeded concrete `_XorStreamPRG` instance, including `clone()`. + * @example + * Seeds the faster test-only ChaCha8 DRBG from fresh entropy. + * + * ```ts + * import { rngChacha8 } from '@noble/ciphers/chacha.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const seed = randomBytes(32); + * const prg = rngChacha8(seed); + * prg.randomBytes(8); + * ``` + */ +export const rngChacha8 = /* @__PURE__ */ createPRG(chacha8, 64, 32, 12); +//# sourceMappingURL=chacha.js.map \ No newline at end of file diff --git a/node_modules/@noble/ciphers/chacha.js.map b/node_modules/@noble/ciphers/chacha.js.map new file mode 100644 index 0000000..349a252 --- /dev/null +++ b/node_modules/@noble/ciphers/chacha.js.map @@ -0,0 +1 @@ +{"version":3,"file":"chacha.js","sourceRoot":"","sources":["src/chacha.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAe,YAAY,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACvE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAML,MAAM,EACN,KAAK,EACL,UAAU,EACV,SAAS,EACT,SAAS,EACT,UAAU,EACV,UAAU,EACV,UAAU,GACX,MAAM,YAAY,CAAC;AAEpB;;;;;GAKG;AAEH,uDAAuD;AACvD,kBAAkB;AAClB,SAAS,QAAQ,CAAC,CAAoB,EAAE,CAAS,EAAE,CAAS,EAAE,CAAS,EAAE,CAAS;IAChF,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACxD,CAAC;AAED,uFAAuF;AACvF,SAAS,WAAW,CAAC,CAAoB,EAAE,MAAM,GAAG,EAAE;IACpD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,qFAAqF;QACrF,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QACzB,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QACzB,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;QAC1B,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;QAC1B,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;QAC1B,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;QAC1B,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QACzB,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;IAC3B,CAAC;AACH,CAAC;AAED,4EAA4E;AAC5E,kFAAkF;AAClF,MAAM,IAAI,GAAG,eAAe,CAAC,IAAI,WAAW,CAAC,EAAE,CAAC,CAAC;AAEjD,yFAAyF;AACzF,kBAAkB;AAClB,SAAS,MAAM,CACb,CAAoB,EAAE,CAAoB,EAAE,CAAoB,EAAE,GAAsB,EACxF,YAAqB,IAAI,EAAE,SAAiB,EAAE;IAE9C,yEAAyE;IACzE,yEAAyE;IACzE,4CAA4C;IAC5C,MAAM,CAAC,GAAG,WAAW,CAAC,IAAI,CAAC;QACzB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,kCAAkC;QAC1D,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,+BAA+B;QACvD,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,+BAA+B;QACvD,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,iCAAiC;KAC1D,CAAC,CAAC;IACH,MAAM,CAAC,GAAG,IAAI,CAAC;IACf,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACT,WAAW,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IAEvB,oEAAoE;IACpE,mDAAmD;IACnD,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,QAAQ,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;QAC9C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;YAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IACtD,CAAC;SAAM,CAAC;QACN,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE;YAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAC1D,CAAC;AACH,CAAC;AAED,sFAAsF;AACtF,aAAa;AACb,MAAM,gBAAgB,GAAsB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE;AACxE,+FAA+F;AAC/F,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;AAC9E,sCAAsC;AACtC,aAAa;AACb,MAAM,aAAa,GAAmB,MAAM,CAAC;AAE7C,gFAAgF;AAChF,kBAAkB;AAClB,SAAS,UAAU,CACjB,CAAoB,EAAE,CAAoB,EAAE,CAAoB,EAAE,GAAsB,EAAE,GAAW,EAAE,MAAM,GAAG,EAAE;IAElH,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,kCAAkC;IAClF,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,+BAA+B;IAC/E,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,+BAA+B;IAC/E,GAAG,GAAG,GAAG,EAAG,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,iCAAiC;IACtF,oCAAoC;IACpC,IAAI,GAAG,GAAG,GAAG,EAAE,GAAG,GAAG,GAAG,EAAE,GAAG,GAAG,GAAG,EAAE,GAAG,GAAG,GAAG,EAC1C,GAAG,GAAG,GAAG,EAAE,GAAG,GAAG,GAAG,EAAE,GAAG,GAAG,GAAG,EAAE,GAAG,GAAG,GAAG,EAC1C,GAAG,GAAG,GAAG,EAAE,GAAG,GAAG,GAAG,EAAE,GAAG,GAAG,GAAG,EAAE,GAAG,GAAG,GAAG,EAC1C,GAAG,GAAG,GAAG,EAAE,GAAG,GAAG,GAAG,EAAE,GAAG,GAAG,GAAG,EAAE,GAAG,GAAG,GAAG,CAAC;IAC/C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,EAAE,CAAC,CAAC;QACjD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,EAAE,CAAC,CAAC;QACjD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC;QAChD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC;QAEhD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,EAAE,CAAC,CAAC;QACjD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,EAAE,CAAC,CAAC;QACjD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC;QAChD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC;QAEhD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,EAAE,CAAC,CAAC;QACjD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,EAAE,CAAC,CAAC;QACjD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC;QAChD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC;QAEhD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,EAAE,CAAC,CAAC;QACjD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,EAAE,CAAC,CAAC;QACjD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC,CAAC,CAAA;QAC/C,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC;QAEhD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,EAAE,CAAC,CAAC;QACjD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,EAAE,CAAC,CAAC;QACjD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC;QAChD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC;QAEhD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,EAAE,CAAC,CAAC;QACjD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,EAAE,CAAC,CAAC;QACjD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC;QAChD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC;QAEhD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,EAAE,CAAC,CAAC;QACjD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,EAAE,CAAC,CAAC;QACjD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC;QAChD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC;QAEhD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,EAAE,CAAC,CAAA;QAChD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,EAAE,CAAC,CAAC;QACjD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE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,CAAC;QAC/B,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,EAAE,CAAC,CAAC;QACjD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,EAAE,CAAC,CAAC;QACjD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC;QAChD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC;QAEhD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,EAAE,CAAC,CAAC;QACjD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,EAAE,CAAC,CAAC;QACjD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC;QAChD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC;QAEhD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,EAAE,CAAC,CAAC;QACjD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,EAAE,CAAC,CAAC;QACjD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC;QAChD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC;QAEhD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,EAAE,CAAC,CAAC;QACjD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,EAAE,CAAC,CAAC;QACjD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC,CAAC,CAAA;QAC/C,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC;QAEhD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,EAAE,CAAC,CAAC;QACjD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,EAAE,CAAC,CAAC;QACjD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC;QAChD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC;QAEhD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,EAAE,CAAC,CAAC;QACjD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,EAAE,CAAC,CAAC;QACjD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC;QAChD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC;QAEhD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,EAAE,CAAC,CAAC;QACjD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,EAAE,CAAC,CAAC;QACjD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC;QAChD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC;QAEhD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,EAAE,CAAC,CAAA;QAChD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,EAAE,CAAC,CAAC;QACjD,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC,CAAC,CAA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"} \ No newline at end of file diff --git a/node_modules/@noble/ciphers/ff1.d.ts b/node_modules/@noble/ciphers/ff1.d.ts new file mode 100644 index 0000000..7eadb87 --- /dev/null +++ b/node_modules/@noble/ciphers/ff1.d.ts @@ -0,0 +1,40 @@ +import { type Cipher, type TArg, type TRet } from './utils.ts'; +/** + * FPE-FF1 format-preserving encryption. + * @param radix - Alphabet size for each input digit. + * @param key - AES key bytes. + * @param tweak - Optional tweak bytes. + * @returns Encrypt/decrypt helpers over digit arrays. + * @example + * Encrypts decimal digits without changing their format, using a fresh AES key. + * + * ```ts + * import { FF1 } from '@noble/ciphers/ff1.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(16); + * const ff1 = FF1(10, key); + * ff1.encrypt([1, 2, 3]); + * ``` + */ +export declare function FF1(radix: number, key: TArg, tweak?: TArg): { + encrypt(x: number[]): number[]; + decrypt(x: number[]): number[]; +}; +/** + * Binary FPE-FF1 wrapper over byte arrays. + * @param key - AES key bytes. + * @param tweak - Optional tweak bytes. + * @returns Encrypt/decrypt helpers over byte arrays. + * @example + * Encrypts raw bytes through FF1's binary alphabet wrapper with a fresh AES key. + * + * ```ts + * import { BinaryFF1 } from '@noble/ciphers/ff1.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(16); + * const ff1 = BinaryFF1(key); + * ff1.encrypt(new Uint8Array([1, 2, 3])); + * ``` + */ +export declare function BinaryFF1(key: TArg, tweak?: TArg): TRet; +//# sourceMappingURL=ff1.d.ts.map \ No newline at end of file diff --git a/node_modules/@noble/ciphers/ff1.d.ts.map b/node_modules/@noble/ciphers/ff1.d.ts.map new file mode 100644 index 0000000..f2ae60f --- /dev/null +++ b/node_modules/@noble/ciphers/ff1.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"ff1.d.ts","sourceRoot":"","sources":["src/ff1.ts"],"names":[],"mappings":"AAMA,OAAO,EAML,KAAK,MAAM,EACX,KAAK,IAAI,EACT,KAAK,IAAI,EACV,MAAM,YAAY,CAAC;AAqGpB;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,GAAG,CACjB,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,EACrB,KAAK,GAAE,IAAI,CAAC,UAAU,CAAa,GAClC;IAAE,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC;IAAC,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAAA;CAAE,CAkCpE;AAsBD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,SAAS,CACvB,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,EACrB,KAAK,GAAE,IAAI,CAAC,UAAU,CAAa,GAClC,IAAI,CAAC,MAAM,CAAC,CAQd"} \ No newline at end of file diff --git a/node_modules/@noble/ciphers/ff1.js b/node_modules/@noble/ciphers/ff1.js new file mode 100644 index 0000000..79679ba --- /dev/null +++ b/node_modules/@noble/ciphers/ff1.js @@ -0,0 +1,204 @@ +/** + * FPE-FF1 (Format-preserving encryption algorithm) specified in + * {@link https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38G.pdf | NIST 800-38G}. + * @module + */ +import { unsafe } from "./aes.js"; +import { abytes, anumber, bytesToNumberBE, clean, numberToBytesBE, } from "./utils.js"; +// NIST SP 800-38G §4.3 / §5.1 Algorithm 7: FF1's designated CIPH_K here is AES, so this file +// reuses the reviewed AES key schedule and single-block encryption helpers. +// NOTE: no point in inlining encrypt instead of encryptBlock, since BigInt stuff will be slow +const { expandKeyLE, encryptBlock } = unsafe; +// Format-preserving encryption algorithm (FPE-FF1) specified in +// {@link https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38G.pdf | NIST Special Publication 800-38G}. +const BLOCK_LEN = 16; +function mod(a, b) { + const result = a % b; + return result >= 0 ? result : b + result; +} +function NUMradix(radix, data) { + let res = BigInt(0); + for (let i of data) + res = res * BigInt(radix) + BigInt(i); + return res; +} +function getRound(radix, key, tweak, x) { + if (radix > 2 ** 16 - 1) + throw new Error('invalid radix ' + radix); + // radix**minlen ≥ 100 + const minLen = Math.ceil(Math.log(100) / Math.log(radix)); + const maxLen = 2 ** 32 - 1; + // 2 ≤ minlen ≤ maxlen < 2**32 + if (2 > minLen || minLen > maxLen || maxLen >= 2 ** 32) + throw new Error('Invalid radix: 2 ≤ minlen ≤ maxlen < 2**32'); + if (!Array.isArray(x)) + throw new Error('invalid X'); + if (x.length < minLen || x.length > maxLen) + throw new Error('X is outside minLen..maxLen bounds'); + // SP 800-38G defines FF1 over numeral strings in base `radix`; out-of-range digits must fail + // before NUMradix(...) or round splitting can reinterpret them as a different numeral string. + for (const i of x) { + if (!Number.isSafeInteger(i) || i < 0 || i >= radix) + throw new Error('invalid X: digit outside radix'); + } + const u = Math.floor(x.length / 2); + const v = x.length - u; + const b = Math.ceil(Math.ceil(v * Math.log2(radix)) / 8); + const d = 4 * Math.ceil(b / 4) + 4; + const padding = mod(-tweak.length - b - 1, 16); + // P = [1]1 || [2]1 || [1]1 || [radix]3 || [10]1 || [u mod 256]1 || [n]4 || [t]4. + const P = Uint8Array.from([1, 2, 1, 0, 0, 0, 10, u, 0, 0, 0, 0, 0, 0, 0, 0]); + const view = new DataView(P.buffer); + // NIST SP 800-38G §5.1 bounds radix <= 2^16, so the 24-bit [radix]3 field is encoded here as + // 0x00 || uint16_be(radix). + view.setUint16(4, radix, false); + view.setUint32(8, x.length, false); + view.setUint32(12, tweak.length, false); + // Q = T || [0](−t−b−1) mod 16 || [i]1 || [NUMradix(B)]b. + const PQ = new Uint8Array(P.length + tweak.length + padding + 1 + b); + PQ.set(P); + clean(P); + PQ.set(tweak, P.length); + const xk = expandKeyLE(key); + const round = (A, B, i, decrypt = false) => { + // Q = ... || [i]1 || [NUMradix(B)]b. + PQ[PQ.length - b - 1] = i; + if (b) + PQ.set(numberToBytesBE(NUMradix(radix, B), b), PQ.length - b); + // NIST SP 800-38G Algorithm 6 PRF: Y_j = CIPH_K(Y_(j-1) xor X_j) starting from Y_0 = 0^128. + let r = new Uint8Array(16); + for (let j = 0; j < PQ.length / BLOCK_LEN; j++) { + for (let i = 0; i < BLOCK_LEN; i++) + r[i] ^= PQ[j * BLOCK_LEN + i]; + encryptBlock(xk, r); + } + // Let S be the first d bytes of the following string of ⎡d/16⎤ blocks: + // R || CIPHK(R ⊕[1]16) || CIPHK(R ⊕[2]16) ...CIPHK(R ⊕[⎡d / 16⎤ – 1]16). + let s = Array.from(r); + for (let j = 1; s.length < d; j++) { + const block = numberToBytesBE(BigInt(j), 16); + for (let k = 0; k < BLOCK_LEN; k++) + block[k] ^= r[k]; + s.push(...Array.from(encryptBlock(xk, block))); + } + let y = bytesToNumberBE(Uint8Array.from(s.slice(0, d))); + s.fill(0); + if (decrypt) + y = -y; + const m = i % 2 === 0 ? u : v; + let c = mod(NUMradix(radix, A) + y, BigInt(radix) ** BigInt(m)); + // STR(radix, m, c) + const C = Array(m).fill(0); + for (let i = 0; i < m; i++, c /= BigInt(radix)) + C[m - 1 - i] = Number(c % BigInt(radix)); + A.fill(0); + A = B; + B = C; + return [A, B]; + }; + const destroy = () => { + clean(xk, PQ); + }; + return { u, round, destroy }; +} +const EMPTY_BUF = /* @__PURE__ */ Uint8Array.of(); +/** + * FPE-FF1 format-preserving encryption. + * @param radix - Alphabet size for each input digit. + * @param key - AES key bytes. + * @param tweak - Optional tweak bytes. + * @returns Encrypt/decrypt helpers over digit arrays. + * @example + * Encrypts decimal digits without changing their format, using a fresh AES key. + * + * ```ts + * import { FF1 } from '@noble/ciphers/ff1.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(16); + * const ff1 = FF1(10, key); + * ff1.encrypt([1, 2, 3]); + * ``` + */ +export function FF1(radix, key, tweak = EMPTY_BUF) { + anumber(radix); + abytes(key); + abytes(tweak); + // This borrows caller key/tweak buffers by reference through the bound closure; mutating them + // after construction changes later encrypt/decrypt outputs. + const PQ = getRound.bind(null, radix, key, tweak); + return { + encrypt(x) { + const { u, round, destroy } = PQ(x); + let [A, B] = [x.slice(0, u), x.slice(u)]; + for (let i = 0; i < 10; i++) + [A, B] = round(A, B, i); + destroy(); + const res = A.concat(B); + A.fill(0); + B.fill(0); + return res; + }, + decrypt(x) { + const { u, round, destroy } = PQ(x); + // The FF1.Decrypt algorithm is similar to the FF1.Encrypt algorithm; + // the differences are in Step 6, where: + // 1) the order of the indices is reversed, + // 2) the roles of A and B are swapped + // 3) modular addition is replaced by modular subtraction, in Step 6vi. + let [B, A] = [x.slice(0, u), x.slice(u)]; + for (let i = 9; i >= 0; i--) + [A, B] = round(A, B, i, true); + destroy(); + const res = B.concat(A); + A.fill(0); + B.fill(0); + return res; + }, + }; +} +// Binary wrapper uses little-endian bit order within each byte so bit 0 stays +// in the first numeral slot for this library-defined byte-array surface. +const binLE = { + encode(bytes) { + const x = []; + for (let i = 0; i < bytes.length; i++) { + for (let j = 0, tmp = bytes[i]; j < 8; j++, tmp >>= 1) + x.push(tmp & 1); + } + return x; + }, + decode(b) { + if (!Array.isArray(b) || b.length % 8) + throw new Error('Invalid binary string'); + const res = new Uint8Array(b.length / 8); + for (let i = 0, j = 0; i < res.length; i++) { + res[i] = b[j++] | (b[j++] << 1) | (b[j++] << 2) | (b[j++] << 3); + res[i] |= (b[j++] << 4) | (b[j++] << 5) | (b[j++] << 6) | (b[j++] << 7); + } + return res; + }, +}; +/** + * Binary FPE-FF1 wrapper over byte arrays. + * @param key - AES key bytes. + * @param tweak - Optional tweak bytes. + * @returns Encrypt/decrypt helpers over byte arrays. + * @example + * Encrypts raw bytes through FF1's binary alphabet wrapper with a fresh AES key. + * + * ```ts + * import { BinaryFF1 } from '@noble/ciphers/ff1.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(16); + * const ff1 = BinaryFF1(key); + * ff1.encrypt(new Uint8Array([1, 2, 3])); + * ``` + */ +export function BinaryFF1(key, tweak = EMPTY_BUF) { + const ff1 = FF1(2, key, tweak); + return { + encrypt: (x) => binLE.decode(ff1.encrypt(binLE.encode(x))), + decrypt: (x) => binLE.decode(ff1.decrypt(binLE.encode(x))), + }; +} +//# sourceMappingURL=ff1.js.map \ No newline at end of file diff --git a/node_modules/@noble/ciphers/ff1.js.map b/node_modules/@noble/ciphers/ff1.js.map new file mode 100644 index 0000000..8a4131a --- /dev/null +++ b/node_modules/@noble/ciphers/ff1.js.map @@ -0,0 +1 @@ +{"version":3,"file":"ff1.js","sourceRoot":"","sources":["src/ff1.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@noble/ciphers/index.d.ts b/node_modules/@noble/ciphers/index.d.ts new file mode 100644 index 0000000..e26a57a --- /dev/null +++ b/node_modules/@noble/ciphers/index.d.ts @@ -0,0 +1,2 @@ +export {}; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/node_modules/@noble/ciphers/index.d.ts.map b/node_modules/@noble/ciphers/index.d.ts.map new file mode 100644 index 0000000..4e8c581 --- /dev/null +++ b/node_modules/@noble/ciphers/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["src/index.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/node_modules/@noble/ciphers/index.js b/node_modules/@noble/ciphers/index.js new file mode 100644 index 0000000..c531a41 --- /dev/null +++ b/node_modules/@noble/ciphers/index.js @@ -0,0 +1,27 @@ +/** + * Audited & minimal JS implementation of Salsa20, ChaCha and AES. Check out individual modules. + * @example +```js +import { gcm, aessiv } from '@noble/ciphers/aes.js'; +import { xsalsa20poly1305 } from '@noble/ciphers/salsa.js'; +import { secretbox } from '@noble/ciphers/salsa.js'; // == xsalsa20poly1305 +import { chacha20poly1305, xchacha20poly1305 } from '@noble/ciphers/chacha.js'; + +// Unauthenticated encryption: make sure to use HMAC or similar +import { ctr, cfb, cbc, ecb } from '@noble/ciphers/aes.js'; +import { salsa20, xsalsa20 } from '@noble/ciphers/salsa.js'; +import { chacha20, xchacha20, chacha8, chacha12 } from '@noble/ciphers/chacha.js'; + +// KW +import { aeskw, aeskwp } from '@noble/ciphers/aes.js'; + +// Utilities +import { managedNonce, randomBytes, bytesToHex, hexToBytes } from '@noble/ciphers/utils.js'; +import { poly1305 } from '@noble/ciphers/_poly1305.js'; +import { ghash, polyval } from '@noble/ciphers/_polyval.js'; +``` + * @module + */ +throw new Error('root module cannot be imported: import submodules instead. Check out README'); +export {}; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/@noble/ciphers/index.js.map b/node_modules/@noble/ciphers/index.js.map new file mode 100644 index 0000000..b4a5484 --- /dev/null +++ b/node_modules/@noble/ciphers/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,IAAI,KAAK,CAAC,6EAA6E,CAAC,CAAC"} \ No newline at end of file diff --git a/node_modules/@noble/ciphers/package.json b/node_modules/@noble/ciphers/package.json new file mode 100644 index 0000000..2f17685 --- /dev/null +++ b/node_modules/@noble/ciphers/package.json @@ -0,0 +1,85 @@ +{ + "name": "@noble/ciphers", + "version": "2.2.0", + "description": "Audited & minimal JS implementation of Salsa20, ChaCha and AES", + "files": [ + "src", + "*.js", + "*.js.map", + "*.d.ts", + "*.d.ts.map" + ], + "devDependencies": { + "@paulmillr/jsbt": "0.5.0", + "@scure/base": "2.0.0", + "@types/node": "25.3.0", + "fast-check": "4.2.0", + "prettier": "3.6.2", + "typescript": "6.0.2" + }, + "scripts": { + "bench": "node test/benchmark/noble.ts", + "bench:compare": "cd test/benchmark; npm install; node compare.ts", + "build": "tsc", + "build:release": "npx --no @paulmillr/jsbt esbuild test/build", + "check": "npm run check:readme && npm run check:treeshake && npm run check:jsdoc", + "check:readme": "npx --no @paulmillr/jsbt readme package.json", + "check:treeshake": "npx --no @paulmillr/jsbt treeshake package.json test/build/out-treeshake", + "check:jsdoc": "npx --no @paulmillr/jsbt tsdoc package.json", + "build:clean": "rm *.{js,js.map,d.ts,d.ts.map} 2> /dev/null", + "format": "prettier --write 'src/**/*.{js,ts}' 'test/**/*.{js,ts,mjs}'", + "test": "node test/index.ts", + "test:bun": "bun test/index.ts", + "test:deno": "deno --allow-env --allow-read test/index.ts", + "test:node20": "cd test; npx tsc; node compiled/test/index.js", + "test:slow": "node test/crosstest.test.ts slow" + }, + "exports": { + ".": "./index.js", + "./_arx.js": "./_arx.js", + "./_poly1305.js": "./_poly1305.js", + "./_polyval.js": "./_polyval.js", + "./aes.js": "./aes.js", + "./chacha.js": "./chacha.js", + "./ff1.js": "./ff1.js", + "./salsa.js": "./salsa.js", + "./utils.js": "./utils.js", + "./webcrypto.js": "./webcrypto.js" + }, + "engines": { + "node": ">= 20.19.0" + }, + "keywords": [ + "salsa20", + "chacha", + "aes", + "cryptography", + "crypto", + "noble", + "cipher", + "ciphers", + "xsalsa20", + "xchacha20", + "poly1305", + "xsalsa20poly1305", + "chacha20poly1305", + "xchacha20poly1305", + "secretbox", + "rijndael", + "siv", + "ff1" + ], + "homepage": "https://paulmillr.com/noble/", + "funding": "https://paulmillr.com/funding/", + "repository": { + "type": "git", + "url": "git+https://github.com/paulmillr/noble-ciphers.git" + }, + "type": "module", + "main": "index.js", + "module": "index.js", + "types": "index.d.ts", + "sideEffects": false, + "author": "Paul Miller (https://paulmillr.com)", + "license": "MIT" +} diff --git a/node_modules/@noble/ciphers/salsa.d.ts b/node_modules/@noble/ciphers/salsa.d.ts new file mode 100644 index 0000000..a56e465 --- /dev/null +++ b/node_modules/@noble/ciphers/salsa.d.ts @@ -0,0 +1,115 @@ +import { type ARXCipher, type TArg, type TRet, type XorStream } from './utils.ts'; +/** + * hsalsa hashes key and nonce-prefix words into the 32-byte subkey used by XSalsa20. + * Identical to `hsalsa_small`. + * Need to find a way to merge it with `salsaCore` without 25% performance hit. + * @param s - Sigma constants as 32-bit words. + * @param k - Key words. + * @param i - Nonce-prefix words. + * @param out - Output buffer for the derived subkey. + * @example + * Derives the XSalsa20 subkey from sigma, key, and nonce-prefix words. + * + * ```ts + * const sigma = new Uint32Array(4); + * const key = new Uint32Array(8); + * const nonce = new Uint32Array(4); + * const out = new Uint32Array(8); + * hsalsa(sigma, key, nonce, out); + * ``` + */ +export declare function hsalsa(s: TArg, k: TArg, i: TArg, out: TArg): void; +/** + * Salsa20 from original paper. 8-byte nonce. + * With smaller nonce, it's not safe to make it random (CSPRNG), due to collision chance. + * @param key - 16-byte or 32-byte key. + * @param nonce - 8-byte nonce. + * @param data - Input bytes to xor with the keystream. + * @param output - Optional destination buffer. + * @param counter - Initial block counter. + * Only the low 32 bits of Salsa20's 64-bit counter state are exposed here; + * the high word stays zero and the implementation still caps the public + * value to 32 bits. + * @returns Encrypted or decrypted bytes. + * @example + * Encrypts bytes with the original 8-byte-nonce Salsa20 stream cipher. + * + * ```ts + * import { salsa20 } from '@noble/ciphers/salsa.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(32); + * const nonce = randomBytes(8); + * salsa20(key, nonce, new Uint8Array([1, 2, 3, 4])); + * ``` + */ +export declare const salsa20: TRet; +/** + * XSalsa20 extended-nonce salsa. + * With 24-byte nonce, it's safe to make it random (CSPRNG). + * @param key - 32-byte key. + * This XSalsa20 wrapper does not enable Salsa20's 16-byte legacy key mode. + * @param nonce - 24-byte nonce. + * @param data - Input bytes to xor with the keystream. + * @param output - Optional destination buffer. + * @param counter - Initial block counter. + * @returns Encrypted or decrypted bytes. + * @example + * Encrypts bytes with XSalsa20 and a random 24-byte nonce. + * + * ```ts + * import { xsalsa20 } from '@noble/ciphers/salsa.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(32); + * const nonce = randomBytes(24); + * xsalsa20(key, nonce, new Uint8Array([1, 2, 3, 4])); + * ``` + */ +export declare const xsalsa20: TRet; +/** + * xsalsa20-poly1305 eXtended-nonce (24 bytes) salsa. + * With 24-byte nonce, it's safe to make it random (CSPRNG). + * Also known as `secretbox` from libsodium / nacl. + * No AAD input is supported here. Caller-provided `output` buffers for + * `encrypt()` / `decrypt()` must be `input.length + 32` bytes because the + * implementation uses a 32-byte leading scratch area before returning `+16`. + * @param key - 32-byte key. + * @param nonce - 24-byte nonce. + * @param AAD - Must be omitted; XSalsa20-Poly1305 secretbox does not support associated data. + * @returns AEAD cipher instance. + * @example + * Encrypts and authenticates plaintext with XSalsa20-Poly1305. + * + * ```ts + * import { xsalsa20poly1305 } from '@noble/ciphers/salsa.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(32); + * const nonce = randomBytes(24); + * const cipher = xsalsa20poly1305(key, nonce); + * cipher.encrypt(new Uint8Array([1, 2, 3])); + * ``` + */ +export declare const xsalsa20poly1305: TRet; +/** + * Alias to `xsalsa20poly1305`, for compatibility with libsodium / nacl. + * Check out {@link https://github.com/serenity-kit/noble-sodium | noble-sodium} + * for `crypto_box`. + * @param key - 32-byte key. + * @param nonce - 24-byte nonce. + * @returns Wrapper with `seal()` and `open()` helpers. + * @example + * Uses the libsodium-style `seal()` and `open()` wrapper. + * + * ```ts + * import { secretbox } from '@noble/ciphers/salsa.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(32); + * const nonce = randomBytes(24); + * const box = secretbox(key, nonce); + * box.seal(new Uint8Array([1, 2, 3])); + * ``` + */ +export declare function secretbox(key: TArg, nonce: TArg): TRet<{ + seal: (plaintext: TArg, output?: TArg) => TRet; + open: (ciphertext: TArg, output?: TArg) => TRet; +}>; +//# sourceMappingURL=salsa.d.ts.map \ No newline at end of file diff --git a/node_modules/@noble/ciphers/salsa.d.ts.map b/node_modules/@noble/ciphers/salsa.d.ts.map new file mode 100644 index 0000000..de0f2e0 --- /dev/null +++ b/node_modules/@noble/ciphers/salsa.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"salsa.d.ts","sourceRoot":"","sources":["src/salsa.ts"],"names":[],"mappings":"AAqBA,OAAO,EAQL,KAAK,SAAS,EAEd,KAAK,IAAI,EACT,KAAK,IAAI,EACT,KAAK,SAAS,EACf,MAAM,YAAY,CAAC;AAuHpB;;;;;;;;;;;;;;;;;;GAkBG;AAEH,wBAAgB,MAAM,CACpB,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,WAAW,CAAC,GACvF,IAAI,CA8BN;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,OAAO,EAAE,IAAI,CAAC,SAAS,CAGlC,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,QAAQ,EAAE,IAAI,CAAC,SAAS,CAGnC,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,gBAAgB,EAAE,IAAI,CAAC,SAAS,CAwD5C,CAAC;AAEF;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,SAAS,CACvB,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,EACrB,KAAK,EAAE,IAAI,CAAC,UAAU,CAAC,GACtB,IAAI,CAAC;IACN,IAAI,EAAE,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC,UAAU,CAAC,CAAC;IACnF,IAAI,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC,UAAU,CAAC,CAAC;CACrF,CAAC,CAMD"} \ No newline at end of file diff --git a/node_modules/@noble/ciphers/salsa.js b/node_modules/@noble/ciphers/salsa.js new file mode 100644 index 0000000..8574db2 --- /dev/null +++ b/node_modules/@noble/ciphers/salsa.js @@ -0,0 +1,371 @@ +/** + * Salsa20 stream cipher, released in 2005. + * Salsa's goal was to implement AES replacement that does not rely on S-Boxes, + * which are hard to implement in a constant-time manner. + * Salsa20 is usually faster than AES, a big deal on slow, budget mobile phones. + * + * - {@link https://cr.yp.to/snuffle/xsalsa-20110204.pdf | XSalsa20}, + * extended-nonce + * variant was released in 2008. It extends Salsa20's 64-bit nonce to 192 bits, + * and became safe to be picked at random. + * - Nacl / Libsodium popularized term "secretbox", - which is just xsalsa20poly1305. + * We provide the alias and corresponding seal / open methods. + * "crypto_box" and "sealedbox" are available in package + * {@link https://github.com/serenity-kit/noble-sodium | noble-sodium}. + * - Check out + * {@link https://cr.yp.to/snuffle/salsafamily-20071225.pdf | PDF} + * and {@link https://cr.yp.to/snuffle.html | website}. + * @module + */ +import { createCipher, rotl } from "./_arx.js"; +import { poly1305 } from "./_poly1305.js"; +import { abytes, clean, equalBytes, getOutput, swap32IfBE, swap8IfBE, wrapCipher, } from "./utils.js"; +/** + * Salsa20 core function. It is implemented twice: + * 1. Simple loop (salsaCore_small, hsalsa_small) + * 2. Unrolled loop (salsaCore, hsalsa) - 4x faster, but larger & harder to read + * The specific implementation is selected in `createCipher` below. + * Performance numbers for 1MB inputs: + * * default x 779 ops/sec @ 1ms/op + * * if salsa+hsalsa are merged x 459 ops/sec @ 2ms/op + * * small x 132 ops/sec @ 7ms/op + */ +/** RFC 7914 §3 Salsa20/8 core quarter-round on words a, b, c, d. */ +function salsaQR(x, a, b, c, d) { + x[b] ^= rotl((x[a] + x[d]) | 0, 7); + x[c] ^= rotl((x[b] + x[a]) | 0, 9); + x[d] ^= rotl((x[c] + x[b]) | 0, 13); + x[a] ^= rotl((x[d] + x[c]) | 0, 18); +} +/** RFC 7914 §3 double-round schedule: four column rounds, then four row rounds. */ +function salsaRound(x, rounds = 20) { + for (let r = 0; r < rounds; r += 2) { + salsaQR(x, 0, 4, 8, 12); + salsaQR(x, 5, 9, 13, 1); + salsaQR(x, 10, 14, 2, 6); + salsaQR(x, 15, 3, 7, 11); + salsaQR(x, 0, 1, 2, 3); + salsaQR(x, 5, 6, 7, 4); + salsaQR(x, 10, 11, 8, 9); + salsaQR(x, 15, 12, 13, 14); + } +} +// Shared scratch for the unused auditability helper below; it would be +// non-reentrant under overlapping/nested calls, but current code doesn't invoke it. +const stmp = /* @__PURE__ */ new Uint32Array(16); +/** Small version of salsa without loop unrolling. Unused, provided for auditability. */ +// prettier-ignore +function salsa(s, k, i, out, isHSalsa = true, rounds = 20) { + // Create initial array using common pattern + const y = Uint32Array.from([ + s[0], k[0], k[1], k[2], // "expa" Key Key Key + k[3], s[1], i[0], i[1], // Key "nd 3" Nonce Nonce + i[2], i[3], s[2], k[4], // Pos. Pos. "2-by" Key + k[5], k[6], k[7], s[3], // Key Key Key "te k" + ]); + const x = stmp; + x.set(y); + // const x = y.slice(); + salsaRound(x, rounds); + // hsalsa extracts 8 specific words for the 32-byte subkey; salsa adds the original state. + if (isHSalsa) { + const xindexes = [0, 5, 10, 15, 6, 7, 8, 9]; + for (let i = 0; i < 8; i++) + out[i] = x[xindexes[i]]; + } + else { + for (let i = 0; i < 16; i++) + out[i] = (y[i] + x[i]) | 0; + } +} +/** Identical to `salsaCore`. Unused. */ +// @ts-ignore +const salsaCore_small = (s, k, n, out, cnt, rounds) => salsa(s, k, Uint32Array.from([n[0], n[1], cnt, 0]), out, false, rounds); +/** Identical to `hsalsa`. Unused. */ +// @ts-ignore +const hsalsa_small = salsa; +/** Identical to `salsaCore_small`. Uses only the low 32 bits of Salsa20's 64-bit counter state. */ +// prettier-ignore +function salsaCore(s, k, n, out, cnt, rounds = 20) { + // Public wrappers expose only the low 32 bits of Salsa20's 64-bit counter; y09 stays zero. + // Based on {@link https://cr.yp.to/salsa20.html | the Salsa20 reference page}. + let y00 = s[0], y01 = k[0], y02 = k[1], y03 = k[2], // "expa" Key Key Key + y04 = k[3], y05 = s[1], y06 = n[0], y07 = n[1], // Key "nd 3" Nonce Nonce + y08 = cnt, y09 = 0, y10 = s[2], y11 = k[4], // Pos. Pos. "2-by" Key + y12 = k[5], y13 = k[6], y14 = k[7], y15 = s[3]; // Key Key Key "te k" + // Save state to temporary variables + let x00 = y00, x01 = y01, x02 = y02, x03 = y03, x04 = y04, x05 = y05, x06 = y06, x07 = y07, x08 = y08, x09 = y09, x10 = y10, x11 = y11, x12 = y12, x13 = y13, x14 = y14, x15 = y15; + for (let r = 0; r < rounds; r += 2) { + x04 ^= rotl(x00 + x12 | 0, 7); + x08 ^= rotl(x04 + x00 | 0, 9); + x12 ^= rotl(x08 + x04 | 0, 13); + x00 ^= rotl(x12 + x08 | 0, 18); + x09 ^= rotl(x05 + x01 | 0, 7); + x13 ^= rotl(x09 + x05 | 0, 9); + x01 ^= rotl(x13 + x09 | 0, 13); + x05 ^= rotl(x01 + x13 | 0, 18); + x14 ^= rotl(x10 + x06 | 0, 7); + x02 ^= rotl(x14 + x10 | 0, 9); + x06 ^= rotl(x02 + x14 | 0, 13); + x10 ^= rotl(x06 + x02 | 0, 18); + x03 ^= rotl(x15 + x11 | 0, 7); + x07 ^= rotl(x03 + x15 | 0, 9); + x11 ^= rotl(x07 + x03 | 0, 13); + x15 ^= rotl(x11 + x07 | 0, 18); + x01 ^= rotl(x00 + x03 | 0, 7); + x02 ^= rotl(x01 + x00 | 0, 9); + x03 ^= rotl(x02 + x01 | 0, 13); + x00 ^= rotl(x03 + x02 | 0, 18); + x06 ^= rotl(x05 + x04 | 0, 7); + x07 ^= rotl(x06 + x05 | 0, 9); + x04 ^= rotl(x07 + x06 | 0, 13); + x05 ^= rotl(x04 + x07 | 0, 18); + x11 ^= rotl(x10 + x09 | 0, 7); + x08 ^= rotl(x11 + x10 | 0, 9); + x09 ^= rotl(x08 + x11 | 0, 13); + x10 ^= rotl(x09 + x08 | 0, 18); + x12 ^= rotl(x15 + x14 | 0, 7); + x13 ^= rotl(x12 + x15 | 0, 9); + x14 ^= rotl(x13 + x12 | 0, 13); + x15 ^= rotl(x14 + x13 | 0, 18); + } + // Write output + let oi = 0; + out[oi++] = (y00 + x00) | 0; + out[oi++] = (y01 + x01) | 0; + out[oi++] = (y02 + x02) | 0; + out[oi++] = (y03 + x03) | 0; + out[oi++] = (y04 + x04) | 0; + out[oi++] = (y05 + x05) | 0; + out[oi++] = (y06 + x06) | 0; + out[oi++] = (y07 + x07) | 0; + out[oi++] = (y08 + x08) | 0; + out[oi++] = (y09 + x09) | 0; + out[oi++] = (y10 + x10) | 0; + out[oi++] = (y11 + x11) | 0; + out[oi++] = (y12 + x12) | 0; + out[oi++] = (y13 + x13) | 0; + out[oi++] = (y14 + x14) | 0; + out[oi++] = (y15 + x15) | 0; +} +/** + * hsalsa hashes key and nonce-prefix words into the 32-byte subkey used by XSalsa20. + * Identical to `hsalsa_small`. + * Need to find a way to merge it with `salsaCore` without 25% performance hit. + * @param s - Sigma constants as 32-bit words. + * @param k - Key words. + * @param i - Nonce-prefix words. + * @param out - Output buffer for the derived subkey. + * @example + * Derives the XSalsa20 subkey from sigma, key, and nonce-prefix words. + * + * ```ts + * const sigma = new Uint32Array(4); + * const key = new Uint32Array(8); + * const nonce = new Uint32Array(4); + * const out = new Uint32Array(8); + * hsalsa(sigma, key, nonce, out); + * ``` + */ +// prettier-ignore +export function hsalsa(s, k, i, out) { + let x00 = swap8IfBE(s[0]), x01 = swap8IfBE(k[0]), x02 = swap8IfBE(k[1]), x03 = swap8IfBE(k[2]), x04 = swap8IfBE(k[3]), x05 = swap8IfBE(s[1]), x06 = swap8IfBE(i[0]), x07 = swap8IfBE(i[1]), x08 = swap8IfBE(i[2]), x09 = swap8IfBE(i[3]), x10 = swap8IfBE(s[2]), x11 = swap8IfBE(k[4]), x12 = swap8IfBE(k[5]), x13 = swap8IfBE(k[6]), x14 = swap8IfBE(k[7]), x15 = swap8IfBE(s[3]); + for (let r = 0; r < 20; r += 2) { + x04 ^= rotl(x00 + x12 | 0, 7); + x08 ^= rotl(x04 + x00 | 0, 9); + x12 ^= rotl(x08 + x04 | 0, 13); + x00 ^= rotl(x12 + x08 | 0, 18); + x09 ^= rotl(x05 + x01 | 0, 7); + x13 ^= rotl(x09 + x05 | 0, 9); + x01 ^= rotl(x13 + x09 | 0, 13); + x05 ^= rotl(x01 + x13 | 0, 18); + x14 ^= rotl(x10 + x06 | 0, 7); + x02 ^= rotl(x14 + x10 | 0, 9); + x06 ^= rotl(x02 + x14 | 0, 13); + x10 ^= rotl(x06 + x02 | 0, 18); + x03 ^= rotl(x15 + x11 | 0, 7); + x07 ^= rotl(x03 + x15 | 0, 9); + x11 ^= rotl(x07 + x03 | 0, 13); + x15 ^= rotl(x11 + x07 | 0, 18); + x01 ^= rotl(x00 + x03 | 0, 7); + x02 ^= rotl(x01 + x00 | 0, 9); + x03 ^= rotl(x02 + x01 | 0, 13); + x00 ^= rotl(x03 + x02 | 0, 18); + x06 ^= rotl(x05 + x04 | 0, 7); + x07 ^= rotl(x06 + x05 | 0, 9); + x04 ^= rotl(x07 + x06 | 0, 13); + x05 ^= rotl(x04 + x07 | 0, 18); + x11 ^= rotl(x10 + x09 | 0, 7); + x08 ^= rotl(x11 + x10 | 0, 9); + x09 ^= rotl(x08 + x11 | 0, 13); + x10 ^= rotl(x09 + x08 | 0, 18); + x12 ^= rotl(x15 + x14 | 0, 7); + x13 ^= rotl(x12 + x15 | 0, 9); + x14 ^= rotl(x13 + x12 | 0, 13); + x15 ^= rotl(x14 + x13 | 0, 18); + } + let oi = 0; + // XSalsa20 takes words 0,5,10,15 and 6,7,8,9 as the 32-byte subkey material. + out[oi++] = x00; + out[oi++] = x05; + out[oi++] = x10; + out[oi++] = x15; + out[oi++] = x06; + out[oi++] = x07; + out[oi++] = x08; + out[oi++] = x09; + swap32IfBE(out); +} +/** + * Salsa20 from original paper. 8-byte nonce. + * With smaller nonce, it's not safe to make it random (CSPRNG), due to collision chance. + * @param key - 16-byte or 32-byte key. + * @param nonce - 8-byte nonce. + * @param data - Input bytes to xor with the keystream. + * @param output - Optional destination buffer. + * @param counter - Initial block counter. + * Only the low 32 bits of Salsa20's 64-bit counter state are exposed here; + * the high word stays zero and the implementation still caps the public + * value to 32 bits. + * @returns Encrypted or decrypted bytes. + * @example + * Encrypts bytes with the original 8-byte-nonce Salsa20 stream cipher. + * + * ```ts + * import { salsa20 } from '@noble/ciphers/salsa.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(32); + * const nonce = randomBytes(8); + * salsa20(key, nonce, new Uint8Array([1, 2, 3, 4])); + * ``` + */ +export const salsa20 = /* @__PURE__ */ createCipher(salsaCore, { + allowShortKeys: true, + counterRight: true, +}); +/** + * XSalsa20 extended-nonce salsa. + * With 24-byte nonce, it's safe to make it random (CSPRNG). + * @param key - 32-byte key. + * This XSalsa20 wrapper does not enable Salsa20's 16-byte legacy key mode. + * @param nonce - 24-byte nonce. + * @param data - Input bytes to xor with the keystream. + * @param output - Optional destination buffer. + * @param counter - Initial block counter. + * @returns Encrypted or decrypted bytes. + * @example + * Encrypts bytes with XSalsa20 and a random 24-byte nonce. + * + * ```ts + * import { xsalsa20 } from '@noble/ciphers/salsa.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(32); + * const nonce = randomBytes(24); + * xsalsa20(key, nonce, new Uint8Array([1, 2, 3, 4])); + * ``` + */ +export const xsalsa20 = /* @__PURE__ */ createCipher(salsaCore, { + counterRight: true, + extendNonceFn: hsalsa, +}); +/** + * xsalsa20-poly1305 eXtended-nonce (24 bytes) salsa. + * With 24-byte nonce, it's safe to make it random (CSPRNG). + * Also known as `secretbox` from libsodium / nacl. + * No AAD input is supported here. Caller-provided `output` buffers for + * `encrypt()` / `decrypt()` must be `input.length + 32` bytes because the + * implementation uses a 32-byte leading scratch area before returning `+16`. + * @param key - 32-byte key. + * @param nonce - 24-byte nonce. + * @param AAD - Must be omitted; XSalsa20-Poly1305 secretbox does not support associated data. + * @returns AEAD cipher instance. + * @example + * Encrypts and authenticates plaintext with XSalsa20-Poly1305. + * + * ```ts + * import { xsalsa20poly1305 } from '@noble/ciphers/salsa.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(32); + * const nonce = randomBytes(24); + * const cipher = xsalsa20poly1305(key, nonce); + * cipher.encrypt(new Uint8Array([1, 2, 3])); + * ``` + */ +export const xsalsa20poly1305 = /* @__PURE__ */ wrapCipher({ blockSize: 64, nonceLength: 24, tagLength: 16 }, (key, nonce) => { + // This borrows caller key/nonce buffers by reference; mutating them after construction changes + // later encrypt/decrypt outputs. + return { + encrypt(plaintext, output) { + // xsalsa20poly1305 optimizes by calculating auth key during the same call as encryption. + // Unfortunately, makes it hard to separate tag calculation & encryption itself, + // because 32 bytes is half-block of 64-byte salsa. + // Need 32 extra bytes up front for the auth-key scratch area described above. + output = getOutput(plaintext.length + 32, output, false); + // output[0..32] = Poly1305 auth key, output[32..] = plaintext then ciphertext. + const authKey = output.subarray(0, 32); + const ciphPlaintext = output.subarray(32); + output.set(plaintext, 32); + // authKey is produced by xoring the first 32 bytes with zeros. + clean(authKey); + // output = stream ^ output; authKey = stream ^ zeros(32) + xsalsa20(key, nonce, output, output); + const tag = poly1305(ciphPlaintext, authKey); + output.set(tag, 16); + // Clean up auth-key remnants and the temporary tag copy. + clean(output.subarray(0, 16), tag); + // Return output[16..]. + return output.subarray(16); + }, + decrypt(ciphertext, output) { + // tmp part passed tag ciphertext + // [0..32] [32..48] [48..] + // Authenticate the ciphertext before decrypting it; on tag failure the scratch/output + // buffer may already contain copied ciphertext and derived auth-key material. + abytes(ciphertext); + output = getOutput(ciphertext.length + 32, output, false); + // output[0..32] is auth-key scratch, output[32..48] is passed tag, + // output[48..] is ciphertext then plaintext. + const tmp = output.subarray(0, 32); + const passedTag = output.subarray(32, 48); + const ciphPlaintext = output.subarray(48); + output.set(ciphertext, 32); + // authKey is produced by xoring the scratch area with zeros. + clean(tmp); + const authKey = xsalsa20(key, nonce, tmp, tmp); + const tag = poly1305(ciphPlaintext, authKey); + if (!equalBytes(passedTag, tag)) { + clean(output); + throw new Error('invalid tag'); + } + // output = stream ^ output[16..] + xsalsa20(key, nonce, output.subarray(16), output.subarray(16)); + clean(tmp, passedTag, tag); + // Return output[48..], skipping zeroized output[0..48]. + return ciphPlaintext; + }, + }; +}); +/** + * Alias to `xsalsa20poly1305`, for compatibility with libsodium / nacl. + * Check out {@link https://github.com/serenity-kit/noble-sodium | noble-sodium} + * for `crypto_box`. + * @param key - 32-byte key. + * @param nonce - 24-byte nonce. + * @returns Wrapper with `seal()` and `open()` helpers. + * @example + * Uses the libsodium-style `seal()` and `open()` wrapper. + * + * ```ts + * import { secretbox } from '@noble/ciphers/salsa.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(32); + * const nonce = randomBytes(24); + * const box = secretbox(key, nonce); + * box.seal(new Uint8Array([1, 2, 3])); + * ``` + */ +export function secretbox(key, nonce) { + const xs = xsalsa20poly1305(key, nonce); + return { seal: xs.encrypt, open: xs.decrypt }; +} +//# sourceMappingURL=salsa.js.map \ No newline at end of file diff --git a/node_modules/@noble/ciphers/salsa.js.map b/node_modules/@noble/ciphers/salsa.js.map new file mode 100644 index 0000000..6a801a1 --- /dev/null +++ b/node_modules/@noble/ciphers/salsa.js.map @@ -0,0 +1 @@ +{"version":3,"file":"salsa.js","sourceRoot":"","sources":["src/salsa.ts"],"names":[],"mappings":"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G,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QAC9D,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;QAAC,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;QAC/D,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAG,CAAC,CAAC,CAAC;QAAC,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QAC9D,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;QAAC,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;QAC/D,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAG,CAAC,CAAC,CAAC;QAAC,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QAC9D,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;QAAC,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;QAC/D,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAG,CAAC,CAAC,CAAC;QAAC,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QAC9D,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;QAAC,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;QAC/D,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAG,CAAC,CAAC,CAAC;QAAC,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QAC9D,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG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GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QAC9D,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;QAAC,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;QAC/D,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QAAE,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QAC9D,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;QAAC,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;QAC/D,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QAAE,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QAC9D,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;QAAC,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;QAC/D,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QAAE,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QAC9D,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;QAAC,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;QAC/D,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QAAE,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QAC9D,GAAG,IAAI,IAAI,CAAC,G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"} \ No newline at end of file diff --git a/node_modules/@noble/ciphers/src/_arx.ts b/node_modules/@noble/ciphers/src/_arx.ts new file mode 100644 index 0000000..fd43e94 --- /dev/null +++ b/node_modules/@noble/ciphers/src/_arx.ts @@ -0,0 +1,499 @@ +/** + * Basic utils for ARX (add-rotate-xor) salsa and chacha ciphers. + +RFC8439 requires multi-step cipher stream, where +authKey starts with counter: 0, actual msg with counter: 1. + +For this, we need a way to re-use nonce / counter: + + const counter = new Uint8Array(4); + chacha(..., counter, ...); // counter is now 1 + chacha(..., counter, ...); // counter is now 2 + +This is complicated: + +- 32-bit counters are enough, no need for 64-bit: max ArrayBuffer size in JS is 4GB +- Original papers don't allow mutating counters +- Counter overflow is undefined [^1] +- Idea A: allow providing (nonce | counter) instead of just nonce, re-use it +- Caveat: Cannot be re-used through all cases: +- * chacha has (counter | nonce) +- * xchacha has (nonce16 | counter | nonce16) +- Idea B: separate nonce / counter and provide separate API for counter re-use +- Caveat: there are different counter sizes depending on an algorithm. +- salsa & chacha also differ in structures of key & sigma: + salsa20: s[0] | k(4) | s[1] | nonce(2) | cnt(2) | s[2] | k(4) | s[3] + chacha: s(4) | k(8) | cnt(1) | nonce(3) + chacha20orig: s(4) | k(8) | cnt(2) | nonce(2) +- Idea C: helper method such as `setSalsaState(key, nonce, sigma, data)` +- Caveat: we can't re-use counter array + +xchacha uses the subkey and remaining 8 byte nonce with ChaCha20 as normal +(prefixed by 4 NUL bytes, since RFC8439 specifies a 12-byte nonce). +Counter overflow is undefined; see {@link https://mailarchive.ietf.org/arch/msg/cfrg/gsOnTJzcbgG6OqD8Sc0GO5aR_tU/ | the CFRG thread}. +Current noble policy is strict non-wrap for the shared 32-bit counter path: +exported ARX ciphers reject initial `0xffffffff` and stop before any implicit +wrap back to zero. +See {@link https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha#appendix-A.2 | the XChaCha appendix} for the extended-nonce construction. + + * @module + */ +import { + type PRG, + type TArg, + type TRet, + type XorStream, + abool, + abytes, + anumber, + checkOpts, + clean, + copyBytes, + getOutput, + isAligned32, + isLE, + randomBytes, + swap32IfBE, + u32, +} from './utils.ts'; + +// Replaces `TextEncoder` for ASCII literals, which is enough for sigma constants. +// Non-ASCII input would not match UTF-8 `TextEncoder` output. +const encodeStr = (str: string) => Uint8Array.from(str.split(''), (c) => c.charCodeAt(0)); +// Raw `createCipher(...)` exports consume these native-endian `u32(...)` views directly. +// Public `wrapCipher(...)` APIs reject non-little-endian platforms before reaching this path. +// RFC 8439 §2.3 / RFC 7539 §2.3 only define the 256-bit-key constants; this 16-byte sigma is +// kept for legacy allowShortKeys Salsa/ChaCha variants. +const sigma16_32 = /* @__PURE__ */ (() => swap32IfBE(u32(encodeStr('expand 16-byte k'))))(); +// RFC 8439 §2.3 / RFC 7539 §2.3 define words 0-3 as +// `0x61707865 0x3320646e 0x79622d32 0x6b206574`, i.e. `expand 32-byte k`. +const sigma32_32 = /* @__PURE__ */ (() => swap32IfBE(u32(encodeStr('expand 32-byte k'))))(); + +/** + * Rotates a 32-bit word left. + * @param a - Input word. + * @param b - Rotation count in bits. + * @returns Rotated 32-bit word. + * @example + * Moves the top byte of `0x12345678` into the low byte position. + * ```ts + * rotl(0x12345678, 8); + * ``` + */ +export function rotl(a: number, b: number): number { + return (a << b) | (a >>> (32 - b)); +} + +/** + * ARX core function operating on 32-bit words. Ciphers must use u32 for efficiency. + * @param sigma - Sigma constants for the selected cipher layout. + * @param key - Expanded key words. + * @param nonce - Nonce and counter words prepared for the round function. + * @param output - Output block written in place. + * @param counter - Block counter value. + * @param rounds - Optional round count override. + */ +export type CipherCoreFn = ( + sigma: TArg, + key: TArg, + nonce: TArg, + output: TArg, + counter: number, + rounds?: number +) => void; + +/** + * Nonce-extension function used by XChaCha and XSalsa. + * @param sigma - Sigma constants for the selected cipher layout. + * @param key - Expanded key words. + * @param input - Input nonce words used for subkey derivation. + * @param output - Output buffer written with the derived nonce words. + */ +export type ExtendNonceFn = ( + sigma: TArg, + key: TArg, + input: TArg, + output: TArg +) => void; + +/** ARX cipher options. + * * `allowShortKeys` for 16-byte keys + * * `counterLength` in bytes + * * `counterRight`: right: `nonce|counter`; left: `counter|nonce` + * */ +export type CipherOpts = { + /** Whether 16-byte keys are accepted for legacy Salsa and ChaCha variants. */ + allowShortKeys?: boolean; + /** Optional nonce-expansion hook used by extended-nonce variants. */ + extendNonceFn?: ExtendNonceFn; + /** Counter length in bytes inside the nonce/counter layout. */ + counterLength?: number; + /** Whether the layout is `nonce|counter` instead of `counter|nonce`. */ + counterRight?: boolean; + /** Number of core rounds to execute. */ + rounds?: number; +}; + +// Salsa and Chacha block length is always 512-bit +const BLOCK_LEN = 64; +// RFC 8439 §2.2 / RFC 7539 §2.2: the ChaCha state has 16 32-bit words. +const BLOCK_LEN32 = 16; + +// Counter policy for the shared public `counter` argument: +// - RFC/IETF ChaCha20 uses a 32-bit counter. +// - OpenSSL/Node `chacha20` instead treat the full 16-byte IV as a 128-bit +// counter state and carry into the next word. +// - Raw `chacha20orig`, `salsa20`, `xsalsa20`, and `xchacha20` use 64-bit counters in libsodium +// and libtomcrypt, while some libs (for example libtomcrypt's RFC/IETF path) reject the max +// boundary instead of carrying. +// - AEAD wrappers diverge too: libsodium `xchacha20poly1305` uses the IETF payload counter from +// block 1, while `secretstream_xchacha20poly1305` is a different protocol with rekey/reset. +// Noble intentionally throws instead of silently picking one wrap model for users. In the default +// path, even a 32-bit boundary would take 2^32 blocks * 64 bytes = 256 GiB, which is practically +// unreachable for normal JS callers; advanced users who pass `counter` explicitly can implement +// whatever wider carry / wrap policy they need on top. +const MAX_COUNTER = /* @__PURE__ */ (() => 2 ** 32 - 1)(); +const U32_EMPTY = /* @__PURE__ */ Uint32Array.of(); +function runCipher( + core: TArg, + sigma: TArg, + key: TArg, + nonce: TArg, + data: TArg, + output: TArg, + counter: number, + rounds: number +): void { + const len = data.length; + const block = new Uint8Array(BLOCK_LEN); + const b32 = u32(block); + // Make sure that buffers aligned to 4 bytes + const isAligned = isLE && isAligned32(data) && isAligned32(output); + const d32 = isAligned ? u32(data) : U32_EMPTY; + const o32 = isAligned ? u32(output) : U32_EMPTY; + // RFC 8439 §2.4.1 / RFC 7539 §2.4.1 allow XORing one keystream block at a time and + // truncating the final partial block instead of materializing the whole keystream. + if (!isLE) { + for (let pos = 0; pos < len; counter++) { + core( + sigma as TRet, + key as TRet, + nonce as TRet, + b32, + counter, + rounds + ); + // RFC 8439 §2.4 / RFC 7539 §2.4 serialize keystream words in little-endian order. + swap32IfBE(b32); + if (counter >= MAX_COUNTER) throw new Error('arx: counter overflow'); + const take = Math.min(BLOCK_LEN, len - pos); + for (let j = 0, posj; j < take; j++) { + posj = pos + j; + output[posj] = data[posj] ^ block[j]; + } + pos += take; + } + return; + } + for (let pos = 0; pos < len; counter++) { + core( + sigma as TRet, + key as TRet, + nonce as TRet, + b32, + counter, + rounds + ); + // See MAX_COUNTER policy note above: never silently wrap the shared public counter. + if (counter >= MAX_COUNTER) throw new Error('arx: counter overflow'); + const take = Math.min(BLOCK_LEN, len - pos); + // aligned to 4 bytes + if (isAligned && take === BLOCK_LEN) { + const pos32 = pos / 4; + if (pos % 4 !== 0) throw new Error('arx: invalid block position'); + for (let j = 0, posj: number; j < BLOCK_LEN32; j++) { + posj = pos32 + j; + o32[posj] = d32[posj] ^ b32[j]; + } + pos += BLOCK_LEN; + continue; + } + for (let j = 0, posj; j < take; j++) { + posj = pos + j; + output[posj] = data[posj] ^ block[j]; + } + pos += take; + } +} + +/** + * Creates an ARX stream cipher from a 32-bit core permutation. + * Used internally to build the exported Salsa and ChaCha stream ciphers. + * @param core - Core function that fills one keystream block. + * @param opts - Cipher layout and nonce-extension options. See {@link CipherOpts}. + * @returns Stream cipher function over byte arrays. + * @throws If the core callback, key size, counter, or output sizing is invalid. {@link Error} + */ +export function createCipher(core: TArg, opts: TArg): TRet { + const { allowShortKeys, extendNonceFn, counterLength, counterRight, rounds } = checkOpts( + { allowShortKeys: false, counterLength: 8, counterRight: false, rounds: 20 }, + opts + ); + if (typeof core !== 'function') throw new Error('core must be a function'); + anumber(counterLength); + anumber(rounds); + abool(counterRight); + abool(allowShortKeys); + return ( + key: TArg, + nonce: TArg, + data: TArg, + output?: TArg, + counter = 0 + ): TRet => { + abytes(key, undefined, 'key'); + abytes(nonce, undefined, 'nonce'); + abytes(data, undefined, 'data'); + const len = data.length; + // Raw XorStream APIs return ciphertext/plaintext bytes directly, so caller-provided outputs + // must match the logical result length exactly instead of returning an oversized workspace. + output = getOutput(len, output, false); + anumber(counter); + // See MAX_COUNTER policy note above: reject advanced explicit-counter requests before any wrap. + if (counter < 0 || counter >= MAX_COUNTER) throw new Error('arx: counter overflow'); + const toClean = []; + + // Key & sigma + // key=16 -> sigma16, k=key|key + // key=32 -> sigma32, k=key + let l = key.length; + let k: Uint8Array; + let sigma: Uint32Array; + if (l === 32) { + // Copy caller keys too: big-endian normalization, extended-nonce subkey derivation, and + // final clean(...) all mutate or wipe the temporary buffer in place. + toClean.push((k = copyBytes(key))); + sigma = sigma32_32; + } else if (l === 16 && allowShortKeys) { + k = new Uint8Array(32); + k.set(key); + k.set(key, 16); + sigma = sigma16_32; + toClean.push(k); + } else { + abytes(key, 32, 'arx key'); + throw new Error('invalid key size'); + // throw new Error(`"arx key" expected Uint8Array of length 32, got length=${l}`); + } + + // Nonce + // salsa20: 8 (8-byte counter) + // chacha20orig: 8 (8-byte counter) + // chacha20: 12 (4-byte counter) + // xsalsa20: 24 (16 -> hsalsa, 8 -> old nonce) + // xchacha20: 24 (16 -> hchacha, 8 -> old nonce) + // Copy before taking u32(...) views on misaligned inputs, and on big-endian so later + // swap32IfBE(...) never mutates caller nonce bytes in place. + if (!isLE || !isAligned32(nonce)) toClean.push((nonce = copyBytes(nonce))); + + let k32 = u32(k); + // hsalsa & hchacha: handle extended nonce + if (extendNonceFn) { + if (nonce.length !== 24) throw new Error(`arx: extended nonce must be 24 bytes`); + const n16 = nonce.subarray(0, 16); + if (isLE) extendNonceFn(sigma as TRet, k32, u32(n16), k32); + else { + const sigmaRaw = swap32IfBE(Uint32Array.from(sigma)); + extendNonceFn(sigmaRaw, k32, u32(n16), k32); + clean(sigmaRaw); + swap32IfBE(k32); + } + nonce = nonce.subarray(16); + } else if (!isLE) swap32IfBE(k32); + + // Handle nonce counter + const nonceNcLen = 16 - counterLength; + if (nonceNcLen !== nonce.length) + throw new Error(`arx: nonce must be ${nonceNcLen} or 16 bytes`); + + // Normalize 64-bit-nonce layouts to the 12-byte core input: ChaCha/XChaCha prefix 4 zero + // counter bytes, while Salsa/XSalsa append them after the nonce words. + if (nonceNcLen !== 12) { + const nc = new Uint8Array(12); + nc.set(nonce, counterRight ? 0 : 12 - nonce.length); + nonce = nc; + toClean.push(nonce); + } + const n32 = swap32IfBE(u32(nonce)); + // Ensure temporary key/nonce copies are wiped even if the remaining + // runtime guard in runCipher(...) throws on counter overflow. + try { + runCipher(core, sigma, k32, n32, data, output, counter, rounds); + return output as TRet; + } finally { + clean(...toClean); + } + }; +} + +/** Internal class which wraps chacha20 or chacha8 to create CSPRNG. */ +export class _XorStreamPRG implements PRG { + readonly blockLen: number; + readonly keyLen: number; + readonly nonceLen: number; + private state: TRet; + private buf: TRet; + private key: TRet; + private nonce: TRet; + private pos: number; + private ctr: number; + private cipher: TArg; + constructor( + cipher: TArg, + blockLen: number, + keyLen: number, + nonceLen: number, + seed: TArg + ) { + this.cipher = cipher; + this.blockLen = blockLen; + this.keyLen = keyLen; + this.nonceLen = nonceLen; + this.state = new Uint8Array(this.keyLen + this.nonceLen) as TRet; + this.reseed(seed); + this.ctr = 0; + this.pos = this.blockLen; + this.buf = new Uint8Array(this.blockLen) as TRet; + // Keep a single key||nonce backing buffer so reseed/addEntropy/clean update the live cipher + // inputs in place through these subarray views. + this.key = this.state.subarray(0, this.keyLen) as TRet; + this.nonce = this.state.subarray(this.keyLen) as TRet; + } + private reseed(seed: TArg) { + abytes(seed); + if (!seed || seed.length === 0) throw new Error('entropy required'); + // Mix variable-length entropy cyclically across the whole key||nonce state, then restart the + // keystream so buffered leftovers from the previous state are never reused. + for (let i = 0; i < seed.length; i++) this.state[i % this.state.length] ^= seed[i]; + this.ctr = 0; + this.pos = this.blockLen; + } + addEntropy(seed: TArg): void { + // Reject empty entropy before re-keying, otherwise a throwing call would still advance state. + abytes(seed); + if (seed.length === 0) throw new Error('entropy required'); + // Re-key from the current stream first, then mix external entropy into the fresh key||nonce + // state through reseed() so stale buffered bytes are discarded. + this.state.set(this.randomBytes(this.state.length)); + this.reseed(seed); + } + randomBytes(len: number): TRet { + anumber(len); + if (len === 0) return new Uint8Array(0) as TRet; + const avail = this.pos < this.blockLen ? this.blockLen - this.pos : 0; + const blocks = Math.ceil(Math.max(0, len - avail) / this.blockLen); + // Preflight overflow so failed reads don't partially consume keystream + // and leave the PRG repeating blocks. + if (blocks > 0 && this.ctr > MAX_COUNTER - blocks) throw new Error('arx: counter overflow'); + const out = new Uint8Array(len); + let outPos = 0; + // `out` starts zero-filled, and `buf.fill(0)` below does the same for leftovers: XOR-stream + // ciphers then emit raw keystream bytes directly into those buffers. + // Serve buffered leftovers first so split reads stay identical to one larger read. + if (this.pos < this.blockLen) { + const take = Math.min(len, this.blockLen - this.pos); + out.set(this.buf.subarray(this.pos, this.pos + take), 0); + this.pos += take; + outPos += take; + if (outPos === len) return out as TRet; // fast path + } + // Full blocks directly to out + const full = Math.floor((len - outPos) / this.blockLen); + if (full > 0) { + const blockBytes = full * this.blockLen; + const b = out.subarray(outPos, outPos + blockBytes); + this.cipher(this.key, this.nonce, b as TRet, b as TRet, this.ctr); + this.ctr += full; + outPos += blockBytes; + } + // Save leftovers + const left = len - outPos; + if (left > 0) { + this.buf.fill(0); + // NOTE: cipher will handle overflow + this.cipher( + this.key, + this.nonce, + this.buf as TRet, + this.buf as TRet, + this.ctr++ + ); + out.set(this.buf.subarray(0, left), outPos); + this.pos = left; + } + return out as TRet; + } + // Clone seeds the new instance from this stream, so the source PRG advances too. + clone(): _XorStreamPRG { + return new _XorStreamPRG( + this.cipher, + this.blockLen, + this.keyLen, + this.nonceLen, + this.randomBytes(this.state.length) + ); + } + // Zeroes the current state and leftover buffer, but does not make the instance unusable: + // Later reads first drain zeros from the cleared buffer and then continue + // from zero key||nonce state. + clean(): void { + this.pos = 0; + this.ctr = 0; + this.buf.fill(0); + this.state.fill(0); + } +} + +/** + * PRG constructor backed by an ARX stream cipher. + * @param seed - Optional seed bytes mixed into the initial state. When omitted, exactly 32 + * random bytes are mixed in by default: larger states keep a zero tail, while smaller states + * wrap those bytes through `reseed()`'s XOR schedule. + * @returns Seeded concrete `_XorStreamPRG` instance, including `clone()`. + */ +export type XorPRG = (seed?: TArg) => TRet<_XorStreamPRG>; + +/** + * Creates a PRG constructor from a stream cipher. + * @param cipher - Stream cipher used to fill output blocks. + * @param blockLen - Keystream block length in bytes. + * @param keyLen - Internal key length in bytes. + * @param nonceLen - Internal nonce length in bytes. + * @returns PRG factory for seeded concrete `_XorStreamPRG` instances. + * @example + * Builds a PRG from XChaCha20 and reads bytes from a randomly seeded instance. + * ```ts + * import { xchacha20 } from '@noble/ciphers/chacha.js'; + * import { createPRG } from '@noble/ciphers/_arx.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const seed = randomBytes(32); + * const init = createPRG(xchacha20, 64, 32, 24); + * const prg = init(seed); + * prg.randomBytes(8); + * ``` + */ +export const createPRG = ( + cipher: TArg, + blockLen: number, + keyLen: number, + nonceLen: number +): TRet => { + return ((seed: TArg = randomBytes(32)): TRet<_XorStreamPRG> => + new _XorStreamPRG( + cipher, + blockLen, + keyLen, + nonceLen, + seed + ) as TRet<_XorStreamPRG>) as TRet; +}; diff --git a/node_modules/@noble/ciphers/src/_poly1305.ts b/node_modules/@noble/ciphers/src/_poly1305.ts new file mode 100644 index 0000000..351a479 --- /dev/null +++ b/node_modules/@noble/ciphers/src/_poly1305.ts @@ -0,0 +1,399 @@ +/** + * Poly1305 ({@link https://cr.yp.to/mac/poly1305-20050329.pdf | PDF}, + * {@link https://en.wikipedia.org/wiki/Poly1305 | wiki}) + * is a fast and parallel secret-key message-authentication code suitable for + * a wide variety of applications. It was standardized in + * {@link https://www.rfc-editor.org/rfc/rfc8439 | RFC 8439} and is now used in TLS 1.3. + * + * Polynomial MACs are not perfect for every situation: + * they lack Random Key Robustness: the MAC can be forged, and can't be used in PAKE schemes. + * See {@link https://keymaterial.net/2020/09/07/invisible-salamanders-in-aes-gcm-siv/ | the invisible salamanders attack writeup}. + * To combat invisible salamanders, `hash(key)` can be included in ciphertext, + * however, this would violate ciphertext indistinguishability: + * an attacker would know which key was used - so `HKDF(key, i)` + * could be used instead. + * + * Check out the {@link https://cr.yp.to/mac.html | original website}. + * Based on public-domain {@link https://github.com/floodyberry/poly1305-donna | poly1305-donna}. + * @module + */ +// prettier-ignore +import { + abytes, aexists, aoutput, bytesToHex, + clean, concatBytes, copyBytes, hexToNumber, numberToBytesBE, + wrapMacConstructor, type CMac, type IHash2, type TArg, type TRet +} from './utils.ts'; + +// Little-endian 2-byte load used by the Poly1305 limb decomposition. +function u8to16(a: TArg, i: number) { + return (a[i++] & 0xff) | ((a[i++] & 0xff) << 8); +} + +function bytesToNumberLE(bytes: TArg): bigint { + return hexToNumber(bytesToHex(Uint8Array.from(bytes).reverse())); +} + +/** Small version of `poly1305` without loop unrolling. Unused, provided for auditability. */ +function poly1305_small(msg: TArg, key: TArg): TRet { + abytes(msg); + abytes(key, 32, 'key'); + const POW_2_130_5 = BigInt(2) ** BigInt(130) - BigInt(5); // 2^130-5 + const POW_2_128_1 = BigInt(2) ** BigInt(128) - BigInt(1); // 2^128-1 + const CLAMP_R = BigInt('0x0ffffffc0ffffffc0ffffffc0fffffff'); + const r = bytesToNumberLE(key.subarray(0, 16)) & CLAMP_R; + const s = bytesToNumberLE(key.subarray(16)); + // Process by 16 byte chunks + let acc = BigInt(0); + for (let i = 0; i < msg.length; i += 16) { + const m = msg.subarray(i, i + 16); + // RFC 8439 §2.5.1 / RFC 7539 §2.5.1 append [0x01] to each chunk before multiplying by r. + const n = bytesToNumberLE(m) | (BigInt(1) << BigInt(8 * m.length)); + acc = ((acc + n) * r) % POW_2_130_5; + } + const res = (acc + s) & POW_2_128_1; + // RFC 8439 §2.5 / RFC 7539 §2.5 serialize the low 128 bits in little-endian order. + return numberToBytesBE(res, 16).reverse() as TRet; // LE +} + +// Can be used to replace `computeTag` in chacha.ts. Unused, provided for auditability. +// @ts-expect-error +function poly1305_computeTag_small( + authKey: TArg, + // AEAD trailer must already be the 16-byte length block: + // 8-byte little-endian AAD length || 8-byte little-endian ciphertext length. + lengths: TArg, + ciphertext: TArg, + AAD?: TArg +): TRet { + // RFC 8439 §2.8.1 / RFC 7539 §2.8.1 MAC input is + // AAD || pad16(AAD) || ciphertext || pad16(ciphertext) || lengths. + const res = []; + const updatePadded2 = (msg: TArg) => { + res.push(msg); + const leftover = msg.length % 16; + // RFC 8439 §2.8.1 / RFC 7539 §2.8.1: pad16(x) is empty for aligned + // inputs, else 16-(len%16) zero bytes. + if (leftover) res.push(new Uint8Array(16).slice(leftover)); + }; + if (AAD) updatePadded2(AAD); + updatePadded2(ciphertext); + res.push(lengths); + return poly1305_small(concatBytes(...res), authKey); +} + +/** + * Incremental Poly1305 MAC state. + * Prefer `poly1305()` for one-shot use. + * @param key - 32-byte Poly1305 one-time key. + * @example + * Feeds one chunk into an incremental Poly1305 state with a fresh one-time key. + * + * ```ts + * import { Poly1305 } from '@noble/ciphers/_poly1305.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(32); + * const mac = new Poly1305(key); + * mac.update(new Uint8Array([1, 2, 3])); + * mac.digest(); + * ``` + */ +export class Poly1305 implements IHash2 { + readonly blockLen = 16; + readonly outputLen = 16; + private buffer = new Uint8Array(16); + private r = new Uint16Array(10); // Allocating 1 array with .subarray() here is slower than 3 + private h = new Uint16Array(10); + private pad = new Uint16Array(8); + private pos = 0; + protected finished = false; + protected destroyed = false; + + // Can be speed-up using BigUint64Array, at the cost of complexity + constructor(key: TArg) { + key = copyBytes(abytes(key, 32, 'key')); + const t0 = u8to16(key, 0); + const t1 = u8to16(key, 2); + const t2 = u8to16(key, 4); + const t3 = u8to16(key, 6); + const t4 = u8to16(key, 8); + const t5 = u8to16(key, 10); + const t6 = u8to16(key, 12); + const t7 = u8to16(key, 14); + + // RFC 8439 §2.5.1 / RFC 7539 §2.5.1 clamp r before multiplication. + // These masks unpack that clamped value into 13-bit limbs, while pad + // keeps the raw s half for finalize(). + // {@link https://github.com/floodyberry/poly1305-donna/blob/e6ad6e091d30d7f4ec2d4f978be1fcfcbce72781/poly1305-donna-16.h#L47 | poly1305-donna reference} + this.r[0] = t0 & 0x1fff; + this.r[1] = ((t0 >>> 13) | (t1 << 3)) & 0x1fff; + this.r[2] = ((t1 >>> 10) | (t2 << 6)) & 0x1f03; + this.r[3] = ((t2 >>> 7) | (t3 << 9)) & 0x1fff; + this.r[4] = ((t3 >>> 4) | (t4 << 12)) & 0x00ff; + this.r[5] = (t4 >>> 1) & 0x1ffe; + this.r[6] = ((t4 >>> 14) | (t5 << 2)) & 0x1fff; + this.r[7] = ((t5 >>> 11) | (t6 << 5)) & 0x1f81; + this.r[8] = ((t6 >>> 8) | (t7 << 8)) & 0x1fff; + this.r[9] = (t7 >>> 5) & 0x007f; + for (let i = 0; i < 8; i++) this.pad[i] = u8to16(key, 16 + 2 * i); + } + + private process(data: TArg, offset: number, isLast = false) { + // RFC 8439 §2.5 / §2.5.1 and RFC 7539 §2.5 / §2.5.1 add an extra high + // bit to every full 16-byte block. The final partial block gets its + // explicit `1` byte during digestInto(), so `hibit` stays zero there. + const hibit = isLast ? 0 : 1 << 11; + const { h, r } = this; + const r0 = r[0]; + const r1 = r[1]; + const r2 = r[2]; + const r3 = r[3]; + const r4 = r[4]; + const r5 = r[5]; + const r6 = r[6]; + const r7 = r[7]; + const r8 = r[8]; + const r9 = r[9]; + + const t0 = u8to16(data, offset + 0); + const t1 = u8to16(data, offset + 2); + const t2 = u8to16(data, offset + 4); + const t3 = u8to16(data, offset + 6); + const t4 = u8to16(data, offset + 8); + const t5 = u8to16(data, offset + 10); + const t6 = u8to16(data, offset + 12); + const t7 = u8to16(data, offset + 14); + + let h0 = h[0] + (t0 & 0x1fff); + let h1 = h[1] + (((t0 >>> 13) | (t1 << 3)) & 0x1fff); + let h2 = h[2] + (((t1 >>> 10) | (t2 << 6)) & 0x1fff); + let h3 = h[3] + (((t2 >>> 7) | (t3 << 9)) & 0x1fff); + let h4 = h[4] + (((t3 >>> 4) | (t4 << 12)) & 0x1fff); + let h5 = h[5] + ((t4 >>> 1) & 0x1fff); + let h6 = h[6] + (((t4 >>> 14) | (t5 << 2)) & 0x1fff); + let h7 = h[7] + (((t5 >>> 11) | (t6 << 5)) & 0x1fff); + let h8 = h[8] + (((t6 >>> 8) | (t7 << 8)) & 0x1fff); + let h9 = h[9] + ((t7 >>> 5) | hibit); + + let c = 0; + + let d0 = c + h0 * r0 + h1 * (5 * r9) + h2 * (5 * r8) + h3 * (5 * r7) + h4 * (5 * r6); + c = d0 >>> 13; + d0 &= 0x1fff; + d0 += h5 * (5 * r5) + h6 * (5 * r4) + h7 * (5 * r3) + h8 * (5 * r2) + h9 * (5 * r1); + c += d0 >>> 13; + d0 &= 0x1fff; + + let d1 = c + h0 * r1 + h1 * r0 + h2 * (5 * r9) + h3 * (5 * r8) + h4 * (5 * r7); + c = d1 >>> 13; + d1 &= 0x1fff; + d1 += h5 * (5 * r6) + h6 * (5 * r5) + h7 * (5 * r4) + h8 * (5 * r3) + h9 * (5 * r2); + c += d1 >>> 13; + d1 &= 0x1fff; + + let d2 = c + h0 * r2 + h1 * r1 + h2 * r0 + h3 * (5 * r9) + h4 * (5 * r8); + c = d2 >>> 13; + d2 &= 0x1fff; + d2 += h5 * (5 * r7) + h6 * (5 * r6) + h7 * (5 * r5) + h8 * (5 * r4) + h9 * (5 * r3); + c += d2 >>> 13; + d2 &= 0x1fff; + + let d3 = c + h0 * r3 + h1 * r2 + h2 * r1 + h3 * r0 + h4 * (5 * r9); + c = d3 >>> 13; + d3 &= 0x1fff; + d3 += h5 * (5 * r8) + h6 * (5 * r7) + h7 * (5 * r6) + h8 * (5 * r5) + h9 * (5 * r4); + c += d3 >>> 13; + d3 &= 0x1fff; + + let d4 = c + h0 * r4 + h1 * r3 + h2 * r2 + h3 * r1 + h4 * r0; + c = d4 >>> 13; + d4 &= 0x1fff; + d4 += h5 * (5 * r9) + h6 * (5 * r8) + h7 * (5 * r7) + h8 * (5 * r6) + h9 * (5 * r5); + c += d4 >>> 13; + d4 &= 0x1fff; + + let d5 = c + h0 * r5 + h1 * r4 + h2 * r3 + h3 * r2 + h4 * r1; + c = d5 >>> 13; + d5 &= 0x1fff; + d5 += h5 * r0 + h6 * (5 * r9) + h7 * (5 * r8) + h8 * (5 * r7) + h9 * (5 * r6); + c += d5 >>> 13; + d5 &= 0x1fff; + + let d6 = c + h0 * r6 + h1 * r5 + h2 * r4 + h3 * r3 + h4 * r2; + c = d6 >>> 13; + d6 &= 0x1fff; + d6 += h5 * r1 + h6 * r0 + h7 * (5 * r9) + h8 * (5 * r8) + h9 * (5 * r7); + c += d6 >>> 13; + d6 &= 0x1fff; + + let d7 = c + h0 * r7 + h1 * r6 + h2 * r5 + h3 * r4 + h4 * r3; + c = d7 >>> 13; + d7 &= 0x1fff; + d7 += h5 * r2 + h6 * r1 + h7 * r0 + h8 * (5 * r9) + h9 * (5 * r8); + c += d7 >>> 13; + d7 &= 0x1fff; + + let d8 = c + h0 * r8 + h1 * r7 + h2 * r6 + h3 * r5 + h4 * r4; + c = d8 >>> 13; + d8 &= 0x1fff; + d8 += h5 * r3 + h6 * r2 + h7 * r1 + h8 * r0 + h9 * (5 * r9); + c += d8 >>> 13; + d8 &= 0x1fff; + + let d9 = c + h0 * r9 + h1 * r8 + h2 * r7 + h3 * r6 + h4 * r5; + c = d9 >>> 13; + d9 &= 0x1fff; + d9 += h5 * r4 + h6 * r3 + h7 * r2 + h8 * r1 + h9 * r0; + c += d9 >>> 13; + d9 &= 0x1fff; + + c = ((c << 2) + c) | 0; + c = (c + d0) | 0; + d0 = c & 0x1fff; + c = c >>> 13; + d1 += c; + + h[0] = d0; + h[1] = d1; + h[2] = d2; + h[3] = d3; + h[4] = d4; + h[5] = d5; + h[6] = d6; + h[7] = d7; + h[8] = d8; + h[9] = d9; + } + + private finalize() { + const { h, pad } = this; + const g = new Uint16Array(10); + let c = h[1] >>> 13; + h[1] &= 0x1fff; + for (let i = 2; i < 10; i++) { + h[i] += c; + c = h[i] >>> 13; + h[i] &= 0x1fff; + } + h[0] += c * 5; + c = h[0] >>> 13; + h[0] &= 0x1fff; + h[1] += c; + c = h[1] >>> 13; + h[1] &= 0x1fff; + h[2] += c; + + // RFC 8439 §2.5 / RFC 7539 §2.5 reduce modulo 2^130-5 before repacking + // to 16-bit words and adding the raw s half. + g[0] = h[0] + 5; + c = g[0] >>> 13; + g[0] &= 0x1fff; + for (let i = 1; i < 10; i++) { + g[i] = h[i] + c; + c = g[i] >>> 13; + g[i] &= 0x1fff; + } + g[9] -= 1 << 13; + + let mask = (c ^ 1) - 1; + for (let i = 0; i < 10; i++) g[i] &= mask; + mask = ~mask; + for (let i = 0; i < 10; i++) h[i] = (h[i] & mask) | g[i]; + h[0] = (h[0] | (h[1] << 13)) & 0xffff; + h[1] = ((h[1] >>> 3) | (h[2] << 10)) & 0xffff; + h[2] = ((h[2] >>> 6) | (h[3] << 7)) & 0xffff; + h[3] = ((h[3] >>> 9) | (h[4] << 4)) & 0xffff; + h[4] = ((h[4] >>> 12) | (h[5] << 1) | (h[6] << 14)) & 0xffff; + h[5] = ((h[6] >>> 2) | (h[7] << 11)) & 0xffff; + h[6] = ((h[7] >>> 5) | (h[8] << 8)) & 0xffff; + h[7] = ((h[8] >>> 8) | (h[9] << 5)) & 0xffff; + + let f = h[0] + pad[0]; + h[0] = f & 0xffff; + for (let i = 1; i < 8; i++) { + f = (((h[i] + pad[i]) | 0) + (f >>> 16)) | 0; + h[i] = f & 0xffff; + } + clean(g); + } + update(data: TArg): this { + aexists(this); + abytes(data); + data = copyBytes(data); + const { buffer, blockLen } = this; + const len = data.length; + + for (let pos = 0; pos < len; ) { + const take = Math.min(blockLen - this.pos, len - pos); + // Fast path: we have at least one block in input + if (take === blockLen) { + for (; blockLen <= len - pos; pos += blockLen) this.process(data, pos); + continue; + } + buffer.set(data.subarray(pos, pos + take), this.pos); + this.pos += take; + pos += take; + if (this.pos === blockLen) { + this.process(buffer, 0, false); + this.pos = 0; + } + } + return this; + } + destroy(): void { + // `aexists(this)` guards update/digest paths, so destroy must mark the instance unusable too. + this.destroyed = true; + clean(this.h, this.r, this.buffer, this.pad); + } + digestInto(out: TArg): void { + aexists(this); + aoutput(out, this); + this.finished = true; + const { buffer, h } = this; + let { pos } = this; + if (pos) { + // RFC 8439 §2.5 / RFC 7539 §2.5: the final short block appends a + // single `0x01` byte and zero-fills the remaining bytes before the + // last multiplication step. + buffer[pos++] = 1; + for (; pos < 16; pos++) buffer[pos] = 0; + this.process(buffer, 0, true); + } + this.finalize(); + let opos = 0; + for (let i = 0; i < 8; i++) { + out[opos++] = h[i] >>> 0; + out[opos++] = h[i] >>> 8; + } + } + digest(): TRet { + const { buffer, outputLen } = this; + this.digestInto(buffer); + // Copy out before destroy() zeroes the internal buffer. + const res = buffer.slice(0, outputLen); + this.destroy(); + return res as TRet; + } +} + +/** One-shot keyed hash helper with `.create()`. */ +export type CHash = CMac; + +/** + * Poly1305 MAC from RFC 8439. + * @param msg - Message bytes to authenticate. + * @param key - 32-byte Poly1305 one-time key. + * @returns 16-byte authentication tag. + * @example + * Authenticates one message with a one-shot Poly1305 call and a fresh key. + * + * ```ts + * import { poly1305 } from '@noble/ciphers/_poly1305.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(32); + * poly1305(new Uint8Array(), key); + * ``` + */ +export const poly1305: TRet = /* @__PURE__ */ wrapMacConstructor( + 32, + (key: TArg) => new Poly1305(key) +); diff --git a/node_modules/@noble/ciphers/src/_polyval.ts b/node_modules/@noble/ciphers/src/_polyval.ts new file mode 100644 index 0000000..f94b885 --- /dev/null +++ b/node_modules/@noble/ciphers/src/_polyval.ts @@ -0,0 +1,381 @@ +/** + * GHash from AES-GCM and its little-endian "mirror image" Polyval from AES-SIV. + * + * Implemented in terms of GHash with conversion function for keys + * GCM GHASH from + * {@link https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf | NIST SP800-38d}, + * SIV from + * {@link https://www.rfc-editor.org/rfc/rfc8452 | RFC 8452}. + * + * GHASH modulo: x^128 + x^7 + x^2 + x + 1 + * POLYVAL modulo: x^128 + x^127 + x^126 + x^121 + 1 + * + * @module + */ +import { + abytes, + aexists, + aoutput, + clean, + copyBytes, + createView, + swap32IfBE, + swap8IfBE, + u32, + wrapMacConstructor, + type CMac, + type IHash2, + type TArg, + type TRet, +} from './utils.ts'; + +const BLOCK_SIZE = 16; +// TODO: rewrite +// temporary padding buffer +// ZEROS32 aliases these bytes, so clean(ZEROS32) also resets this shared tail-padding scratch. +const ZEROS16 = /* @__PURE__ */ new Uint8Array(16); +const ZEROS32 = /* @__PURE__ */ u32(ZEROS16); +// GHASH reduces modulo x^128 + x^7 + x^2 + x + 1, so the low-degree terms +// x^7 + x^2 + x + 1 become bits `11100001` = 0xe1 in R = 0xe1 || 0^120. +const POLY = 0xe1; + +// v = 2*v % POLY +// NOTE: because x + x = 0 (add/sub is same), mul2(x) != x+x +// Montgomery ladder can multiply any field element with this doubling step; +// addition stays simple xor. +const mul2 = (s0: number, s1: number, s2: number, s3: number) => { + const hiBit = s3 & 1; + return { + s3: (s2 << 31) | (s3 >>> 1), + s2: (s1 << 31) | (s2 >>> 1), + s1: (s0 << 31) | (s1 >>> 1), + // NIST SP 800-38D §6.3 applies `V >> 1` and XORs R on carry. In this + // 4x32-bit split, R = 0xe1 || 0^120 lives in the top byte of s0. + s0: (s0 >>> 1) ^ ((POLY << 24) & -(hiBit & 1)), // reduce % poly + }; +}; + +// Per-word part of RFC 8452 `ByteReverse`; callers also reverse the 32-bit word order. +const swapLE = (n: number) => + (((n >>> 0) & 0xff) << 24) | + (((n >>> 8) & 0xff) << 16) | + (((n >>> 16) & 0xff) << 8) | + ((n >>> 24) & 0xff) | + 0; +// POLYVAL first applies RFC 8452's per-word byte reversal, then re-normalizes +// host-endian u32 loads to the little-endian word value `_updateBlock()` expects. +const swap8IfLE = (n: number) => swap8IfBE(swapLE(n)); + +/** + * `mulX_GHASH(ByteReverse(H))` from RFC 8452 Appendix A. + * @param k mutated in place + */ +export function _toGHASHKey(k: TArg): TRet { + // The input is the original POLYVAL key H; reverse() materializes + // RFC 8452's `ByteReverse(H)` before the GHASH mulX step. + k.reverse(); + const hiBit = k[15] & 1; + // k >>= 1 + let carry = 0; + for (let i = 0; i < k.length; i++) { + const t = k[i]; + k[i] = (t >>> 1) | carry; + carry = (t & 1) << 7; + } + k[0] ^= -hiBit & 0xe1; // if (hiBit) n ^= 0xe1000000000000000000000000000000; + return k as TRet; +} + +type Value = { s0: number; s1: number; s2: number; s3: number }; + +// Precompute-window heuristic only: larger inputs trade memory for fewer table lookups. +// Any caller-provided length hint still collapses to one of the supported windows {2, 4, 8}. +const estimateWindow = (bytes: number) => { + if (bytes > 64 * 1024) return 8; + if (bytes > 1024) return 4; + return 2; +}; + +/** + * Incremental GHASH state for AES-GCM. + * @param key - 16-byte GHASH key. + * @param expectedLength - Expected message length for table sizing. + * Chunking is segment-based, not hash-streaming: every `update()` call is zero-padded + * to the next 16-byte boundary before it is absorbed. This matches the internal AES/GCM + * use where AAD, payload, and length block are separate padded segments. + * @example + * Feeds one ciphertext block into an incremental GHASH state with a fresh hash key. + * + * ```ts + * import { GHASH } from '@noble/ciphers/_polyval.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(16); + * const mac = new GHASH(key); + * mac.update(new Uint8Array(16)); + * mac.digest(); + * ``` + */ +export class GHASH implements IHash2 { + readonly blockLen: number = BLOCK_SIZE; + readonly outputLen: number = BLOCK_SIZE; + protected s0 = 0; + protected s1 = 0; + protected s2 = 0; + protected s3 = 0; + protected finished = false; + protected destroyed = false; + protected t: Value[]; + private W: number; + private windowSize: number; + // We select bits per window adaptively based on expectedLength + constructor(key: TArg, expectedLength?: number) { + abytes(key, 16, 'key'); + key = copyBytes(key); + const kView = createView(key); + let k0 = kView.getUint32(0, false); + let k1 = kView.getUint32(4, false); + let k2 = kView.getUint32(8, false); + let k3 = kView.getUint32(12, false); + // generate table of doubled keys (half of montgomery ladder) + const doubles: Value[] = []; + for (let i = 0; i < 128; i++) { + doubles.push({ s0: swapLE(k0), s1: swapLE(k1), s2: swapLE(k2), s3: swapLE(k3) }); + ({ s0: k0, s1: k1, s2: k2, s3: k3 } = mul2(k0, k1, k2, k3)); + } + const W = estimateWindow(expectedLength || 1024); + if (![1, 2, 4, 8].includes(W)) + throw new Error('ghash: invalid window size, expected 2, 4 or 8'); + this.W = W; + const bits = 128; // always 128 bits; + const windows = bits / W; + const windowSize = (this.windowSize = 2 ** W); + const items: Value[] = []; + // Create precompute table for window of W bits + for (let w = 0; w < windows; w++) { + // truth table: 00, 01, 10, 11 + for (let byte = 0; byte < windowSize; byte++) { + // prettier-ignore + let s0 = 0, s1 = 0, s2 = 0, s3 = 0; + for (let j = 0; j < W; j++) { + const bit = (byte >>> (W - j - 1)) & 1; + if (!bit) continue; + const { s0: d0, s1: d1, s2: d2, s3: d3 } = doubles[W * w + j]; + ((s0 ^= d0), (s1 ^= d1), (s2 ^= d2), (s3 ^= d3)); + } + items.push({ s0, s1, s2, s3 }); + } + } + this.t = items; + } + protected _updateBlock(s0: number, s1: number, s2: number, s3: number): void { + ((s0 ^= this.s0), (s1 ^= this.s1), (s2 ^= this.s2), (s3 ^= this.s3)); + const { W, t, windowSize } = this; + // prettier-ignore + let o0 = 0, o1 = 0, o2 = 0, o3 = 0; + const mask = (1 << W) - 1; // 2**W will kill performance. + let w = 0; + // NIST SP 800-38D §6.3 interprets blocks as little-endian polynomials, + // so the lookup walk consumes each word byte-by-byte from + // least-significant to most-significant bits. + for (const num of [s0, s1, s2, s3]) { + for (let bytePos = 0; bytePos < 4; bytePos++) { + const byte = (num >>> (8 * bytePos)) & 0xff; + for (let bitPos = 8 / W - 1; bitPos >= 0; bitPos--) { + const bit = (byte >>> (W * bitPos)) & mask; + const { s0: e0, s1: e1, s2: e2, s3: e3 } = t[w * windowSize + bit]; + ((o0 ^= e0), (o1 ^= e1), (o2 ^= e2), (o3 ^= e3)); + w += 1; + } + } + } + this.s0 = o0; + this.s1 = o1; + this.s2 = o2; + this.s3 = o3; + } + update(data: TArg): this { + aexists(this); + abytes(data); + data = copyBytes(data); + const b32 = u32(data); + const blocks = Math.floor(data.length / BLOCK_SIZE); + const left = data.length % BLOCK_SIZE; + for (let i = 0; i < blocks; i++) { + this._updateBlock( + swap8IfBE(b32[i * 4 + 0]), + swap8IfBE(b32[i * 4 + 1]), + swap8IfBE(b32[i * 4 + 2]), + swap8IfBE(b32[i * 4 + 3]) + ); + } + if (left) { + ZEROS16.set(data.subarray(blocks * BLOCK_SIZE)); + // Tail blocks go through the shared ZEROS32 scratch, so they need the same host-endian + // normalization as full blocks; otherwise segmented GHASH/POLYVAL updates diverge on BE. + this._updateBlock( + swap8IfBE(ZEROS32[0]), + swap8IfBE(ZEROS32[1]), + swap8IfBE(ZEROS32[2]), + swap8IfBE(ZEROS32[3]) + ); + clean(ZEROS32); // clean tmp buffer + } + return this; + } + destroy(): void { + // `aexists(this)` guards update/digest paths, so destroy must mark the instance unusable too. + this.destroyed = true; + const { t } = this; + // Wipe the key-derived precompute table; scalar accumulator words remain, + // but the destroyed guard blocks further use. + // clean precompute table + for (const elm of t) { + ((elm.s0 = 0), (elm.s1 = 0), (elm.s2 = 0), (elm.s3 = 0)); + } + } + digestInto(out: TArg): void { + aexists(this); + // `digestInto(out)` is the no-allocation fast path, so callers must pass a + // 32-bit-aligned buffer before we reinterpret it with `u32(out)`. + aoutput(out, this, true); + this.finished = true; + // NIST SP 800-38D §6.4 returns the final 128-bit block Y_m. + // `digestInto()` follows the relaxed `aoutput()` contract, so only + // out[0..15] may be touched. + const { s0, s1, s2, s3 } = this; + const o32 = u32(out); + o32[0] = s0; + o32[1] = s1; + o32[2] = s2; + o32[3] = s3; + swap32IfBE(o32); + } + digest(): TRet { + const res = new Uint8Array(BLOCK_SIZE); + this.digestInto(res); + // `res` is independent of internal state, so it stays valid after destroy() wipes the table. + this.destroy(); + return res as TRet; + } +} + +/** + * Incremental POLYVAL state for AES-SIV. + * @param key - 16-byte POLYVAL key. + * @param expectedLength - Expected message length for table sizing. + * Inherits GHASH's segment-padded `update()` behavior: each call is padded + * independently to a 16-byte boundary before absorption. + * @example + * Feeds one block into an incremental POLYVAL state with a fresh hash key. + * + * ```ts + * import { Polyval } from '@noble/ciphers/_polyval.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(16); + * const mac = new Polyval(key); + * mac.update(new Uint8Array(16)); + * mac.digest(); + * ``` + */ +export class Polyval extends GHASH { + constructor(key: TArg, expectedLength?: number) { + abytes(key); + // RFC 8452 Appendix A converts the POLYVAL key with + // `mulX_GHASH(ByteReverse(H))`; copy first because `_toGHASHKey(...)` + // mutates in place. + const ghKey = _toGHASHKey(copyBytes(key)); + super(ghKey, expectedLength); + clean(ghKey); + } + update(data: TArg): this { + aexists(this); + abytes(data); + data = copyBytes(data); + const b32 = u32(data); + const left = data.length % BLOCK_SIZE; + const blocks = Math.floor(data.length / BLOCK_SIZE); + for (let i = 0; i < blocks; i++) { + // RFC 8452 Appendix A feeds `ByteReverse(X_i)` into GHASH, so POLYVAL + // reverses the 32-bit word order in addition to the per-word byte swap. + this._updateBlock( + swap8IfLE(b32[i * 4 + 3]), + swap8IfLE(b32[i * 4 + 2]), + swap8IfLE(b32[i * 4 + 1]), + swap8IfLE(b32[i * 4 + 0]) + ); + } + if (left) { + ZEROS16.set(data.subarray(blocks * BLOCK_SIZE)); + this._updateBlock( + swap8IfLE(ZEROS32[3]), + swap8IfLE(ZEROS32[2]), + swap8IfLE(ZEROS32[1]), + swap8IfLE(ZEROS32[0]) + ); + clean(ZEROS32); + } + return this; + } + digestInto(out: TArg): void { + aexists(this); + // `digestInto(out)` is the no-allocation fast path, so callers must pass a + // 32-bit-aligned buffer before we reinterpret the output prefix with `u32(view)`. + aoutput(out, this, true); + this.finished = true; + // RFC 8452 Appendix A maps POLYVAL output back through `ByteReverse(...)`. + // `digestInto()` follows the relaxed `aoutput()` contract, so only out[0..15] may be touched. + const view = out.subarray(0, this.outputLen); + const { s0, s1, s2, s3 } = this; + const o32 = u32(view); + o32[0] = s0; + o32[1] = s1; + o32[2] = s2; + o32[3] = s3; + swap32IfBE(o32); + view.reverse(); + } +} + +/** + * GHash MAC for AES-GCM. + * @param msg - Message bytes to authenticate. + * @param key - 16-byte GHASH key. + * @returns 16-byte authentication tag. + * @example + * Authenticates a short message with GHASH and a fresh hash key. + * + * ```ts + * import { ghash } from '@noble/ciphers/_polyval.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(16); + * ghash(new Uint8Array(), key); + * ``` + */ +export const ghash: TRet> = + /* @__PURE__ */ wrapMacConstructor( + 16, + (key: TArg, expectedLength?: number) => new GHASH(key, expectedLength), + (msg: TArg): [expectedLength?: number] => [msg.length] + ); + +/** + * POLYVAL MAC for AES-SIV. + * @param msg - Message bytes to authenticate. + * @param key - 16-byte POLYVAL key. + * @returns 16-byte authentication tag. + * @example + * Authenticates a short message with POLYVAL and a fresh hash key. + * + * ```ts + * import { polyval } from '@noble/ciphers/_polyval.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(16); + * polyval(new Uint8Array(), key); + * ``` + */ +export const polyval: TRet> = + /* @__PURE__ */ wrapMacConstructor( + 16, + (key: TArg, expectedLength?: number) => new Polyval(key, expectedLength), + (msg: TArg): [expectedLength?: number] => [msg.length] + ); diff --git a/node_modules/@noble/ciphers/src/aes.ts b/node_modules/@noble/ciphers/src/aes.ts new file mode 100644 index 0000000..960d67c --- /dev/null +++ b/node_modules/@noble/ciphers/src/aes.ts @@ -0,0 +1,2018 @@ +/** + * {@link https://en.wikipedia.org/wiki/Advanced_Encryption_Standard | AES} + * a.k.a. Advanced Encryption Standard + * is a variant of Rijndael block cipher, standardized by NIST in 2001. + * We provide the fastest available pure JS implementation. + * + * `cipher = encrypt(block, key)` + * + * Data is split into 128-bit blocks. + * Encrypted in 10/12/14 rounds (128/192/256 bits). In every round: + * 1. **S-box**, table substitution + * 2. **Shift rows**, cyclic shift left of all rows of data array + * 3. **Mix columns**, multiplying every column by fixed polynomial + * 4. **Add round key**, round_key xor i-th column of array + * + * Check out + * {@link https://csrc.nist.gov/files/pubs/fips/197/final/docs/fips-197.pdf | FIPS-197}, + * {@link https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38G.pdf | NIST 800-38G}, + * and {@link https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/aes-development/rijndael-ammended.pdf | original proposal}. + * @module + */ +import { ghash, polyval } from './_polyval.ts'; +// prettier-ignore +import { + abytes, anumber, aoutput, + byteSwap, + clean, complexOverlapBytes, concatBytes, + copyBytes, createView, equalBytes, getOutput, isAligned32, + isLE, + overlapBytes, + swap32IfBE, + swap8IfBE, + u32, u64Lengths, u8, wrapCipher, wrapMacConstructor, + type Cipher, type CipherWithOutput, + type CMac, type IHash2, + type PRG, type TArg, type TRet, type Uint8ArrayBuffer +} from './utils.ts'; + +const BLOCK_SIZE = 16; +// AES operates on 16-byte blocks, i.e. 4 32-bit words. +const BLOCK_SIZE32 = 4; +// Shared zero block (`0^128`) used by GCM's `H = CIPH_K(0^128)` / J0 scratch +// and by CMAC / SIV helpers; callers take `.slice()` before mutating it. +const EMPTY_BLOCK = /* @__PURE__ */ new Uint8Array(BLOCK_SIZE); +// RFC 5297 §2.1 / §2.4: S2V uses ` = 0^127 || 1` for the `n = 0` special case. +const ONE_BLOCK = /* @__PURE__ */ Uint8Array.from([ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, +]); +const POLY = 0x11b; // 1 + x + x**3 + x**4 + x**8 +// Validates plain AES key sizes only; AES-SIV's doubled-key contract is checked elsewhere. +function validateKeyLength(key: TArg) { + if (![16, 24, 32].includes(key.length)) + throw new Error('"aes key" expected Uint8Array of length 16/24/32, got length=' + key.length); +} + +// TODO: remove multiplication, binary ops only +// Doubles one GF(2^8) field element; callers are expected to stay in byte range. +// FIPS 197 upd1 §4.3 equation (4.5): XTIMES(b) left-shifts by one and, when +// b7=1, reduces by m(x); using POLY=0x11b here yields the same byte result +// as XORing with {1b} after the shift. +function mul2(n: number) { + return (n << 1) ^ (POLY & -(n >> 7)); +} + +// Shift-and-add multiplication in GF(2^8); callers are expected to pass byte values. +// FIPS 197 upd1 §4.3 equation (4.7): general products are XORs of repeated +// XTIMES() multiples, e.g. {57}•{13} = {57}⊕{ae}⊕{07}. +function mul(a: number, b: number) { + let res = 0; + for (; b > 0; b >>= 1) { + // Usual shift-and-add step in GF(2^8), not a scalar-multiplication ladder. + res ^= a & -(b & 1); // if (b&1) res ^=a (but const-time). + a = mul2(a); // a = 2*a + } + return res; +} + +/** + * Increments a counter block with wrap around. + * AES call sites here currently use the big-endian branch, but the helper supports both layouts. + * NIST SP 800-38A Appendix B.1 and SP 800-38D §6.2 increment the + * least-significant/rightmost bits. + * `isLE=false` matches that standard counter-block layout, while `isLE=true` + * is a generic extension for non-AES callers. + * The implementation keeps a 32-bit bitwise carry path, so `carry` is capped at `0xffffff00`; + * larger values throw instead of silently overflowing before the next-byte propagation step. + */ +// Keep the helper explicitly typed so `--isolatedDeclarations` can expose it +// through the test-only `__TESTS` export without inference errors. +const incBytes: (data: TArg, isLE: boolean, carry?: number) => void = ( + data: TArg, + isLE: boolean, + carry: number = 1 +): void => { + // Keep `carry + byte <= 0xffffffff` so the `| 0` / `>>> 8` path below + // never truncates a real carry bit. + if (!Number.isSafeInteger(carry) || carry > 0xffffff00) + throw new Error('incBytes: wrong carry ' + carry); + abytes(data); + for (let i = 0; i < data.length; i++) { + const pos = !isLE ? data.length - 1 - i : i; + carry = (carry + (data[pos] & 0xff)) | 0; + data[pos] = carry & 0xff; + carry >>>= 8; + } +}; + +// AES S-box is generated using finite field inversion, +// an affine transform, and xor of a constant 0x63. +const sbox = /* @__PURE__ */ (() => { + const t = new Uint8Array(256); + // Repeated multiplication by {03} walks all 255 nonzero field elements + // once, so t[255 - i] is the multiplicative inverse of t[i] for the + // affine step. + for (let i = 0, x = 1; i < 256; i++, x ^= mul2(x)) t[i] = x; + const box = new Uint8Array(256); + // FIPS 197 upd1 §5.1.1: SBOX({00}) = {63} because the inverse step leaves + // {00} at {00}, then the affine transform xors in c = {63}. + box[0] = 0x63; + for (let i = 0; i < 255; i++) { + let x = t[255 - i]; + x |= x << 8; + box[t[i]] = (x ^ (x >> 4) ^ (x >> 5) ^ (x >> 6) ^ (x >> 7) ^ 0x63) & 0xff; + } + clean(t); + return box; +})(); + +// FIPS 197 upd1 §5.3.2: INVSBOX() is derived from SBOX() by swapping input +// and output roles (Table 6). +// `indexOf` is only used once at module init, so the quadratic setup cost stays off hot paths. +const invSbox = /* @__PURE__ */ sbox.map((_, j) => sbox.indexOf(j)); + +// FIPS 197 upd1 §5.2: ROTWORD([a0,a1,a2,a3]) = [a1,a2,a3,a0]; with this LE +// word packing that is a right rotate by 8 bits. +const rotr32_8 = (n: number) => (n << 24) | (n >>> 8); +// LE T-table helper: rotates one precomputed word by one byte so T1/T2/T3 +// reuse T0's substitution/mix result in the other byte lanes. +const rotl32_8 = (n: number) => (n << 8) | (n >>> 24); +// T-table is optimization suggested in 5.2 of original proposal (missed from FIPS-197). Changes: +// - LE instead of BE +// - bigger tables: T0 and T1 are merged into T01 table and T2 & T3 into T23; +// so index is u16, instead of u8. This speeds up things, unexpectedly +function genTtable(sbox: TArg, fn: (n: number) => number) { + if (sbox.length !== 256) throw new Error('Wrong sbox length'); + const T0 = new Uint32Array(256).map((_, j) => fn(sbox[j])); + const T1 = T0.map(rotl32_8); + const T2 = T1.map(rotl32_8); + const T3 = T2.map(rotl32_8); + // Pre-xor adjacent lanes so apply0123/applySbox can fetch two substituted + // byte lanes per lookup in the LE round layout. + const T01 = new Uint32Array(256 * 256); + const T23 = new Uint32Array(256 * 256); + const sbox2 = new Uint16Array(256 * 256); + for (let i = 0; i < 256; i++) { + for (let j = 0; j < 256; j++) { + const idx = i * 256 + j; + T01[idx] = T0[i] ^ T1[j]; + T23[idx] = T2[i] ^ T3[j]; + sbox2[idx] = (sbox[i] << 8) | sbox[j]; + } + } + return { sbox, sbox2, T0, T1, T2, T3, T01, T23 }; +} + +// Forward round precompute: the packed word stores the MIXCOLUMNS row +// [{02},{01},{01},{03}] in LE byte-lane order, and the returned `sbox2` +// is also reused by key expansion and the final round. +const tableEncoding = /* @__PURE__ */ genTtable( + sbox, + (s: number) => (mul(s, 3) << 24) | (s << 16) | (s << 8) | mul(s, 2) +); +// Inverse round precompute: the packed word stores the INVMIXCOLUMNS row +// [{0e},{09},{0d},{0b}] in LE byte-lane order, and the tables are reused +// by decrypt() and expandKeyDecLE(). +const tableDecoding = /* @__PURE__ */ genTtable( + invSbox, + (s) => (mul(s, 11) << 24) | (mul(s, 13) << 16) | (mul(s, 9) << 8) | mul(s, 14) +); + +// FIPS 197 upd1 §5.2 Table 5: left-most bytes of Rcon[j] = x^(j-1), generated by repeated XTIMES(). +const xPowers = /* @__PURE__ */ (() => { + const p = new Uint8Array(16); + for (let i = 0, x = 1; i < 16; i++, x = mul2(x)) p[i] = x; + return p; +})(); + +/** Forward AES key expansion used across ECB/CBC/CTR/GCM/CMAC/KW-style paths. */ +function expandKeyLE(key: TArg): TRet { + abytes(key); + const len = key.length; + validateKeyLength(key); + const { sbox2 } = tableEncoding; + const toClean = []; + // Copy on BE or misaligned inputs so the LE word normalization below never + // mutates caller key bytes in place. + if (!isLE || !isAligned32(key)) toClean.push((key = copyBytes(key))); + const k32 = swap32IfBE(u32(key)); + const Nk = k32.length; + // `applySbox` normally reads one byte lane from each argument; repeating + // `n` across all four lanes turns it into SUBWORD(n). + const subByte = (n: number) => applySbox(sbox2, n, n, n, n); + // AES key sizes are 16/24/32 bytes, so len + 28 yields the 44/52/60 + // schedule words from FIPS 197 §5.2 / Table 3. + const xk = new Uint32Array(len + 28); // expanded key + xk.set(k32); + // 4.3.1 Key expansion + for (let i = Nk; i < xk.length; i++) { + let t = xk[i - 1]; + if (i % Nk === 0) t = subByte(rotr32_8(t)) ^ xPowers[i / Nk - 1]; + else if (Nk > 6 && i % Nk === 4) t = subByte(t); + xk[i] = xk[i - Nk] ^ t; + } + clean(...toClean); + return xk as TRet; +} + +function expandKeyDecLE(key: TArg): TRet { + const encKey = expandKeyLE(key); + const xk = encKey.slice(); + const Nk = encKey.length; + const { sbox2 } = tableEncoding; + const { T0, T1, T2, T3 } = tableDecoding; + // Local decrypt() walks round keys forward from xk[0], so reverse the + // encryption round-key blocks first before applying the equivalent-inverse + // middle-round transform. + for (let i = 0; i < Nk; i += 4) { + for (let j = 0; j < 4; j++) xk[i + j] = encKey[Nk - i - 4 + j]; + } + clean(encKey); + // Apply InvMixColumn to the reversed round keys using the same LE sbox2 + // packing as the forward path. + // apply InvMixColumn except first & last round + for (let i = 4; i < Nk - 4; i++) { + const x = xk[i]; + const w = applySbox(sbox2, x, x, x, x); + xk[i] = T0[w & 0xff] ^ T1[(w >>> 8) & 0xff] ^ T2[(w >>> 16) & 0xff] ^ T3[w >>> 24]; + } + return xk as TRet; +} + +// Apply tables +function apply0123( + T01: TArg, + T23: TArg, + s0: number, + s1: number, + s2: number, + s3: number +) { + // `T01` takes the low byte lane from `s0` plus the next lane from `s1`; + // `T23` does the same for `s2`/`s3`. + // Equivalent to `T0[s0&0xff] ^ T1[(s1>>>8)&0xff] ^ T2[(s2>>>16)&0xff] ^ + // T3[s3>>>24]`, but with two merged-table fetches. + return ( + T01[((s0 << 8) & 0xff00) | ((s1 >>> 8) & 0xff)] ^ + T23[((s2 >>> 8) & 0xff00) | ((s3 >>> 24) & 0xff)] + ); +} + +function applySbox(sbox2: TArg, s0: number, s1: number, s2: number, s3: number) { + // `sbox2` packs two substituted byte lanes at a time in the same LE + // layout used by the round code. + // Equivalent to `SBOX(byte0(s0)) | SBOX(byte1(s1))<<8 | + // SBOX(byte2(s2))<<16 | SBOX(byte3(s3))<<24`. + return ( + sbox2[(s0 & 0xff) | (s1 & 0xff00)] | + (sbox2[((s2 >>> 16) & 0xff) | ((s3 >>> 16) & 0xff00)] << 16) + ); +} + +function encrypt( + xk: TArg, + s0: number, + s1: number, + s2: number, + s3: number +): { s0: number; s1: number; s2: number; s3: number } { + const { sbox2, T01, T23 } = tableEncoding; + let k = 0; + ((s0 ^= xk[k++]), (s1 ^= xk[k++]), (s2 ^= xk[k++]), (s3 ^= xk[k++])); + // `xk` has Nr+1 round-key blocks, so after the initial AddRoundKey and the + // final S-box-only round there are Nr-1 full table/MixColumns rounds left. + const rounds = xk.length / 4 - 2; + for (let i = 0; i < rounds; i++) { + const t0 = xk[k++] ^ apply0123(T01, T23, s0, s1, s2, s3); + const t1 = xk[k++] ^ apply0123(T01, T23, s1, s2, s3, s0); + const t2 = xk[k++] ^ apply0123(T01, T23, s2, s3, s0, s1); + const t3 = xk[k++] ^ apply0123(T01, T23, s3, s0, s1, s2); + ((s0 = t0), (s1 = t1), (s2 = t2), (s3 = t3)); + } + // last round (without mixcolumns, so using SBOX2 table) + const t0 = xk[k++] ^ applySbox(sbox2, s0, s1, s2, s3); + const t1 = xk[k++] ^ applySbox(sbox2, s1, s2, s3, s0); + const t2 = xk[k++] ^ applySbox(sbox2, s2, s3, s0, s1); + const t3 = xk[k++] ^ applySbox(sbox2, s3, s0, s1, s2); + return { s0: t0, s1: t1, s2: t2, s3: t3 }; +} + +// Can't be merged with encrypt: arg positions for apply0123 / applySbox are different +function decrypt( + xk: TArg, + s0: number, + s1: number, + s2: number, + s3: number +): { + s0: number; + s1: number; + s2: number; + s3: number; +} { + const { sbox2, T01, T23 } = tableDecoding; + let k = 0; + ((s0 ^= xk[k++]), (s1 ^= xk[k++]), (s2 ^= xk[k++]), (s3 ^= xk[k++])); + // With `expandKeyDecLE()` the round keys are already reversed and middle + // rounds are InvMixColumns-adjusted, so this loop follows the equivalent + // inverse cipher order directly. + const rounds = xk.length / 4 - 2; + for (let i = 0; i < rounds; i++) { + const t0 = xk[k++] ^ apply0123(T01, T23, s0, s3, s2, s1); + const t1 = xk[k++] ^ apply0123(T01, T23, s1, s0, s3, s2); + const t2 = xk[k++] ^ apply0123(T01, T23, s2, s1, s0, s3); + const t3 = xk[k++] ^ apply0123(T01, T23, s3, s2, s1, s0); + ((s0 = t0), (s1 = t1), (s2 = t2), (s3 = t3)); + } + // Final equivalent-inverse round omits InvMixColumns, so use inverse + // S-box lanes in InvShiftRows order. + const t0: number = xk[k++] ^ applySbox(sbox2, s0, s3, s2, s1); + const t1: number = xk[k++] ^ applySbox(sbox2, s1, s0, s3, s2); + const t2: number = xk[k++] ^ applySbox(sbox2, s2, s1, s0, s3); + const t3: number = xk[k++] ^ applySbox(sbox2, s3, s2, s1, s0); + return { s0: t0, s1: t1, s2: t2, s3: t3 }; +} + +function ctrCounter( + xk: TArg, + nonce: TArg, + src: TArg, + dst?: TArg +): TRet { + abytes(nonce, BLOCK_SIZE, 'nonce'); + abytes(src); + const srcLen = src.length; + dst = getOutput(srcLen, dst); + complexOverlapBytes(src, dst); + // Internal helper: mutate `nonce` in place as the live counter block so + // each encrypted block uses the next CTR value. + const ctr = nonce; + const c32 = u32(ctr); + const src32 = u32(src); + const dst32 = u32(dst); + // Fill block (empty, ctr=0) + let { s0, s1, s2, s3 } = encrypt( + xk, + swap8IfBE(c32[0]), + swap8IfBE(c32[1]), + swap8IfBE(c32[2]), + swap8IfBE(c32[3]) + ); + // process blocks + for (let i = 0; i + 4 <= src32.length; i += 4) { + dst32[i + 0] = src32[i + 0] ^ swap8IfBE(s0); + dst32[i + 1] = src32[i + 1] ^ swap8IfBE(s1); + dst32[i + 2] = src32[i + 2] ^ swap8IfBE(s2); + dst32[i + 3] = src32[i + 3] ^ swap8IfBE(s3); + incBytes(ctr, false, 1); // Full 128 bit counter with wrap around + ({ s0, s1, s2, s3 } = encrypt( + xk, + swap8IfBE(c32[0]), + swap8IfBE(c32[1]), + swap8IfBE(c32[2]), + swap8IfBE(c32[3]) + )); + } + // NIST SP 800-38A CTR mode uses the leading `u` bits of the next output + // block for the final short block. + // It's possible to handle > u32 fast, but is it worth it? + const start = BLOCK_SIZE * Math.floor(src32.length / BLOCK_SIZE32); + if (start < srcLen) { + const b32 = new Uint32Array([s0, s1, s2, s3]); + swap32IfBE(b32); + const buf = u8(b32); + for (let i = start, pos = 0; i < srcLen; i++, pos++) dst[i] = src[i] ^ buf[pos]; + clean(b32); + } + // Unsafe mutable-counter API only advances whole blocks. Callers that want to + // resume after consuming part of this block must re-run from the same counter + // with left-padding and strip the already-consumed prefix themselves. + return dst as TRet; +} + +// AES CTR with overflowing 32 bit counter +// It's possible to do 32le significantly simpler (and probably faster) by using u32. +// But, we need both, and perf bottleneck is in ghash anyway. +// Unsafe 32-bit CTR helper: mutates `nonce` in place, expects aligned `src`/`dst`, +// and uses `isLE` to choose which 32-bit counter word is incremented. +function ctr32( + xk: TArg, + isLE: boolean, + nonce: TArg, + src: TArg, + dst?: TArg +): TRet { + abytes(nonce, BLOCK_SIZE, 'nonce'); + abytes(src); + dst = getOutput(src.length, dst); + const ctr = nonce; // write new value to nonce, so it can be re-used + const c32 = u32(ctr); + const view = createView(ctr); + const src32 = u32(src); + const dst32 = u32(dst); + // NIST SP 800-38D GCTR increments the rightmost 32 bits of J0, while + // RFC 8452 AES-GCM-SIV increments the first 32 bits as a little-endian u32. + const ctrPos = isLE ? 0 : 12; + const srcLen = src.length; + // Fill block (empty, ctr=0) + let ctrNum = view.getUint32(ctrPos, isLE); // read current counter value + let { s0, s1, s2, s3 } = encrypt( + xk, + swap8IfBE(c32[0]), + swap8IfBE(c32[1]), + swap8IfBE(c32[2]), + swap8IfBE(c32[3]) + ); + // process blocks + for (let i = 0; i + 4 <= src32.length; i += 4) { + dst32[i + 0] = src32[i + 0] ^ swap8IfBE(s0); + dst32[i + 1] = src32[i + 1] ^ swap8IfBE(s1); + dst32[i + 2] = src32[i + 2] ^ swap8IfBE(s2); + dst32[i + 3] = src32[i + 3] ^ swap8IfBE(s3); + ctrNum = (ctrNum + 1) >>> 0; // u32 wrap + view.setUint32(ctrPos, ctrNum, isLE); + ({ s0, s1, s2, s3 } = encrypt( + xk, + swap8IfBE(c32[0]), + swap8IfBE(c32[1]), + swap8IfBE(c32[2]), + swap8IfBE(c32[3]) + )); + } + // leftovers (less than a block) + const start = BLOCK_SIZE * Math.floor(src32.length / BLOCK_SIZE32); + if (start < srcLen) { + const b32 = new Uint32Array([s0, s1, s2, s3]); + swap32IfBE(b32); + const buf = u8(b32); + for (let i = start, pos = 0; i < srcLen; i++, pos++) dst[i] = src[i] ^ buf[pos]; + clean(b32); + } + // Same unsafe contract as ctrCounter(): only full blocks advance the stored + // mutable counter state; partial-block continuation is caller-managed. + return dst as TRet; +} + +/** + * **CTR** (Counter Mode): turns a block cipher into a stream cipher using a + * full 16-byte counter block. + * Efficient and parallelizable. Requires a unique nonce per encryption. Unauthenticated: needs MAC. + * @param key - AES key bytes. + * @param nonce - 16-byte counter block, incremented as a full AES block. + * @returns Cipher instance with `encrypt()` and `decrypt()`. + * @example + * Encrypts a short payload with a fresh AES key and counter block. + * + * ```ts + * import { ctr } from '@noble/ciphers/aes.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(16); + * const nonce = randomBytes(16); + * const cipher = ctr(key, nonce); + * cipher.encrypt(new Uint8Array([1, 2, 3])); + * ``` + */ +export const ctr: TRet< + ((key: TArg, nonce: TArg) => CipherWithOutput) & { + blockSize: number; + nonceLength: number; + } +> = /* @__PURE__ */ wrapCipher( + { blockSize: 16, nonceLength: 16 }, + function aesctr(key: TArg, nonce: TArg): TRet { + function processCtr(buf: TArg, dst?: TArg): TRet { + abytes(buf); + if (dst !== undefined) { + abytes(dst); + // Optional output buffers must stay 4-byte aligned because + // ctrCounter() reinterprets them as Uint32Array words. + if (!isAligned32(dst)) throw new Error('unaligned destination'); + } + const xk = expandKeyLE(key); + // Public CTR keeps caller nonce bytes immutable even though ctrCounter() + // advances the live 16-byte counter block in place. + const n = copyBytes(nonce); // align + avoid changing + const toClean = [xk, n]; + if (!isAligned32(buf)) toClean.push((buf = copyBytes(buf))); + const out = ctrCounter(xk, n, buf, dst); + clean(...toClean); + return out as TRet; + } + return { + encrypt: (plaintext: TArg, dst?: TArg) => processCtr(plaintext, dst), + decrypt: (ciphertext: TArg, dst?: TArg) => + processCtr(ciphertext, dst), + } as TRet; + } +); + +function validateBlockDecrypt(data: TArg) { + abytes(data); + // ECB/CBC decryption always consumes whole ciphertext blocks; PKCS#7/CMS + // padding, when enabled, is removed only after decrypting the final block. + if (data.length % BLOCK_SIZE !== 0) { + throw new Error( + 'aes-(cbc/ecb).decrypt ciphertext should consist of blocks with size ' + BLOCK_SIZE + ); + } +} + +// ECB/CBC core modes operate on whole blocks; `pkcs5` enables the library's +// PKCS#7/CMS-compatible final-block padding convenience before encryption. +function validateBlockEncrypt(plaintext: TArg, pkcs5: boolean, dst?: TArg) { + abytes(plaintext); + let outLen = plaintext.length; + const remaining = outLen % BLOCK_SIZE; + if (!pkcs5 && remaining !== 0) + throw new Error('aec/(cbc-ecb): unpadded plaintext with disabled padding'); + if (pkcs5) { + let left = BLOCK_SIZE - remaining; + // RFC 5652 pads even already-aligned inputs, so a full extra block is + // appended when the plaintext length is already a multiple of 16 bytes. + if (!left) left = BLOCK_SIZE; // if no bytes left, create empty padding block + outLen = outLen + left; + } + dst = getOutput(outLen, dst); + complexOverlapBytes(plaintext, dst); + // Copy on BE or misaligned inputs so u32()/swap32IfBE() normalization never + // mutates caller plaintext bytes in place before ECB/CBC processing. + if (!isLE || !isAligned32(plaintext)) plaintext = copyBytes(plaintext); + const b = u32(plaintext); + swap32IfBE(b); + const o = u32(dst); + return { b, o, out: dst }; +} + +// `pkcs5` is the historical option name; for AES's 16-byte block this is the +// generic PKCS#7/CMS-style block-padding rule on decrypt. +function validatePKCS(data: TArg, pkcs5: boolean): TRet { + if (!pkcs5) return data as TRet; + + const len = data.length; + // RFC 5652 pads even empty / already-aligned inputs, so a valid padded + // ECB/CBC ciphertext is never empty when PKCS#7/CMS unpadding is enabled. + // AES-CBC/ECB ciphertext should be full blocks before unpadding + if (len === 0) throw new Error('aes/pkcs7: empty ciphertext not allowed'); + const lastByte = data[len - 1]; + let valid = 1; + valid &= ((lastByte - 1) >>> 31) ^ 1; // pad >= 1 + valid &= ((16 - lastByte) >>> 31) ^ 1; // pad <= 16 + // Check exactly 16 tail bytes in constant-shape loop + // For i < pad: byte must equal pad + // For i >= pad: ignore byte + for (let i = 0; i < 16; i++) { + // const b = data[len - 1 - i]; + const shouldCheck = (i - lastByte) >>> 31; // 1 if i < pad else 0 + const eq = (data[len - 1 - i] ^ lastByte) === 0 ? 1 : 0; // 1 if equal + valid &= eq | (shouldCheck ^ 1); // pass if equal OR not checked + } + + // if (invalidLen) throw new Error('aes/pkcs7: ciphertext length must be multiple of 16'); + if (!valid) throw new Error('aes/pkcs7: wrong padding'); + return data.subarray(0, len - lastByte) as TRet; +} + +// ECB/CBC callers only pass the final short block here, so `left.length` is +// 0..15 and the helper always emits exactly one padded 16-byte block. +function padPCKS(left: TArg): TRet { + const tmp = new Uint8Array(16); + const tmp32 = u32(tmp); + tmp.set(left); + const paddingByte = BLOCK_SIZE - left.length; + // RFC 5652 §6.3 fills the whole suffix with the padding length byte: + // e.g. `aa 0f..0f` for a 1-byte tail, or `10..10` for a full extra block. + for (let i = BLOCK_SIZE - paddingByte; i < BLOCK_SIZE; i++) tmp[i] = paddingByte; + return tmp32; +} + +/** Options for ECB and CBC. */ +export type BlockOpts = { + /** Disable the library's PKCS#7 padding/unpadding layer and require exact-block inputs. */ + disablePadding?: boolean; +}; + +/** + * **ECB** (Electronic Codebook): Deterministic encryption; identical plaintext blocks yield + * identical ciphertexts. Not secure due to pattern leakage. + * See {@link https://words.filippo.io/the-ecb-penguin/ | the AES Penguin}. + * @param key - AES key bytes. + * @param opts - Padding options. See {@link BlockOpts}. + * @returns Cipher instance with `encrypt()` and `decrypt()`. + * @example + * Shows the basic ECB encrypt call shape with a fresh key; avoid ECB in new designs. + * + * ```ts + * import { ecb } from '@noble/ciphers/aes.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(16); + * const cipher = ecb(key); + * cipher.encrypt(new Uint8Array([1, 2, 3])); + * ``` + */ +export const ecb: TRet< + ((key: TArg, opts?: BlockOpts) => CipherWithOutput) & { + blockSize: number; + } +> = /* @__PURE__ */ wrapCipher( + { blockSize: 16 }, + function aesecb(key: TArg, opts: BlockOpts = {}): TRet { + const pkcs5 = !opts.disablePadding; + return { + encrypt(plaintext: TArg, dst?: TArg): TRet { + const { b, o, out: _out } = validateBlockEncrypt(plaintext, pkcs5, dst); + const xk = expandKeyLE(key); + let i = 0; + for (; i + 4 <= b.length; ) { + const { s0, s1, s2, s3 } = encrypt(xk, b[i + 0], b[i + 1], b[i + 2], b[i + 3]); + ((o[i++] = s0), (o[i++] = s1), (o[i++] = s2), (o[i++] = s3)); + } + if (pkcs5) { + const tmp32 = padPCKS(plaintext.subarray(i * 4)); + swap32IfBE(tmp32); + const { s0, s1, s2, s3 } = encrypt(xk, tmp32[0], tmp32[1], tmp32[2], tmp32[3]); + ((o[i++] = s0), (o[i++] = s1), (o[i++] = s2), (o[i++] = s3)); + } + swap32IfBE(o); + clean(xk); + return _out as TRet; + }, + decrypt(ciphertext: TArg, dst?: TArg): TRet { + validateBlockDecrypt(ciphertext); + const xk = expandKeyDecLE(key); + dst = getOutput(ciphertext.length, dst); + const toClean: (Uint8Array | Uint32Array)[] = [xk]; + complexOverlapBytes(ciphertext, dst); + // Copy on BE or misaligned ciphertext so u32()/swap32IfBE() + // normalization never mutates caller bytes in place before decrypt(). + if (!isLE || !isAligned32(ciphertext)) toClean.push((ciphertext = copyBytes(ciphertext))); + const b = u32(ciphertext); + const o = u32(dst); + swap32IfBE(b); + for (let i = 0; i + 4 <= b.length; ) { + const { s0, s1, s2, s3 } = decrypt(xk, b[i + 0], b[i + 1], b[i + 2], b[i + 3]); + ((o[i++] = s0), (o[i++] = s1), (o[i++] = s2), (o[i++] = s3)); + } + swap32IfBE(o); + clean(...toClean); + return validatePKCS(dst, pkcs5) as TRet; + }, + } as TRet; + } +); + +/** + * **CBC** (Cipher Block Chaining): Each plaintext block is XORed with the + * previous block of ciphertext before encryption. + * Hard to use: requires proper padding and an unpredictable IV. Unauthenticated: needs MAC. + * @param key - AES key bytes. + * @param iv - 16-byte unpredictable initialization vector. + * @param opts - Padding options. See {@link BlockOpts}. + * @returns Cipher instance with `encrypt()` and `decrypt()`. + * @example + * Encrypts a padded message with a fresh key and 16-byte IV. + * + * ```ts + * import { cbc } from '@noble/ciphers/aes.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(16); + * const iv = randomBytes(16); + * const cipher = cbc(key, iv); + * cipher.encrypt(new Uint8Array([1, 2, 3])); + * ``` + */ +export const cbc: TRet< + ((key: TArg, iv: TArg, opts?: BlockOpts) => CipherWithOutput) & { + blockSize: number; + nonceLength: number; + } +> = /* @__PURE__ */ wrapCipher( + { blockSize: 16, nonceLength: 16 }, + function aescbc( + key: TArg, + iv: TArg, + opts: BlockOpts = {} + ): TRet { + const pkcs5 = !opts.disablePadding; + return { + encrypt(plaintext: TArg, dst?: TArg): TRet { + const xk = expandKeyLE(key); + const { b, o, out: _out } = validateBlockEncrypt(plaintext, pkcs5, dst); + let _iv = iv; + const toClean: (Uint8Array | Uint32Array)[] = [xk]; + // Copy on BE or misaligned inputs so IV normalization and the mutable + // local chaining state never write back into caller IV bytes. + if (!isLE || !isAligned32(_iv)) toClean.push((_iv = copyBytes(_iv))); + const n32 = u32(_iv); + swap32IfBE(n32); + // prettier-ignore + let s0 = n32[0], s1 = n32[1], s2 = n32[2], s3 = n32[3]; + let i = 0; + for (; i + 4 <= b.length; ) { + ((s0 ^= b[i + 0]), (s1 ^= b[i + 1]), (s2 ^= b[i + 2]), (s3 ^= b[i + 3])); + ({ s0, s1, s2, s3 } = encrypt(xk, s0, s1, s2, s3)); + ((o[i++] = s0), (o[i++] = s1), (o[i++] = s2), (o[i++] = s3)); + } + if (pkcs5) { + const tmp32 = padPCKS(plaintext.subarray(i * 4)); + swap32IfBE(tmp32); + ((s0 ^= tmp32[0]), (s1 ^= tmp32[1]), (s2 ^= tmp32[2]), (s3 ^= tmp32[3])); + ({ s0, s1, s2, s3 } = encrypt(xk, s0, s1, s2, s3)); + ((o[i++] = s0), (o[i++] = s1), (o[i++] = s2), (o[i++] = s3)); + } + swap32IfBE(o); + clean(...toClean); + return _out as TRet; + }, + decrypt(ciphertext: TArg, dst?: TArg): TRet { + validateBlockDecrypt(ciphertext); + const xk = expandKeyDecLE(key); + let _iv = iv; + const toClean: (Uint8Array | Uint32Array)[] = [xk]; + // Copy on BE or misaligned inputs so IV normalization and the mutable + // local chaining state never write back into caller IV bytes. + if (!isLE || !isAligned32(_iv)) toClean.push((_iv = copyBytes(_iv))); + const n32 = u32(_iv); + swap32IfBE(n32); + dst = getOutput(ciphertext.length, dst); + complexOverlapBytes(ciphertext, dst); + // Copy on BE or misaligned ciphertext so u32()/swap32IfBE() + // normalization never mutates caller bytes in place before decrypt(). + if (!isLE || !isAligned32(ciphertext)) toClean.push((ciphertext = copyBytes(ciphertext))); + const b = u32(ciphertext); + const o = u32(dst); + swap32IfBE(b); + // prettier-ignore + let s0 = n32[0], s1 = n32[1], s2 = n32[2], s3 = n32[3]; + for (let i = 0; i + 4 <= b.length; ) { + // prettier-ignore + const ps0 = s0, ps1 = s1, ps2 = s2, ps3 = s3; + ((s0 = b[i + 0]), (s1 = b[i + 1]), (s2 = b[i + 2]), (s3 = b[i + 3])); + const { s0: o0, s1: o1, s2: o2, s3: o3 } = decrypt(xk, s0, s1, s2, s3); + ((o[i++] = o0 ^ ps0), (o[i++] = o1 ^ ps1), (o[i++] = o2 ^ ps2), (o[i++] = o3 ^ ps3)); + } + swap32IfBE(o); + clean(...toClean); + return validatePKCS(dst, pkcs5) as TRet; + }, + } as TRet; + } +); + +/** + * CFB (CFB-128): Cipher Feedback Mode with 128-bit segments. The input for the + * block cipher is the previous cipher output. + * Unauthenticated: needs MAC. + * @param key - AES key bytes. + * @param iv - 16-byte unpredictable initialization vector. + * @returns Cipher instance with `encrypt()` and `decrypt()`. + * @example + * Encrypts a short message with feedback mode and a fresh key/IV pair. + * + * ```ts + * import { cfb } from '@noble/ciphers/aes.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(16); + * const iv = randomBytes(16); + * const cipher = cfb(key, iv); + * cipher.encrypt(new Uint8Array([1, 2, 3])); + * ``` + */ +export const cfb: TRet< + ((key: TArg, iv: TArg) => CipherWithOutput) & { + blockSize: number; + nonceLength: number; + } +> = /* @__PURE__ */ wrapCipher( + { blockSize: 16, nonceLength: 16 }, + function aescfb(key: TArg, iv: TArg): TRet { + function processCfb( + src: TArg, + isEncrypt: boolean, + dst?: TArg + ): TRet { + abytes(src); + const srcLen = src.length; + dst = getOutput(srcLen, dst); + // CFB feeds back previous ciphertext, so overlapping src/dst could + // overwrite bytes that are still needed as the next feedback block. + if (overlapBytes(src, dst)) throw new Error('overlapping src and dst not supported.'); + const xk = expandKeyLE(key); + let _iv = iv; + const toClean: (Uint8Array | Uint32Array)[] = [xk]; + // Copy on BE or misaligned inputs so u32()/swap32IfBE() normalization + // never mutates caller IV/src bytes in place before CFB processing. + if (!isLE || !isAligned32(_iv)) toClean.push((_iv = copyBytes(_iv))); + if (!isLE || !isAligned32(src)) toClean.push((src = copyBytes(src))); + const src32 = u32(src); + const dst32 = u32(dst); + // NIST SP 800-38A §6.3 feeds back the previous ciphertext segment in + // both directions: encrypt reuses freshly written dst words, decrypt + // reuses the source ciphertext words. + const next32 = isEncrypt ? dst32 : src32; + const n32 = u32(_iv); + swap32IfBE(src32); + swap32IfBE(n32); + // prettier-ignore + let s0 = n32[0], s1 = n32[1], s2 = n32[2], s3 = n32[3]; + for (let i = 0; i + 4 <= src32.length; ) { + const { s0: e0, s1: e1, s2: e2, s3: e3 } = encrypt(xk, s0, s1, s2, s3); + dst32[i + 0] = src32[i + 0] ^ e0; + dst32[i + 1] = src32[i + 1] ^ e1; + dst32[i + 2] = src32[i + 2] ^ e2; + dst32[i + 3] = src32[i + 3] ^ e3; + ((s0 = next32[i++]), (s1 = next32[i++]), (s2 = next32[i++]), (s3 = next32[i++])); + } + // leftovers (less than block) + const start = BLOCK_SIZE * Math.floor(src32.length / BLOCK_SIZE32); + if (start < srcLen) { + // Byte-oriented API: for a final short tail, reuse the next CFB-128 + // output block and XOR only the needed prefix. RFC 3826 §3.1.3 / + // §3.1.4 describes the same no-padding rule at bit granularity for a + // final r<=128 segment. + ({ s0, s1, s2, s3 } = encrypt(xk, s0, s1, s2, s3)); + const tmp = new Uint32Array([s0, s1, s2, s3]); + swap32IfBE(tmp); + const buf = u8(tmp); + for (let i = start, pos = 0; i < srcLen; i++, pos++) dst[i] = src[i] ^ buf[pos]; + clean(buf); + } + swap32IfBE(dst32); + clean(...toClean); + return dst as TRet; + } + return { + encrypt: (plaintext: TArg, dst?: TArg) => + processCfb(plaintext, true, dst), + decrypt: (ciphertext: TArg, dst?: TArg) => + processCfb(ciphertext, false, dst), + } as TRet; + } +); + +// TODO: merge with chacha, however gcm has bitLen while chacha has byteLen +// `data` is the payload covered by the polynomial MAC: ciphertext for GCM, +// plaintext for GCM-SIV. Keep AAD/data/length as separate updates because +// GHASH/POLYVAL pad each call to block boundaries, so the chunks must match the +// spec-defined segments instead of arbitrary concatenation boundaries. +function computeTag( + fn: typeof ghash, + isLE: boolean, + key: TArg, + data: TArg, + AAD?: TArg +): TRet { + const aadLength = AAD ? AAD.length : 0; + const h = fn.create(key, data.length + aadLength); + if (AAD) h.update(AAD); + // u64Lengths() takes (dataBits, aadBits) but still serializes the final + // block as len(AAD) || len(data), matching both GCM and GCM-SIV. + const num = u64Lengths(8 * data.length, 8 * aadLength, isLE); + h.update(data); + h.update(num); + const res = h.digest(); + clean(num); + return res; +} + +/** + * **GCM** (Galois/Counter Mode): Combines CTR mode with polynomial MAC. Efficient and widely used. + * Not perfect: + * a) conservative key wear-out is `2**32` (4B) msgs. + * b) key wear-out under random nonces is even smaller: `2**23` (8M) messages for `2**-50` chance. + * c) MAC can be forged: see Poly1305 documentation. + * @param key - AES key bytes. + * @param nonce - Nonce bytes (12 recommended, minimum 8; other lengths use GHASH J0 derivation). + * @param AAD - Additional authenticated data. + * @returns AEAD cipher instance with a fixed 16-byte tag. + * @example + * Encrypts and authenticates plaintext with a fresh key and 12-byte nonce. + * + * ```ts + * import { gcm } from '@noble/ciphers/aes.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(16); + * const nonce = randomBytes(12); + * const cipher = gcm(key, nonce); + * cipher.encrypt(new Uint8Array([1, 2, 3])); + * ``` + */ +export const gcm: TRet< + ((key: TArg, nonce: TArg, AAD?: TArg) => Cipher) & { + blockSize: number; + nonceLength: number; + tagLength: number; + varSizeNonce: true; + } +> = /* @__PURE__ */ wrapCipher( + { blockSize: 16, nonceLength: 12, tagLength: 16, varSizeNonce: true }, + function aesgcm( + key: TArg, + nonce: TArg, + AAD?: TArg + ): TRet { + // SP 800-38D lets implementations narrow supported IV lengths. + // This wrapper intentionally requires at least 8 bytes; OpenSSL accepts shorter IVs too. + // 12-byte nonces take the fast path; other allowed lengths use GHASH to derive J0. + if (nonce.length < 8) throw new Error('aes/gcm: invalid nonce length'); + const tagLength = 16; + function _computeTag( + authKey: TArg, + tagMask: TArg, + data: TArg + ): TRet { + const tag = computeTag(ghash, false, authKey, data, AAD); + for (let i = 0; i < tagMask.length; i++) tag[i] ^= tagMask[i]; + return tag; + } + function deriveKeys() { + const xk = expandKeyLE(key); + const authKey = EMPTY_BLOCK.slice(); + const counter = EMPTY_BLOCK.slice(); + ctr32(xk, false, counter, counter, authKey); + // NIST 800-38d, page 15: different behavior for 96-bit and non-96-bit nonces + if (nonce.length === 12) { + counter.set(nonce); + } else { + const nonceLen = EMPTY_BLOCK.slice(); + const view = createView(nonceLen); + view.setBigUint64(8, BigInt(nonce.length * 8), false); + // GHASH.update() pads each call to 16 bytes, so + // update(nonce).update(nonceLen) realizes + // IV || 0^s || 0^64 || [len(IV)]_64 for non-96-bit nonces. + // ghash(nonce || u64be(0) || u64be(nonceLen*8)) + const g = ghash.create(authKey).update(nonce).update(nonceLen); + g.digestInto(counter); // digestInto doesn't trigger '.destroy' + g.destroy(); + } + // GCTR_K(J0, 0^128) = E_K(J0); reusing ctr32() here extracts that tag + // mask and leaves `counter` advanced to inc32(J0) for payload GCTR. + const tagMask = ctr32(xk, false, counter, EMPTY_BLOCK); + return { xk, authKey, counter, tagMask }; + } + return { + encrypt(plaintext: TArg): TRet { + const { xk, authKey, counter, tagMask } = deriveKeys(); + const out = new Uint8Array(plaintext.length + tagLength); + const toClean: (Uint8Array | Uint32Array)[] = [xk, authKey, counter, tagMask]; + if (!isAligned32(plaintext)) toClean.push((plaintext = copyBytes(plaintext))); + ctr32(xk, false, counter, plaintext, out.subarray(0, plaintext.length)); + const tag = _computeTag(authKey, tagMask, out.subarray(0, out.length - tagLength)); + toClean.push(tag); + out.set(tag, plaintext.length); + clean(...toClean); + return out as TRet; + }, + decrypt(ciphertext: TArg): TRet { + const { xk, authKey, counter, tagMask } = deriveKeys(); + const toClean: (Uint8Array | Uint32Array)[] = [xk, authKey, tagMask, counter]; + if (!isAligned32(ciphertext)) toClean.push((ciphertext = copyBytes(ciphertext))); + const data = ciphertext.subarray(0, -tagLength); + const passedTag = ciphertext.subarray(-tagLength); + const tag = _computeTag(authKey, tagMask, data); + toClean.push(tag); + // NIST SP 800-38D §7.2 permits equivalent step orderings; verify the + // tag before CTR so unauthenticated plaintext is never materialized. + if (!equalBytes(tag, passedTag)) { + clean(...toClean); + throw new Error('aes/gcm: invalid ghash tag'); + } + const out = ctr32(xk, false, counter, data); + clean(...toClean); + return out as TRet; + }, + } as TRet; + } +); + +const limit = (name: string, min: number, max: number) => (value: number) => { + // Current AES-SIV/GCM-SIV callers pass protocol limits from RFC 8452 / RFC 5297, + // not arbitrary library-preference bounds. + // Callers feed Uint8Array.length values here, so safe-integer rejection + // does not exclude any representable input even when an RFC bound is larger. + if (!Number.isSafeInteger(value) || min > value || value > max) { + const minmax = '[' + min + '..' + max + ']'; + throw new Error('' + name + ': expected value in range ' + minmax + ', got ' + value); + } +}; + +/** + * **SIV** (Synthetic IV): GCM with nonce-misuse resistance. + * Repeating nonces reveal only the fact plaintexts are identical. + * Also suffers from GCM issues: key wear-out limits & MAC forging. + * See {@link https://www.rfc-editor.org/rfc/rfc8452 | RFC 8452}. + * RFC 8452 defines 16-byte and 32-byte AES keys for this mode. + * This implementation also accepts 24-byte AES-192 keys as a local + * extension; see the inline comment next to `validateKeyLength(key)` below + * for the exact scope note. + * @param key - AES key bytes. + * @param nonce - 12-byte nonce. + * @param AAD - Additional authenticated data. + * @returns AEAD cipher instance. + * @example + * Encrypts and authenticates plaintext with a fresh key and nonce, while tolerating reuse. + * + * ```ts + * import { gcmsiv } from '@noble/ciphers/aes.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(16); + * const nonce = randomBytes(12); + * const cipher = gcmsiv(key, nonce); + * cipher.encrypt(new Uint8Array([1, 2, 3])); + * ``` + */ +export const gcmsiv: TRet< + ((key: TArg, nonce: TArg, AAD?: TArg) => Cipher) & { + blockSize: number; + nonceLength: number; + tagLength: number; + varSizeNonce: true; + } +> = /* @__PURE__ */ wrapCipher( + { blockSize: 16, nonceLength: 12, tagLength: 16, varSizeNonce: true }, + function aessiv( + key: TArg, + nonce: TArg, + AAD?: TArg + ): TRet { + const tagLength = 16; + // From RFC 8452: Section 6 + const AAD_LIMIT = limit('AAD', 0, 2 ** 36); + const PLAIN_LIMIT = limit('plaintext', 0, 2 ** 36); + const NONCE_LIMIT = limit('nonce', 12, 12); + const CIPHER_LIMIT = limit('ciphertext', 16, 2 ** 36 + 16); + abytes(key); + // RFC 8452 only standardizes 16-byte and 32-byte key-generating keys. + // The accepted 24-byte path is a local AES-192 extension outside the RFC-defined AEADs. + validateKeyLength(key); + NONCE_LIMIT(nonce.length); + if (AAD !== undefined) AAD_LIMIT(AAD.length); + function deriveKeys() { + const xk = expandKeyLE(key); + const encKey = new Uint8Array(key.length); + const authKey = new Uint8Array(16); + const toClean: (Uint8Array | Uint32Array)[] = [xk, encKey]; + let _nonce = nonce; + // Copy on BE or misaligned nonce so u32()/swap32IfBE() normalization + // never mutates caller nonce bytes before RFC 8452 key derivation. + if (!isLE || !isAligned32(_nonce)) toClean.push((_nonce = copyBytes(_nonce))); + const n32 = u32(_nonce); + swap32IfBE(n32); + // prettier-ignore + let s0 = 0, s1 = n32[0], s2 = n32[1], s3 = n32[2]; + let counter = 0; + for (const derivedKey of [authKey, encKey].map(u32)) { + const d32 = u32(derivedKey); + for (let i = 0; i < d32.length; i += 2) { + // aes(u32le(0) || nonce)[:8] || aes(u32le(1) || nonce)[:8] ... + const { s0: o0, s1: o1 } = encrypt(xk, s0, s1, s2, s3); + d32[i + 0] = o0; + d32[i + 1] = o1; + s0 = ++counter; // increment counter inside state + } + swap32IfBE(d32); + } + const res = { authKey, encKey: expandKeyLE(encKey) }; + // Cleanup + clean(...toClean); + return res; + } + function _computeTag( + encKey: TArg, + authKey: TArg, + data: TArg + ): TRet { + const tag = computeTag(polyval, true, authKey, data, AAD); + // Compute the expected tag by XORing S_s and the nonce, clearing the + // most significant bit of the last byte and encrypting with the + // message-encryption key. + for (let i = 0; i < 12; i++) tag[i] ^= nonce[i]; + tag[15] &= 0x7f; // Clear the highest bit + // encrypt tag as block + const t32 = u32(tag); + swap32IfBE(t32); + // prettier-ignore + let s0 = t32[0], s1 = t32[1], s2 = t32[2], s3 = t32[3]; + ({ s0, s1, s2, s3 } = encrypt(encKey, s0, s1, s2, s3)); + ((t32[0] = s0), (t32[1] = s1), (t32[2] = s2), (t32[3] = s3)); + swap32IfBE(t32); + return tag; + } + // actual decrypt/encrypt of message. + function processSiv( + encKey: TArg, + tag: TArg, + input: TArg + ): TRet { + let block = copyBytes(tag); + // RFC 8452 §4 / §5 use the tag with the highest bit of the last byte + // forced to one as the initial AES-CTR counter block. + block[15] |= 0x80; // Force highest bit + const res = ctr32(encKey, true, block, input); + // Cleanup + clean(block); + return res; + } + return { + encrypt(plaintext: TArg): TRet { + PLAIN_LIMIT(plaintext.length); + const { encKey, authKey } = deriveKeys(); + const tag = _computeTag(encKey, authKey, plaintext); + const toClean: (Uint8Array | Uint32Array)[] = [encKey, authKey, tag]; + if (!isAligned32(plaintext)) toClean.push((plaintext = copyBytes(plaintext))); + const out = new Uint8Array(plaintext.length + tagLength); + out.set(tag, plaintext.length); + out.set(processSiv(encKey, tag, plaintext)); + // Cleanup + clean(...toClean); + return out as TRet; + }, + decrypt(ciphertext: TArg): TRet { + CIPHER_LIMIT(ciphertext.length); + const tag = ciphertext.subarray(-tagLength); + const { encKey, authKey } = deriveKeys(); + const toClean: (Uint8Array | Uint32Array)[] = [encKey, authKey]; + if (!isAligned32(ciphertext)) toClean.push((ciphertext = copyBytes(ciphertext))); + const plaintext = processSiv(encKey, tag, ciphertext.subarray(0, -tagLength)); + const expectedTag = _computeTag(encKey, authKey, plaintext); + toClean.push(expectedTag); + // RFC 8452 §5: plaintext is unauthenticated here and MUST NOT be + // returned until the expected-tag check completes successfully. + if (!equalBytes(tag, expectedTag)) { + clean(...toClean); + throw new Error('invalid polyval tag'); + } + // Cleanup + clean(...toClean); + return plaintext as TRet; + }, + } as TRet; + } +); + +function isBytes32(a: unknown): a is Uint32Array { + // Plain `instanceof Uint32Array` is too strict for cross-realm expanded-key views. + // This is only a best-effort unsafe-export guard, not a provenance proof for `expandKeyLE`. + return ( + a instanceof Uint32Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint32Array') + ); +} + +// Unsafe single-block helpers: mutate `block` in place and require its 16-byte +// Uint8Array view to be 4-byte aligned because `u32(block)` reinterprets it. +function encryptBlock(xk: TArg, block: TArg): TRet { + abytes(block, 16, 'block'); + if (!isBytes32(xk)) throw new Error('_encryptBlock accepts result of expandKeyLE'); + const b32 = u32(block); + swap32IfBE(b32); + let { s0, s1, s2, s3 } = encrypt(xk, b32[0], b32[1], b32[2], b32[3]); + ((b32[0] = s0), (b32[1] = s1), (b32[2] = s2), (b32[3] = s3)); + swap32IfBE(b32); + return block as TRet; +} + +function decryptBlock(xk: TArg, block: TArg): TRet { + abytes(block, 16, 'block'); + if (!isBytes32(xk)) throw new Error('_decryptBlock accepts result of expandKeyLE'); + const b32 = u32(block); + swap32IfBE(b32); + let { s0, s1, s2, s3 } = decrypt(xk, b32[0], b32[1], b32[2], b32[3]); + ((b32[0] = s0), (b32[1] = s1), (b32[2] = s2), (b32[3] = s3)); + swap32IfBE(b32); + return block as TRet; +} + +/** + * AES-W (base for AESKW/AESKWP). + * Specs: + * {@link https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38F.pdf | SP800-38F}, + * {@link https://www.rfc-editor.org/rfc/rfc3394 | RFC 3394}, + * {@link https://www.rfc-editor.org/rfc/rfc5649 | RFC 5649}. + * Shared core mutates `out` in place; callers are responsible for prepending + * the right IV/AIV and checking the recovered value after decrypt. + */ +const AESW = { + /* + High-level pseudocode: + ``` + A: u64 = IV + out = [] + for (let i=0, ctr = 0; i<6; i++) { + for (const chunk of chunks(plaintext, 8)) { + A ^= swapEndianess(ctr++) + [A, res] = chunks(encrypt(A || chunk), 8); + out ||= res + } + } + out = A || out + ``` + Decrypt is the same, but reversed. + */ + encrypt(kek: TArg, out: TArg) { + // Current implementation keeps RFC 3394/5649 `t` in a u32-shaped counter, + // so the shared core caps plaintext below 4 GiB even though the specs allow more. + if (out.length >= 2 ** 32) throw new Error('plaintext should be less than 4gb'); + const xk = expandKeyLE(kek); + // 16-byte `S = A || P[1]` is the RFC 5649 KWP special case for n=1; + // KW callers never reach it because KW requires at least two plaintext semiblocks. + if (out.length === 16) encryptBlock(xk, out); + else { + const o32 = u32(out); + swap32IfBE(o32); + // prettier-ignore + let a0 = o32[0], a1 = o32[1]; // A + for (let j = 0, ctr = 1; j < 6; j++) { + for (let pos = 2; pos < o32.length; pos += 2, ctr++) { + const { s0, s1, s2, s3 } = encrypt(xk, a0, a1, o32[pos], o32[pos + 1]); + // A = MSB(64, B) ^ t where t = (n*j)+i. Under the 32-bit length cap + // above, `t` fits in the low half of `[t]_64`, so xor only the low + // 32 bits of A after converting `ctr` to network order. + ((a0 = s0), (a1 = s1 ^ byteSwap(ctr)), (o32[pos] = s2), (o32[pos + 1] = s3)); + } + } + ((o32[0] = a0), (o32[1] = a1)); // out = A || out + swap32IfBE(o32); + } + xk.fill(0); + }, + decrypt(kek: TArg, out: TArg) { + // Same implementation cap on the recovered plaintext length after + // removing the 8-byte A/IV prefix. + if (out.length - 8 >= 2 ** 32) throw new Error('ciphertext should be less than 4gb'); + const xk = expandKeyDecLE(kek); + const chunks = out.length / 8 - 1; // first chunk is IV + // `n = 2` semiblocks is the RFC 5649 KWP special case; KW ciphertexts + // always have at least three semiblocks and therefore use the W^-1 loop. + if (chunks === 1) decryptBlock(xk, out); + else { + const o32 = u32(out); + swap32IfBE(o32); + // prettier-ignore + let a0 = o32[0], a1 = o32[1]; // A + for (let j = 0, ctr = chunks * 6; j < 6; j++) { + for (let pos = chunks * 2; pos >= 1; pos -= 2, ctr--) { + a1 ^= byteSwap(ctr); + const { s0, s1, s2, s3 } = decrypt(xk, a0, a1, o32[pos], o32[pos + 1]); + ((a0 = s0), (a1 = s1), (o32[pos] = s2), (o32[pos + 1] = s3)); + } + } + ((o32[0] = a0), (o32[1] = a1)); + swap32IfBE(o32); + } + xk.fill(0); + }, +}; + +// RFC 3394 §2.2.3.1 / NIST SP 800-38F Algorithm 3 / Algorithm 4: KW prepends +// the default 64-bit ICV1 and unwrap must verify the same value. +const AESKW_IV = /* @__PURE__ */ new Uint8Array(8).fill(0xa6); // A6A6A6A6A6A6A6A6 + +/** + * AES-KW (key-wrap). Injects static IV into plaintext, adds counter, encrypts 6 times. + * Reduces block size from 16 to 8 bytes. + * Plaintext must be a non-empty multiple of 8 bytes with minimum 16 bytes. + * 8-byte inputs use aeskwp. + * Wrapped ciphertext must be a multiple of 8 bytes with minimum 24 bytes. + * For padded version, use aeskwp. + * See {@link https://www.rfc-editor.org/rfc/rfc3394/ | RFC 3394} and + * {@link https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38F.pdf | NIST SP 800-38F}. + * @param kek - AES key-encryption key. + * @returns Key-wrap cipher instance. + * As with other `wrapCipher(...)` wrappers, `encrypt()` is single-use per + * instance. + * @example + * Wraps a 128-bit content-encryption key with a fresh key-encryption key. + * + * ```ts + * import { aeskw } from '@noble/ciphers/aes.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const kek = randomBytes(16); + * const cek = randomBytes(16); + * const wrap = aeskw(kek); + * wrap.encrypt(cek); + * ``` + */ +export const aeskw: TRet< + ((kek: TArg) => Cipher) & { + blockSize: number; + } +> = /* @__PURE__ */ wrapCipher( + { blockSize: 8 }, + (kek: TArg): TRet => + ({ + encrypt(plaintext: TArg): TRet { + if (!plaintext.length || plaintext.length % 8 !== 0) + throw new Error('invalid plaintext length'); + // RFC 3394 / NIST SP 800-38F define KW only for >=2 plaintext + // semiblocks; the 1-semiblock case belongs to RFC 5649 KWP. + if (plaintext.length === 8) + throw new Error('8-byte keys not allowed in AESKW, use AESKWP instead'); + const out = concatBytes(AESKW_IV, plaintext); + AESW.encrypt(kek, out); + return out; + }, + decrypt(ciphertext: TArg): TRet { + // ciphertext must be at least 24 bytes and a multiple of 8 bytes + // 24 because should have at least two block (1 iv + 2). + // Replace with 16 to enable '8-byte keys' + if (ciphertext.length % 8 !== 0 || ciphertext.length < 3 * 8) + throw new Error('invalid ciphertext length'); + // AESW.decrypt() mutates its buffer in place, so keep caller ciphertext + // immutable across the unwrap, ICV1 check, and IV scrubbing below. + const out = copyBytes(ciphertext); + AESW.decrypt(kek, out); + if (!equalBytes(out.subarray(0, 8), AESKW_IV)) throw new Error('integrity check failed'); + out.subarray(0, 8).fill(0); // ciphertext.subarray(0, 8) === IV, but we clean it anyway + return out.subarray(8) as TRet; + }, + }) as TRet +); + +/* +We don't support 8-byte keys. The rabbit hole: + +- Wycheproof says: "NIST SP 800-38F does not define the wrapping of 8 byte keys. + RFC 3394 Section 2 on the other hand specifies that 8 byte keys are wrapped + by directly encrypting one block with AES." + - {@link https://github.com/C2SP/wycheproof/blob/master/doc/key_wrap.md | Wycheproof key-wrap note} + - "RFC 3394 specifies in Section 2, that the input for the key wrap + algorithm must be at least two blocks and otherwise the constant + field and key are simply encrypted with ECB as a single block" +- What RFC 3394 actually says (in Section 2): + - "Before being wrapped, the key data is parsed into n blocks of 64 bits. + The only restriction the key wrap algorithm places on n is that n be + at least two" + - "For key data with length less than or equal to 64 bits, the constant + field used in this specification and the key data form a single + 128-bit codebook input making this key wrap unnecessary." +- Which means "assert(n >= 2)" and "use something else for 8 byte keys" +- NIST SP800-38F actually prohibits 8-byte in "5.3.1 Mandatory Limits". + It states that plaintext for KW should be "2 to 2^54 -1 semiblocks". +- So, where does "directly encrypt single block with AES" come from? + - Not RFC 3394. Pseudocode of key wrap in 2.2 explicitly uses + loop of 6 for any code path + - There is a weird W3C spec: + {@link https://www.w3.org/TR/2002/REC-xmlenc-core-20021210/Overview.html#kw-aes128 | XML Encryption AES key-wrap section} + - This spec is outdated, as admitted by Wycheproof authors + - There is RFC 5649 for padded key wrap, which is padding construction on + top of AESKW. In '4.1.2' it says: "If the padded plaintext contains exactly + eight octets, then prepend the AIV as defined in Section 3 above to P[1] and + encrypt the resulting 128-bit block using AES in ECB mode [Modes] with key + K (the KEK). In this case, the output is two 64-bit blocks C[0] and C[1]:" + - Browser subtle crypto is actually crashes on wrapping keys less than 16 bytes: + `Error: error:1C8000E6:Provider routines::invalid input length] + { opensslErrorStack: [ 'error:030000BD:digital envelope routines::update error' ]` + +In the end, seems like a bug in Wycheproof. +The 8-byte check can be easily disabled inside of AES_W. +*/ + +// RFC 5649 §3 / NIST SP 800-38F Algorithm 5 / Algorithm 6: KWP uses ICV2 as +// the high 32 bits of the AIV; the low 32 bits carry the MLI in network order. +const AESKWP_IV = 0xa65959a6; // single u32le value + +/** + * AES-KW, but with padding and allows random keys. + * Uses the RFC 5649 alternative initial value; the second u32 stores the + * 32-bit MLI in network order. + * Wrapped ciphertext must be at least 16 bytes; malformed lengths are + * rejected during AIV/padding checks. + * See {@link https://www.rfc-editor.org/rfc/rfc5649 | RFC 5649}. + * @param kek - AES key-encryption key. + * @returns Padded key-wrap cipher instance. + * @example + * Wraps a short key blob using the padded variant and a fresh key-encryption key. + * + * ```ts + * import { aeskwp } from '@noble/ciphers/aes.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const kek = randomBytes(16); + * const wrap = aeskwp(kek); + * wrap.encrypt(new Uint8Array([1, 2, 3])); + * ``` + */ +export const aeskwp: TRet< + ((kek: TArg) => Cipher) & { + blockSize: number; + } +> = /* @__PURE__ */ wrapCipher( + { blockSize: 8 }, + (kek: TArg): TRet => + ({ + encrypt(plaintext: TArg): TRet { + if (!plaintext.length) throw new Error('invalid plaintext length'); + const padded = Math.ceil(plaintext.length / 8) * 8; + const out = new Uint8Array(8 + padded); + out.set(plaintext, 8); + const out32 = u32(out); + out32[0] = swap8IfBE(AESKWP_IV); + // RFC 5649 §3: the low 32 bits of the AIV carry the octet-length MLI in + // network order, even though this buffer is addressed through LE u32s. + out32[1] = swap8IfBE(byteSwap(plaintext.length)); + AESW.encrypt(kek, out); + return out as TRet; + }, + decrypt(ciphertext: TArg): TRet { + // 16 because should have at least one block + if (ciphertext.length < 16) throw new Error('invalid ciphertext length'); + // AESW.decrypt() mutates its buffer in place, so keep caller ciphertext + // immutable across the unwrap, AIV checks, and IV scrubbing below. + const out = copyBytes(ciphertext); + const o32 = u32(out); + AESW.decrypt(kek, out); + const len = byteSwap(swap8IfBE(o32[1])) >>> 0; + const padded = Math.ceil(len / 8) * 8; + if (swap8IfBE(o32[0]) !== AESKWP_IV || out.length - 8 !== padded) + throw new Error('integrity check failed'); + // RFC 5649 §3 / NIST SP 800-38F Algorithm 6: recovered padding length + // must be in [0,7], and every recovered pad octet must be zero. + for (let i = len; i < padded; i++) + if (out[8 + i] !== 0) throw new Error('integrity check failed'); + out.subarray(0, 8).fill(0); // ciphertext.subarray(0, 8) === IV, but we clean it anyway + return out.subarray(8, 8 + len) as TRet; + }, + }) as TRet +); + +class _AesCtrDRBG implements PRG { + readonly blockLen: number; + private key: TRet; + private nonce: TRet; + private state: TRet; + private reseedCnt: number; + constructor(keyLen: number, seed: TArg, personalization?: TArg) { + this.blockLen = ctr.blockSize; + const keyLenBytes = keyLen / 8; + const nonceLen = 16; + // Store the full seedlen state as key || V so CTR_DRBG_Update-style steps + // can rewrite the entire internal state in place. + this.state = new Uint8Array(keyLenBytes + nonceLen) as TRet; + this.key = this.state.subarray(0, keyLenBytes) as TRet; + this.nonce = this.state.subarray(keyLenBytes, keyLenBytes + nonceLen) as TRet; + this.reseedCnt = 1; + // Keep the stored counter one step ahead of SP 800-90A's formal V so + // ctr(key, nonce) uses the next counter block directly. + incBytes(this.nonce, false, 1); + this.addEntropy(seed, personalization); + } + private update(data?: TArg) { + // cannot re-use state here, because we will wipe current key + ctr(this.key, this.nonce).encrypt(new Uint8Array(this.state.length), this.state); + if (data) { + abytes(data); + // CTR_DRBG without a derivation function pads shorter additional_input + // with zeros to seedlen, so XOR only the provided prefix here. + for (let i = 0; i < data.length; i++) this.state[i] ^= data[i]; + } + // Keep storing V+1 so the next ctr(key, nonce) call starts from the + // spec's post-update counter state. + incBytes(this.nonce, false, 1); + } + // Optional `info` is additional input XORed into the reseed block and is + // limited to the internal state width. + addEntropy(seed: TArg, info?: TArg): void { + abytes(seed, this.state.length, 'seed'); + // Copy caller entropy before XORing in personalization/additional input, + // then wipe the mixed seed material after CTR_DRBG_Update consumes it. + const _seed = seed.slice(); + if (info) { + abytes(info); + if (info.length > _seed.length) throw new Error('info length is too big'); + for (let i = 0; i < info.length; i++) _seed[i] ^= info[i]; + } + this.update(_seed); + _seed.fill(0); + this.reseedCnt = 1; + } + // Optional `info` is additional input for the pre/post-update steps; bytes + // SP 800-90A Rev. 1 CTR_DRBG without a derivation function limits + // additional_input to seedlen, which is exactly this internal state width. + randomBytes(len: number, info?: TArg): TRet { + anumber(len); + // SP 800-90A Table 3 caps AES CTR_DRBG requests at 2^16 bits = 65536 bytes. + if (len > 2 ** 16) throw new Error('requested output is too big'); + // The spec allows generate while reseed_counter == reseed_interval and increments afterwards. + if (this.reseedCnt > 2 ** 48) throw new Error('entropy exhausted'); + if (info) { + abytes(info); + if (info.length > this.state.length) throw new Error('info length is too big'); + this.update(info); + } + const res = new Uint8Array(len); + ctr(this.key, this.nonce).encrypt(res, res); + incBytes(this.nonce, false, Math.ceil(len / this.blockLen)); + this.update(info); + this.reseedCnt++; + return res as TRet; + } + // Zeroes the current state and resets the counter, but does not make the + // instance unusable: later calls continue from the zeroed state. + clean(): void { + // `key` and `nonce` alias this backing buffer, so one fill wipes the full + // secret state in place. + this.state.fill(0); + this.reseedCnt = 0; + } +} + +/** + * Factory for AES-CTR DRBG instances. + * @param seed - Initial entropy input. + * @param personalization - Optional personalization string mixed into the state. + * @returns Seeded AES-CTR DRBG instance. + */ +export type AesCtrDrbg = ( + seed: TArg, + personalization?: TArg +) => TRet<_AesCtrDRBG>; + +// Internal helper for the exported 128-bit and 256-bit aliases; other key +// lengths are not validated here. +const createAesDrbg: (keyLen: number) => TRet = (keyLen) => { + return (seed, personalization = undefined) => + new _AesCtrDRBG(keyLen, seed, personalization) as TRet<_AesCtrDRBG>; +}; + +/** + * AES-CTR DRBG 128-bit - CSPRNG (cryptographically secure pseudorandom number generator). + * It's best to limit usage to non-production, non-critical cases: for example, test-only. + * @param seed - Initial 32-byte entropy input. + * @param personalization - Optional personalization string. + * @returns Seeded DRBG instance. The concrete methods also accept optional additional-input bytes. + * @example + * Seeds the test-only AES-CTR DRBG from fresh entropy and reads bytes from it. + * + * ```ts + * import { rngAesCtrDrbg128 } from '@noble/ciphers/aes.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const seed = randomBytes(32); + * const prg = rngAesCtrDrbg128(seed); + * prg.randomBytes(8); + * ``` + */ +export const rngAesCtrDrbg128: TRet = /* @__PURE__ */ createAesDrbg(128); +/** + * AES-CTR DRBG 256-bit - CSPRNG (cryptographically secure pseudorandom number generator). + * It's best to limit usage to non-production, non-critical cases: for example, test-only. + * @param seed - Initial 48-byte entropy input. + * @param personalization - Optional personalization string. + * @returns Seeded DRBG instance. The concrete methods also accept optional additional-input bytes. + * @example + * Seeds the test-only AES-CTR DRBG from fresh entropy and reads bytes from it. + * + * ```ts + * import { rngAesCtrDrbg256 } from '@noble/ciphers/aes.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const seed = randomBytes(48); + * const prg = rngAesCtrDrbg256(seed); + * prg.randomBytes(8); + * ``` + */ +export const rngAesCtrDrbg256: TRet = /* @__PURE__ */ createAesDrbg(256); + +//#region CMAC + +/** + * Left-shift by one bit and conditionally XOR with 0x87: + * ``` + * if MSB(L) is equal to 0 + * then K1 := L << 1; + * else K1 := (L << 1) XOR const_Rb; + * ``` + * + * Specs: + * {@link https://www.rfc-editor.org/rfc/rfc4493.html#section-2.3 | RFC 4493 Section 2.3}, + * {@link https://datatracker.ietf.org/doc/html/rfc5297.html#section-2.3 | RFC 5297 Section 2.3} + * + * @returns modified `block` (for chaining) + */ +function dbl(block: T): T { + let carry = 0; + + // Left shift by 1 bit + for (let i = BLOCK_SIZE - 1; i >= 0; i--) { + const newCarry = (block[i] & 0x80) >>> 7; + block[i] = (block[i] << 1) | carry; + carry = newCarry; + } + + // XOR with 0x87 if there was a carry from the most significant bit + if (carry) { + // RFC 4493 §2.3 / RFC 5297 §2.1: 0x87 is const_Rb for doubling in the + // CMAC/S2V finite field with primitive polynomial x^128 + x^7 + x^2 + x + 1. + block[BLOCK_SIZE - 1] ^= 0x87; + } + + return block; +} + +/** + * `a XOR b`, running in-place on `a`. + * @param a left operand and output + * @param b right operand + * @returns `a` (for chaining) + */ +function xorBlock>(a: T, b: TArg): T { + if (a.length !== b.length) throw new Error('xorBlock: blocks must have same length'); + for (let i = 0; i < a.length; i++) { + a[i] = a[i] ^ b[i]; + } + return a; +} + +/** + * xorend as defined in + * {@link https://datatracker.ietf.org/doc/html/rfc5297.html#section-2.1 | RFC 5297 Section 2.1}. + * + * ``` + * leftmost(A, len(A)-len(B)) || (rightmost(A, len(B)) xor B) + * ``` + * + * Mutates `a` in place so the left prefix stays untouched and only the + * rightmost `len(B)` bytes are xored with `b`. + */ +function xorend>(a: T, b: TArg): T { + if (b.length > a.length) { + throw new Error('xorend: len(B) must be less than or equal to len(A)'); + } + // keep leftmost part of `a` unchanged + // and xor only the rightmost part: + const offset = a.length - b.length; + for (let i = 0; i < b.length; i++) { + a[offset + i] = a[offset + i] ^ b[i]; + } + return a; +} + +/** + * Internal CMAC class. + */ +class _CMAC implements IHash2 { + readonly blockLen: number = BLOCK_SIZE; + readonly outputLen: number = BLOCK_SIZE; + // CMAC can only decide between `K1` and `K2` once the true final block is known, + // so updates process older blocks eagerly but keep one pending block buffered. + private buffer: Uint8Array; + private pos: number; + private finished: boolean; + private destroyed: boolean; + private k1: Uint8Array; + private k2: Uint8Array; + private x: Uint8Array; + private xk: Uint32Array; + + constructor(key: TArg) { + abytes(key); + validateKeyLength(key); + this.xk = expandKeyLE(key); + this.buffer = new Uint8Array(BLOCK_SIZE); + this.pos = 0; + this.finished = false; + this.destroyed = false; + this.x = new Uint8Array(BLOCK_SIZE); + // L = AES_encrypt(K, const_Zero) + const L = new Uint8Array(BLOCK_SIZE); + encryptBlock(this.xk, L); + // Generate subkeys K1 and K2 from the main key according to + // {@link https://www.rfc-editor.org/rfc/rfc4493.html#section-2.3 | RFC 4493 Section 2.3} + // K1 + this.k1 = dbl(L); + this.k2 = dbl(new Uint8Array(this.k1)); + } + + private process(data: TArg): void { + // RFC 4493 §2.4 step 6 loop body: Y := X XOR M_i; X := AES-128(K, Y). + xorBlock(this.x, data); + encryptBlock(this.xk, this.x); + } + + update(data: TArg): this { + if (this.destroyed) throw new Error('Hash instance has been destroyed'); + if (this.finished) throw new Error('Hash#digest() has already been called'); + abytes(data); + let pos = 0; + if (this.pos) { + const take = Math.min(BLOCK_SIZE - this.pos, data.length); + this.buffer.set(data.subarray(0, take), this.pos); + this.pos += take; + pos = take; + if (this.pos === BLOCK_SIZE && pos < data.length) { + this.process(this.buffer); + this.pos = 0; + } + } + // Keep one complete block buffered: an exact 16-byte tail may still be + // M_n, and digestInto() must decide there whether RFC 4493 uses K1 or K2. + while (pos + BLOCK_SIZE < data.length) { + this.process(data.subarray(pos, pos + BLOCK_SIZE)); + pos += BLOCK_SIZE; + } + if (pos < data.length) { + this.buffer.set(data.subarray(pos), 0); + this.pos = data.length - pos; + } + return this; + } + + // See {@link https://www.rfc-editor.org/rfc/rfc4493.html#section-2.4 | RFC 4493 Section 2.4}. + digestInto(out: TArg): void { + if (this.destroyed) throw new Error('Hash instance has been destroyed'); + if (this.finished) throw new Error('Hash#digest() has already been called'); + // `digestInto(out)` is the no-allocation fast path, so AES block re-use below + // requires a 32-bit-aligned caller buffer instead of hidden temp copies. + aoutput(out, this, true); + this.finished = true; + // `digestInto()` accepts out.length >= outputLen, so only the first block stores the tag. + const view = out.subarray(0, this.outputLen); + let last = new Uint8Array(BLOCK_SIZE); + if (this.pos === BLOCK_SIZE) { + // M_last := M_n XOR K1; + last.set(this.buffer); + xorBlock(last, this.k1); + } else { + // M_last := padding(M_n) XOR K2; + // + // [...] padding(x) is the concatenation of x and a single '1', + // followed by the minimum number of '0's, so that the total length is + // equal to 128 bits. + last.set(this.buffer.subarray(0, this.pos)); + last[this.pos] = 0x80; // single '1' bit + xorBlock(last, this.k2); + } + view.set(this.x); // X := AES_CBC(K, M_1..M_{n-1}) + xorBlock(view, last); // Y := X XOR M_last + encryptBlock(this.xk, view); // T := AES-128(K, Y) + clean(last); + } + + digest(): Uint8ArrayBuffer { + const { buffer, outputLen } = this; + this.digestInto(buffer); + // Copy out before destroy() wipes the internal digest buffer in place. + const res = buffer.slice(0, outputLen); + this.destroy(); + return res; + } + + destroy(): void { + const { buffer, destroyed, x, xk, k1, k2 } = this; + if (destroyed) return; + this.destroyed = true; + // Wipe the buffered tail, chaining value, expanded AES key, and both CMAC subkeys. + clean(buffer, x, xk, k1, k2); + } +} + +/** + * AES-CMAC (Cipher-based Message Authentication Code). + * Specs: {@link https://www.rfc-editor.org/rfc/rfc4493.html | RFC 4493}. + * @param msg - Message bytes to authenticate. + * @param key - AES key bytes. + * @returns 16-byte authentication tag. `cmac.create(...)` follows the same incremental MAC shape as + * the other keyed helpers in this repo, including `blockLen`, + * `outputLen`, `digestInto()` and `destroy()`. + * @example + * Authenticates a message with AES-CMAC and a fresh key. + * + * ```ts + * import { cmac } from '@noble/ciphers/aes.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(16); + * cmac(new Uint8Array(), key); + * ``` + */ +// The 16-byte probe key is only used to read static metadata; runtime CMAC +// still accepts AES-128/192/256 keys. +export const cmac: TRet> = /* @__PURE__ */ wrapMacConstructor( + 16, + (key: TArg) => new _CMAC(key) +); + +/** + * S2V (Synthetic Initialization Vector) function as described in + * {@link https://datatracker.ietf.org/doc/html/rfc5297.html#section-2.4 | RFC 5297 Section 2.4}. + * + * ``` + * S2V(K, S1, ..., Sn) { + * if n = 0 then + * return V = AES-CMAC(K, ) + * fi + * D = AES-CMAC(K, ) + * for i = 1 to n-1 do + * D = dbl(D) xor AES-CMAC(K, Si) + * done + * if len(Sn) >= 128 then + * T = Sn xorend D + * else + * T = dbl(D) xor pad(Sn) + * fi + * return V = AES-CMAC(K, T) + * } + * ``` + * + * S2V takes a key and a vector of strings S1, S2, ..., Sn and returns a 128-bit string. + * The S2V function is used to generate a synthetic IV for AES-SIV. + * + * @param key - AES key (128, 192, or 256 bits) + * @param strings - Array of byte arrays to process + * @returns 128-bit synthetic IV + */ +function s2v(key: TArg, strings: TArg): TRet { + validateKeyLength(key); + const len = strings.length; + if (len > 127) { + // RFC 5297 §7 only proves S2V secure for at most 127 components; SIV + // spends one of those on the plaintext, leaving at most 126 AAD inputs. + throw new Error('s2v: number of input strings must be less than or equal to 127'); + } + + if (len === 0) return cmac(ONE_BLOCK, key); + + // D = AES-CMAC(K, ) + let d = cmac(EMPTY_BLOCK, key); + + // for i = 1 to n-1 do + // D = dbl(D) xor AES-CMAC(K, Si) + for (let i = 0; i < len - 1; i++) { + dbl(d); + const cmacResult = cmac(strings[i], key); + xorBlock(d, cmacResult); + clean(cmacResult); + } + + const s_n = strings[len - 1]; + // Earlier components are validated through cmac(...); validate the final one explicitly because + // the Uint8Array.from()/set() paths below would otherwise coerce array-like inputs silently. + abytes(s_n); + let t: Uint8Array; + + // if len(Sn) >= 128 then + if (s_n.byteLength >= BLOCK_SIZE) { + // T = Sn xorend D + t = xorend(Uint8Array.from(s_n), d); + } else { + // pad(Sn): + const paddedSn = new Uint8Array(BLOCK_SIZE); + paddedSn.set(s_n); + paddedSn[s_n.length] = 0x80; // padding: 0x80 followed by zeros + + // T = dbl(D) xor pad(Sn) + t = xorBlock(dbl(d), paddedSn); + clean(paddedSn); + } + + // V = AES-CMAC(K, T) + const result = cmac(t, key); + clean(d, t); + return result; +} + +/** + * Use `gcmsiv` or `aessiv`. + * @returns Never; always throws with the migration hint. + * @throws If called; `siv()` is a removed v1 alias. {@link Error} + * @example + * `siv()` was removed in v2; use `gcmsiv()` for nonce-based SIV instead. + * + * ```ts + * import { gcmsiv } from '@noble/ciphers/aes.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(16); + * const nonce = randomBytes(12); + * const cipher = gcmsiv(key, nonce); + * cipher.encrypt(new Uint8Array([1, 2, 3])); + * ``` + */ +export const siv: () => never = () => { + throw new Error('"siv" from v1 is now "gcmsiv"'); +}; + +/** + * **SIV**: Synthetic Initialization Vector (SIV) Authenticated Encryption + * Nonce is derived from the plaintext and AAD using the S2V function. + * Supports at most 126 AAD components. RFC 5297 nonce-based use is expressed by + * passing the nonce as the final AAD component before the plaintext. + * See {@link https://datatracker.ietf.org/doc/html/rfc5297.html | RFC 5297}. + * @param key - 32-byte, 48-byte, or 64-byte key. + * @param AAD - Additional authenticated data chunks (up to 126). + * @returns AEAD cipher instance. + * @example + * Authenticates and encrypts plaintext with a fresh key without requiring unique nonces. + * + * ```ts + * import { aessiv } from '@noble/ciphers/aes.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(32); + * const cipher = aessiv(key); + * cipher.encrypt(new Uint8Array([1, 2, 3])); + * ``` + */ +export const aessiv: TRet< + ((key: TArg, ...AAD: TArg) => Cipher) & { + blockSize: number; + tagLength: number; + } +> = /* @__PURE__ */ wrapCipher( + { blockSize: 16, tagLength: 16 }, + function aessiv(key: TArg, ...AAD: TArg): TRet { + // From RFC 5297: Section 6.1, 6.2, 6.3: + const PLAIN_LIMIT = limit('plaintext', 0, 2 ** 132); + const CIPHER_LIMIT = limit('ciphertext', 16, 2 ** 132 + 16); + if (AAD.length > 126) { + // RFC 5297 §2.6 / §2.7 / §7: SIV passes the plaintext as the last S2V + // component, so callers only get 126 associated-data components. + throw new Error('"AAD" number of elements must be less than or equal to 126'); + } + AAD.forEach((aad) => abytes(aad)); + abytes(key); + if (![32, 48, 64].includes(key.length)) + throw new Error('"aes key" expected Uint8Array of length 32/48/64, got length=' + key.length); + + // The key is split into equal halves, K1 = leftmost(K, len(K)/2) and + // K2 = rightmost(K, len(K)/2). K1 is used for S2V and K2 is used for CTR. + // This borrows caller key/AAD buffers by reference; mutating them after + // construction changes future encrypt/decrypt results. + const k1 = key.subarray(0, key.length / 2); + const k2 = key.subarray(key.length / 2); + + return { + // {@link https://datatracker.ietf.org/doc/html/rfc5297.html#section-2.6 | RFC 5297 Section 2.6} + encrypt(plaintext: TArg): TRet { + PLAIN_LIMIT(plaintext.length); + + const v = s2v(k1, [...AAD, plaintext]); + + // clear out the 31st and 63rd (rightmost) bit: + const q = Uint8Array.from(v); + q[8] &= 0x7f; + q[12] &= 0x7f; + + // encrypt: + const c = ctr(k2, q).encrypt(plaintext); + + return concatBytes(v, c); + }, + // {@link https://datatracker.ietf.org/doc/html/rfc5297.html#section-2.7 | RFC 5297 Section 2.7} + decrypt(ciphertext: TArg): TRet { + CIPHER_LIMIT(ciphertext.length); + const v = ciphertext.subarray(0, BLOCK_SIZE); + const c = ciphertext.subarray(BLOCK_SIZE); + + // clear out the 31st and 63rd (rightmost) bit: + const q = Uint8Array.from(v); + q[8] &= 0x7f; + q[12] &= 0x7f; + + // decrypt: + const p = ctr(k2, q).decrypt(c); + + // verify tag: + const t = s2v(k1, [...AAD, p]); + + if (equalBytes(t, v)) { + return p as TRet; + } else { + throw new Error('invalid siv tag'); + } + }, + } as TRet; + } +); +//#endregion + +/** + * Unsafe low-level internal methods. May change at any time. + * Callers are expected to use reviewed expanded-key outputs, pass mutable and + * aligned 16-byte blocks where required, and treat several helpers as in-place + * mutations of their input buffers or counters. + */ +export const unsafe: { + expandKeyLE: typeof expandKeyLE; + expandKeyDecLE: typeof expandKeyDecLE; + encrypt: typeof encrypt; + decrypt: typeof decrypt; + encryptBlock: typeof encryptBlock; + decryptBlock: typeof decryptBlock; + ctrCounter: typeof ctrCounter; + ctr32: typeof ctr32; + dbl: typeof dbl; + xorBlock: typeof xorBlock; + xorend: typeof xorend; + s2v: typeof s2v; +} = /* @__PURE__ */ Object.freeze({ + expandKeyLE, + expandKeyDecLE, + encrypt, + decrypt, + encryptBlock, + decryptBlock, + ctrCounter, + ctr32, + dbl, + xorBlock, + xorend, + s2v, +}); + +export const __TESTS: { incBytes: typeof incBytes } = /* @__PURE__ */ Object.freeze({ + incBytes: incBytes, +}); diff --git a/node_modules/@noble/ciphers/src/chacha.ts b/node_modules/@noble/ciphers/src/chacha.ts new file mode 100644 index 0000000..7b1d7c3 --- /dev/null +++ b/node_modules/@noble/ciphers/src/chacha.ts @@ -0,0 +1,579 @@ +/** + * ChaCha stream cipher, released + * in 2008. Developed after Salsa20, ChaCha aims to increase diffusion per round. + * It was standardized in + * {@link https://www.rfc-editor.org/rfc/rfc8439 | RFC 8439} and + * is now used in TLS 1.3. + * + * {@link https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha | XChaCha20} + * extended-nonce variant is also provided. Similar to XSalsa, it's safe to use with + * randomly-generated nonces. + * + * Check out + * {@link http://cr.yp.to/chacha/chacha-20080128.pdf | PDF}, + * {@link https://en.wikipedia.org/wiki/Salsa20 | wiki}, and + * {@link https://cr.yp.to/chacha.html | website}. + * + * @module + */ +import { type XorPRG, createCipher, createPRG, rotl } from './_arx.ts'; +import { poly1305 } from './_poly1305.ts'; +import { + type ARXCipher, + type CipherWithOutput, + type TArg, + type TRet, + type XorStream, + abytes, + clean, + equalBytes, + getOutput, + swap8IfBE, + swap32IfBE, + u64Lengths, + wrapCipher, +} from './utils.ts'; + +/** + * ChaCha core function. It is implemented twice: + * 1. Simple loop (chachaCore_small, hchacha_small) + * 2. Unrolled loop (chachaCore, hchacha) - 4x faster, but larger & harder to read + * The specific implementation is selected in `createCipher` below. + */ + +/** RFC 8439 §2.1 quarter round on words a, b, c, d. */ +// prettier-ignore +function chachaQR(x: TArg, a: number, b: number, c: number, d: number) { + x[a] = (x[a] + x[b]) | 0; x[d] = rotl(x[d] ^ x[a], 16); + x[c] = (x[c] + x[d]) | 0; x[b] = rotl(x[b] ^ x[c], 12); + x[a] = (x[a] + x[b]) | 0; x[d] = rotl(x[d] ^ x[a], 8); + x[c] = (x[c] + x[d]) | 0; x[b] = rotl(x[b] ^ x[c], 7); +} + +/** Repeated ChaCha double rounds; callers are expected to pass an even round count. */ +function chachaRound(x: TArg, rounds = 20) { + for (let r = 0; r < rounds; r += 2) { + // RFC 8439 §2.3 / §2.3.1 inner_block: four column rounds, then four diagonal rounds. + chachaQR(x, 0, 4, 8, 12); + chachaQR(x, 1, 5, 9, 13); + chachaQR(x, 2, 6, 10, 14); + chachaQR(x, 3, 7, 11, 15); + chachaQR(x, 0, 5, 10, 15); + chachaQR(x, 1, 6, 11, 12); + chachaQR(x, 2, 7, 8, 13); + chachaQR(x, 3, 4, 9, 14); + } +} + +// Shared scratch for the auditability-only helper below; only the test-only +// __TESTS.chachaCore_small hook reaches it, so production exports stay reentrant. +const ctmp = /* @__PURE__ */ new Uint32Array(16); + +/** Small version of chacha without loop unrolling. Unused, provided for auditability. */ +// prettier-ignore +function chacha( + s: TArg, k: TArg, i: TArg, out: TArg, + isHChacha: boolean = true, rounds: number = 20 +): void { + // `i` is either `[counter, nonce0, nonce1, nonce2]` for the ChaCha block + // function or the full 128-bit nonce prefix for the HChaCha subkey path. + // Create initial array using common pattern + const y = Uint32Array.from([ + s[0], s[1], s[2], s[3], // "expa" "nd 3" "2-by" "te k" + k[0], k[1], k[2], k[3], // Key Key Key Key + k[4], k[5], k[6], k[7], // Key Key Key Key + i[0], i[1], i[2], i[3], // Counter Counter Nonce Nonce + ]); + const x = ctmp; + x.set(y); + chachaRound(x, rounds); + + // HChaCha writes words 0..3 and 12..15 after the rounds; the ChaCha + // block path adds the original state word-by-word. + if (isHChacha) { + const xindexes = [0, 1, 2, 3, 12, 13, 14, 15]; + for (let i = 0; i < 8; i++) out[i] = x[xindexes[i]]; + } else { + for (let i = 0; i < 16; i++) out[i] = (y[i] + x[i]) | 0; + } +} + +/** Identical to `chachaCore`. Reached only through the test-only `__TESTS` export. */ +// @ts-ignore +const chachaCore_small: typeof chachaCore = (s, k, n, out, cnt, rounds) => + // Keep the reference wrapper on the same [counter, nonce0, nonce1, nonce2] layout as chacha(). + chacha(s, k, Uint32Array.from([cnt, n[0], n[1], n[2]]), out, false, rounds); +/** Identical to `hchacha`. Unused. */ +// @ts-ignore +const hchacha_small: typeof hchacha = chacha; + +/** RFC 8439 §2.3 block core for `state = constants | key | counter | nonce`. */ +// prettier-ignore +function chachaCore( + s: TArg, k: TArg, n: TArg, out: TArg, cnt: number, rounds = 20 +): void { + let y00 = s[0], y01 = s[1], y02 = s[2], y03 = s[3], // "expa" "nd 3" "2-by" "te k" + y04 = k[0], y05 = k[1], y06 = k[2], y07 = k[3], // Key Key Key Key + y08 = k[4], y09 = k[5], y10 = k[6], y11 = k[7], // Key Key Key Key + y12 = cnt, y13 = n[0], y14 = n[1], y15 = n[2]; // Counter Nonce Nonce Nonce + // Save state to temporary variables + let x00 = y00, x01 = y01, x02 = y02, x03 = y03, + x04 = y04, x05 = y05, x06 = y06, x07 = y07, + x08 = y08, x09 = y09, x10 = y10, x11 = y11, + x12 = y12, x13 = y13, x14 = y14, x15 = y15; + for (let r = 0; r < rounds; r += 2) { + x00 = (x00 + x04) | 0; x12 = rotl(x12 ^ x00, 16); + x08 = (x08 + x12) | 0; x04 = rotl(x04 ^ x08, 12); + x00 = (x00 + x04) | 0; x12 = rotl(x12 ^ x00, 8); + x08 = (x08 + x12) | 0; x04 = rotl(x04 ^ x08, 7); + + x01 = (x01 + x05) | 0; x13 = rotl(x13 ^ x01, 16); + x09 = (x09 + x13) | 0; x05 = rotl(x05 ^ x09, 12); + x01 = (x01 + x05) | 0; x13 = rotl(x13 ^ x01, 8); + x09 = (x09 + x13) | 0; x05 = rotl(x05 ^ x09, 7); + + x02 = (x02 + x06) | 0; x14 = rotl(x14 ^ x02, 16); + x10 = (x10 + x14) | 0; x06 = rotl(x06 ^ x10, 12); + x02 = (x02 + x06) | 0; x14 = rotl(x14 ^ x02, 8); + x10 = (x10 + x14) | 0; x06 = rotl(x06 ^ x10, 7); + + x03 = (x03 + x07) | 0; x15 = rotl(x15 ^ x03, 16); + x11 = (x11 + x15) | 0; x07 = rotl(x07 ^ x11, 12); + x03 = (x03 + x07) | 0; x15 = rotl(x15 ^ x03, 8) + x11 = (x11 + x15) | 0; x07 = rotl(x07 ^ x11, 7); + + x00 = (x00 + x05) | 0; x15 = rotl(x15 ^ x00, 16); + x10 = (x10 + x15) | 0; x05 = rotl(x05 ^ x10, 12); + x00 = (x00 + x05) | 0; x15 = rotl(x15 ^ x00, 8); + x10 = (x10 + x15) | 0; x05 = rotl(x05 ^ x10, 7); + + x01 = (x01 + x06) | 0; x12 = rotl(x12 ^ x01, 16); + x11 = (x11 + x12) | 0; x06 = rotl(x06 ^ x11, 12); + x01 = (x01 + x06) | 0; x12 = rotl(x12 ^ x01, 8); + x11 = (x11 + x12) | 0; x06 = rotl(x06 ^ x11, 7); + + x02 = (x02 + x07) | 0; x13 = rotl(x13 ^ x02, 16); + x08 = (x08 + x13) | 0; x07 = rotl(x07 ^ x08, 12); + x02 = (x02 + x07) | 0; x13 = rotl(x13 ^ x02, 8); + x08 = (x08 + x13) | 0; x07 = rotl(x07 ^ x08, 7); + + x03 = (x03 + x04) | 0; x14 = rotl(x14 ^ x03, 16) + x09 = (x09 + x14) | 0; x04 = rotl(x04 ^ x09, 12); + x03 = (x03 + x04) | 0; x14 = rotl(x14 ^ x03, 8); + x09 = (x09 + x14) | 0; x04 = rotl(x04 ^ x09, 7); + } + // RFC 8439 §2.3 / §2.3.1: add the original state words back in state order. + let oi = 0; + out[oi++] = (y00 + x00) | 0; out[oi++] = (y01 + x01) | 0; + out[oi++] = (y02 + x02) | 0; out[oi++] = (y03 + x03) | 0; + out[oi++] = (y04 + x04) | 0; out[oi++] = (y05 + x05) | 0; + out[oi++] = (y06 + x06) | 0; out[oi++] = (y07 + x07) | 0; + out[oi++] = (y08 + x08) | 0; out[oi++] = (y09 + x09) | 0; + out[oi++] = (y10 + x10) | 0; out[oi++] = (y11 + x11) | 0; + out[oi++] = (y12 + x12) | 0; out[oi++] = (y13 + x13) | 0; + out[oi++] = (y14 + x14) | 0; out[oi++] = (y15 + x15) | 0; +} +/** + * hchacha hashes key and nonce into key' and nonce' for xchacha20. + * Algorithmically identical to `hchacha_small`, but this exported path + * normalizes word order on big-endian hosts. + * Need to find a way to merge it with `chachaCore` without 25% performance hit. + * @param s - Sigma constants as 32-bit words. + * @param k - Key words. + * @param i - Nonce-prefix words. + * @param out - Output buffer for the derived subkey. + * @example + * Derives the XChaCha subkey from sigma, key, and nonce-prefix words. + * + * ```ts + * const sigma = new Uint32Array(4); + * const key = new Uint32Array(8); + * const nonce = new Uint32Array(4); + * const out = new Uint32Array(8); + * hchacha(sigma, key, nonce, out); + * ``` + */ +// prettier-ignore +export function hchacha( + s: TArg, k: TArg, i: TArg, out: TArg +): void { + let x00 = swap8IfBE(s[0]), x01 = swap8IfBE(s[1]), x02 = swap8IfBE(s[2]), x03 = swap8IfBE(s[3]), + x04 = swap8IfBE(k[0]), x05 = swap8IfBE(k[1]), x06 = swap8IfBE(k[2]), x07 = swap8IfBE(k[3]), + x08 = swap8IfBE(k[4]), x09 = swap8IfBE(k[5]), x10 = swap8IfBE(k[6]), x11 = swap8IfBE(k[7]), + x12 = swap8IfBE(i[0]), x13 = swap8IfBE(i[1]), x14 = swap8IfBE(i[2]), x15 = swap8IfBE(i[3]); + for (let r = 0; r < 20; r += 2) { + x00 = (x00 + x04) | 0; x12 = rotl(x12 ^ x00, 16); + x08 = (x08 + x12) | 0; x04 = rotl(x04 ^ x08, 12); + x00 = (x00 + x04) | 0; x12 = rotl(x12 ^ x00, 8); + x08 = (x08 + x12) | 0; x04 = rotl(x04 ^ x08, 7); + + x01 = (x01 + x05) | 0; x13 = rotl(x13 ^ x01, 16); + x09 = (x09 + x13) | 0; x05 = rotl(x05 ^ x09, 12); + x01 = (x01 + x05) | 0; x13 = rotl(x13 ^ x01, 8); + x09 = (x09 + x13) | 0; x05 = rotl(x05 ^ x09, 7); + + x02 = (x02 + x06) | 0; x14 = rotl(x14 ^ x02, 16); + x10 = (x10 + x14) | 0; x06 = rotl(x06 ^ x10, 12); + x02 = (x02 + x06) | 0; x14 = rotl(x14 ^ x02, 8); + x10 = (x10 + x14) | 0; x06 = rotl(x06 ^ x10, 7); + + x03 = (x03 + x07) | 0; x15 = rotl(x15 ^ x03, 16); + x11 = (x11 + x15) | 0; x07 = rotl(x07 ^ x11, 12); + x03 = (x03 + x07) | 0; x15 = rotl(x15 ^ x03, 8) + x11 = (x11 + x15) | 0; x07 = rotl(x07 ^ x11, 7); + + x00 = (x00 + x05) | 0; x15 = rotl(x15 ^ x00, 16); + x10 = (x10 + x15) | 0; x05 = rotl(x05 ^ x10, 12); + x00 = (x00 + x05) | 0; x15 = rotl(x15 ^ x00, 8); + x10 = (x10 + x15) | 0; x05 = rotl(x05 ^ x10, 7); + + x01 = (x01 + x06) | 0; x12 = rotl(x12 ^ x01, 16); + x11 = (x11 + x12) | 0; x06 = rotl(x06 ^ x11, 12); + x01 = (x01 + x06) | 0; x12 = rotl(x12 ^ x01, 8); + x11 = (x11 + x12) | 0; x06 = rotl(x06 ^ x11, 7); + + x02 = (x02 + x07) | 0; x13 = rotl(x13 ^ x02, 16); + x08 = (x08 + x13) | 0; x07 = rotl(x07 ^ x08, 12); + x02 = (x02 + x07) | 0; x13 = rotl(x13 ^ x02, 8); + x08 = (x08 + x13) | 0; x07 = rotl(x07 ^ x08, 7); + + x03 = (x03 + x04) | 0; x14 = rotl(x14 ^ x03, 16) + x09 = (x09 + x14) | 0; x04 = rotl(x04 ^ x09, 12); + x03 = (x03 + x04) | 0; x14 = rotl(x14 ^ x03, 8); + x09 = (x09 + x14) | 0; x04 = rotl(x04 ^ x09, 7); + } + // HChaCha derives the subkey from state words 0..3 and 12..15 after 20 rounds. + let oi = 0; + out[oi++] = x00; out[oi++] = x01; + out[oi++] = x02; out[oi++] = x03; + out[oi++] = x12; out[oi++] = x13; + out[oi++] = x14; out[oi++] = x15; + swap32IfBE(out); +} + +/** + * Original, non-RFC chacha20 from DJB. 8-byte nonce, 8-byte counter. + * The nonce/counter layout still reserves 8 counter bytes internally, but the shared public + * `counter` argument follows noble's strict non-wrapping 32-bit policy. See `src/_arx.ts` + * near `MAX_COUNTER` for the full counter-policy rationale. + * @param key - 16-byte or 32-byte key. + * @param nonce - 8-byte nonce. + * @param data - Input bytes to xor with the keystream. + * @param output - Optional destination buffer. + * @param counter - Initial block counter. + * @returns Encrypted or decrypted bytes. + * @example + * Encrypts bytes with the original 8-byte-nonce ChaCha variant and a fresh key/nonce. + * + * ```ts + * import { chacha20orig } from '@noble/ciphers/chacha.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(32); + * const nonce = randomBytes(8); + * chacha20orig(key, nonce, new Uint8Array(4)); + * ``` + */ +export const chacha20orig: TRet = /* @__PURE__ */ createCipher(chachaCore, { + counterRight: false, + counterLength: 8, + allowShortKeys: true, +}); +/** + * ChaCha stream cipher. Conforms to RFC 8439 (IETF, TLS). 12-byte nonce, 4-byte counter. + * With smaller nonce, it's not safe to make it random (CSPRNG), due to collision chance. + * @param key - 32-byte key. + * @param nonce - 12-byte nonce. + * @param data - Input bytes to xor with the keystream. + * @param output - Optional destination buffer. + * @param counter - Initial block counter. + * @returns Encrypted or decrypted bytes. + * @example + * Encrypts bytes with the RFC 8439 ChaCha20 stream cipher and a fresh key/nonce. + * + * ```ts + * import { chacha20 } from '@noble/ciphers/chacha.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(32); + * const nonce = randomBytes(12); + * chacha20(key, nonce, new Uint8Array(4)); + * ``` + */ +export const chacha20: TRet = /* @__PURE__ */ createCipher(chachaCore, { + counterRight: false, + counterLength: 4, + allowShortKeys: false, +}); + +/** + * XChaCha eXtended-nonce ChaCha. With 24-byte nonce, it's safe to make it random (CSPRNG). + * See {@link https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha | the IRTF draft}. + * The nonce/counter layout still reserves 8 counter bytes internally, but the shared public + * `counter` argument follows noble's strict non-wrapping 32-bit policy. See `src/_arx.ts` + * near `MAX_COUNTER` for the full counter-policy rationale. + * @param key - 32-byte key. + * @param nonce - 24-byte extended nonce. + * @param data - Input bytes to xor with the keystream. + * @param output - Optional destination buffer. + * @param counter - Initial block counter. + * @returns Encrypted or decrypted bytes. + * @example + * Encrypts bytes with XChaCha20 using a fresh key and random 24-byte nonce. + * + * ```ts + * import { xchacha20 } from '@noble/ciphers/chacha.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(32); + * const nonce = randomBytes(24); + * xchacha20(key, nonce, new Uint8Array(4)); + * ``` + */ +export const xchacha20: TRet = /* @__PURE__ */ createCipher(chachaCore, { + counterRight: false, + counterLength: 8, + extendNonceFn: hchacha, + allowShortKeys: false, +}); + +/** + * Reduced 8-round chacha, described in original paper. + * @param key - 32-byte key. + * @param nonce - 12-byte nonce. + * @param data - Input bytes to xor with the keystream. + * @param output - Optional destination buffer. + * @param counter - Initial block counter. + * @returns Encrypted or decrypted bytes. + * @example + * Uses the reduced 8-round variant for non-critical workloads with a fresh key/nonce. + * + * ```ts + * import { chacha8 } from '@noble/ciphers/chacha.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(32); + * const nonce = randomBytes(12); + * chacha8(key, nonce, new Uint8Array(4)); + * ``` + */ +export const chacha8: TRet = /* @__PURE__ */ createCipher(chachaCore, { + counterRight: false, + counterLength: 4, + rounds: 8, +}); + +/** + * Reduced 12-round chacha, described in original paper. + * @param key - 32-byte key. + * @param nonce - 12-byte nonce. + * @param data - Input bytes to xor with the keystream. + * @param output - Optional destination buffer. + * @param counter - Initial block counter. + * @returns Encrypted or decrypted bytes. + * @example + * Uses the reduced 12-round variant for non-critical workloads with a fresh key/nonce. + * + * ```ts + * import { chacha12 } from '@noble/ciphers/chacha.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(32); + * const nonce = randomBytes(12); + * chacha12(key, nonce, new Uint8Array(4)); + * ``` + */ +export const chacha12: TRet = /* @__PURE__ */ createCipher(chachaCore, { + counterRight: false, + counterLength: 4, + rounds: 12, +}); + +// Test-only hooks for keeping the simple/reference core aligned with the unrolled production core. +export const __TESTS: { + chachaCore_small: typeof chachaCore_small; + chachaCore: typeof chachaCore; +} = /* @__PURE__ */ Object.freeze({ chachaCore_small, chachaCore }); + +// RFC 8439 §2.8.1 pad16(x): shared zero block for AAD/ciphertext padding. +const ZEROS16 = /* @__PURE__ */ new Uint8Array(16); +// RFC 8439 §2.8 / §2.8.1: aligned inputs add nothing, otherwise append 16-(len%16) zero bytes. +const updatePadded = (h: ReturnType, msg: TArg) => { + h.update(msg); + const leftover = msg.length % 16; + if (leftover) h.update(ZEROS16.subarray(leftover)); +}; + +// RFC 8439 §2.6.1 poly1305_key_gen returns `block[0..31]`, so AEAD key +// generation only needs 32 zero bytes. +const ZEROS32 = /* @__PURE__ */ new Uint8Array(32); +function computeTag( + fn: TArg, + key: TArg, + nonce: TArg, + ciphertext: TArg, + AAD?: TArg +): TRet { + if (AAD !== undefined) abytes(AAD, undefined, 'AAD'); + // RFC 8439 §2.6 / §2.8: derive the Poly1305 one-time key from counter 0, + // then MAC AAD || pad16(AAD) || ciphertext || pad16(ciphertext) || len(AAD) || len(ciphertext). + const authKey = fn( + key as TRet, + nonce as TRet, + ZEROS32 as TRet + ); + const lengths = u64Lengths(ciphertext.length, AAD ? AAD.length : 0, true); + + // Methods below can be replaced with + // return poly1305_computeTag_small(authKey, lengths, ciphertext, AAD) + const h = poly1305.create(authKey); + if (AAD) updatePadded(h, AAD); + updatePadded(h, ciphertext); + h.update(lengths); + const res = h.digest(); + clean(authKey, lengths); + return res; +} + +/** + * AEAD algorithm from RFC 8439. + * Salsa20 and chacha (RFC 8439) use poly1305 differently. + * We could have composed them, but it's hard because of authKey: + * In salsa20, authKey changes position in salsa stream. + * In chacha, authKey can't be computed inside computeTag, it modifies the counter. + */ +export const _poly1305_aead = + (xorStream: TArg) => + (key: TArg, nonce: TArg, AAD?: TArg): CipherWithOutput => { + // This borrows caller key/nonce/AAD buffers by reference; mutating them after construction + // changes future encrypt/decrypt results. + const tagLength = 16; + return { + encrypt(plaintext: TArg, output?: TArg): TRet { + const plength = plaintext.length; + output = getOutput(plength + tagLength, output, false); + output.set(plaintext); + const oPlain = output.subarray(0, -tagLength); + // RFC 8439 §2.8: payload encryption starts at counter 1 because counter 0 produced the OTK. + xorStream( + key as TRet, + nonce as TRet, + oPlain as TRet, + oPlain as TRet, + 1 + ); + const tag = computeTag(xorStream, key, nonce, oPlain, AAD); + output.set(tag, plength); // append tag + clean(tag); + return output as TRet; + }, + decrypt(ciphertext: TArg, output?: TArg): TRet { + output = getOutput(ciphertext.length - tagLength, output, false); + const data = ciphertext.subarray(0, -tagLength); + const passedTag = ciphertext.subarray(-tagLength); + const tag = computeTag(xorStream, key, nonce, data, AAD); + // RFC 8439 §2.8 / §4: authenticate ciphertext before decrypting it, and compare tags with + // the constant-time equalBytes() helper rather than decrypting speculative plaintext first. + if (!equalBytes(passedTag, tag)) { + clean(tag); + throw new Error('invalid tag'); + } + output.set(ciphertext.subarray(0, -tagLength)); + // Actual decryption + xorStream( + key as TRet, + nonce as TRet, + output as TRet, + output as TRet, + 1 + ); // start stream with i=1 + clean(tag); + return output as TRet; + }, + }; + }; + +/** + * ChaCha20-Poly1305 from RFC 8439. + * + * Unsafe to use random nonces under the same key, due to collision chance. + * Prefer XChaCha instead. + * @param key - 32-byte key. + * @param nonce - 12-byte nonce. + * @param AAD - Additional authenticated data. + * @returns AEAD cipher instance. + * @example + * Encrypts and authenticates plaintext with a fresh key and nonce. + * + * ```ts + * import { chacha20poly1305 } from '@noble/ciphers/chacha.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(32); + * const nonce = randomBytes(12); + * const cipher = chacha20poly1305(key, nonce); + * cipher.encrypt(new Uint8Array([1, 2, 3])); + * ``` + */ +export const chacha20poly1305: TRet = /* @__PURE__ */ wrapCipher( + { blockSize: 64, nonceLength: 12, tagLength: 16 }, + /* @__PURE__ */ _poly1305_aead(chacha20) +); +/** + * XChaCha20-Poly1305 extended-nonce chacha. + * + * Can be safely used with random nonces (CSPRNG). + * See {@link https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha | the IRTF draft}. + * @param key - 32-byte key. + * @param nonce - 24-byte nonce. + * @param AAD - Additional authenticated data. + * @returns AEAD cipher instance. + * @example + * Encrypts and authenticates plaintext with a fresh key and random 24-byte nonce. + * + * ```ts + * import { xchacha20poly1305 } from '@noble/ciphers/chacha.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(32); + * const nonce = randomBytes(24); + * const cipher = xchacha20poly1305(key, nonce); + * cipher.encrypt(new Uint8Array([1, 2, 3])); + * ``` + */ +export const xchacha20poly1305: TRet = /* @__PURE__ */ wrapCipher( + { blockSize: 64, nonceLength: 24, tagLength: 16 }, + /* @__PURE__ */ _poly1305_aead(xchacha20) +); + +/** + * Chacha20 CSPRNG (cryptographically secure pseudorandom number generator). + * It's best to limit usage to non-production, non-critical cases: for example, test-only. + * Compatible with libtomcrypt. It does not have a specification, so unclear how secure it is. + * @param seed - Optional seed bytes mixed into the internal `key || nonce` state. When omitted, + * only 32 random bytes are mixed into the 40-byte state. + * @returns Seeded concrete `_XorStreamPRG` instance, including `clone()`. + * @example + * Seeds the test-only ChaCha20 DRBG from fresh entropy. + * + * ```ts + * import { rngChacha20 } from '@noble/ciphers/chacha.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const seed = randomBytes(32); + * const prg = rngChacha20(seed); + * prg.randomBytes(8); + * ``` + */ +export const rngChacha20: TRet = /* @__PURE__ */ createPRG(chacha20orig, 64, 32, 8); +/** + * Chacha20/8 CSPRNG (cryptographically secure pseudorandom number generator). + * It's best to limit usage to non-production, non-critical cases: for example, test-only. + * Faster than `rngChacha20`. + * @param seed - Optional seed bytes mixed into the internal `key || nonce` state. When omitted, + * only 32 random bytes are mixed into the 44-byte state. + * @returns Seeded concrete `_XorStreamPRG` instance, including `clone()`. + * @example + * Seeds the faster test-only ChaCha8 DRBG from fresh entropy. + * + * ```ts + * import { rngChacha8 } from '@noble/ciphers/chacha.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const seed = randomBytes(32); + * const prg = rngChacha8(seed); + * prg.randomBytes(8); + * ``` + */ +export const rngChacha8: TRet = /* @__PURE__ */ createPRG(chacha8, 64, 32, 12); diff --git a/node_modules/@noble/ciphers/src/ff1.ts b/node_modules/@noble/ciphers/src/ff1.ts new file mode 100644 index 0000000..45a178e --- /dev/null +++ b/node_modules/@noble/ciphers/src/ff1.ts @@ -0,0 +1,221 @@ +/** + * FPE-FF1 (Format-preserving encryption algorithm) specified in + * {@link https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38G.pdf | NIST 800-38G}. + * @module + */ +import { unsafe } from './aes.ts'; +import { + abytes, + anumber, + bytesToNumberBE, + clean, + numberToBytesBE, + type Cipher, + type TArg, + type TRet, +} from './utils.ts'; + +// NIST SP 800-38G §4.3 / §5.1 Algorithm 7: FF1's designated CIPH_K here is AES, so this file +// reuses the reviewed AES key schedule and single-block encryption helpers. +// NOTE: no point in inlining encrypt instead of encryptBlock, since BigInt stuff will be slow +const { expandKeyLE, encryptBlock } = unsafe; + +// Format-preserving encryption algorithm (FPE-FF1) specified in +// {@link https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38G.pdf | NIST Special Publication 800-38G}. + +const BLOCK_LEN = 16; + +// FF1 step 6vi needs mathematical modulo in [0, b); JS `%` is remainder, so decrypt rounds must +// map negative intermediate values back into that range. +function mod(a: number, b: number): number; +function mod(a: bigint, b: bigint): bigint; +function mod(a: any, b: any): number | bigint { + const result = a % b; + return result >= 0 ? result : b + result; +} + +function NUMradix(radix: number, data: number[]): bigint { + let res = BigInt(0); + for (let i of data) res = res * BigInt(radix) + BigInt(i); + return res; +} + +function getRound(radix: number, key: TArg, tweak: TArg, x: number[]) { + if (radix > 2 ** 16 - 1) throw new Error('invalid radix ' + radix); + // radix**minlen ≥ 100 + const minLen = Math.ceil(Math.log(100) / Math.log(radix)); + const maxLen = 2 ** 32 - 1; + // 2 ≤ minlen ≤ maxlen < 2**32 + if (2 > minLen || minLen > maxLen || maxLen >= 2 ** 32) + throw new Error('Invalid radix: 2 ≤ minlen ≤ maxlen < 2**32'); + if (!Array.isArray(x)) throw new Error('invalid X'); + if (x.length < minLen || x.length > maxLen) throw new Error('X is outside minLen..maxLen bounds'); + // SP 800-38G defines FF1 over numeral strings in base `radix`; out-of-range digits must fail + // before NUMradix(...) or round splitting can reinterpret them as a different numeral string. + for (const i of x) { + if (!Number.isSafeInteger(i) || i < 0 || i >= radix) + throw new Error('invalid X: digit outside radix'); + } + const u = Math.floor(x.length / 2); + const v = x.length - u; + const b = Math.ceil(Math.ceil(v * Math.log2(radix)) / 8); + const d = 4 * Math.ceil(b / 4) + 4; + const padding = mod(-tweak.length - b - 1, 16); + // P = [1]1 || [2]1 || [1]1 || [radix]3 || [10]1 || [u mod 256]1 || [n]4 || [t]4. + const P = Uint8Array.from([1, 2, 1, 0, 0, 0, 10, u, 0, 0, 0, 0, 0, 0, 0, 0]); + const view = new DataView(P.buffer); + // NIST SP 800-38G §5.1 bounds radix <= 2^16, so the 24-bit [radix]3 field is encoded here as + // 0x00 || uint16_be(radix). + view.setUint16(4, radix, false); + view.setUint32(8, x.length, false); + view.setUint32(12, tweak.length, false); + // Q = T || [0](−t−b−1) mod 16 || [i]1 || [NUMradix(B)]b. + const PQ = new Uint8Array(P.length + tweak.length + padding + 1 + b); + PQ.set(P); + clean(P); + PQ.set(tweak, P.length); + const xk = expandKeyLE(key); + const round = (A: number[], B: number[], i: number, decrypt = false) => { + // Q = ... || [i]1 || [NUMradix(B)]b. + PQ[PQ.length - b - 1] = i; + if (b) PQ.set(numberToBytesBE(NUMradix(radix, B), b), PQ.length - b); + // NIST SP 800-38G Algorithm 6 PRF: Y_j = CIPH_K(Y_(j-1) xor X_j) starting from Y_0 = 0^128. + let r = new Uint8Array(16); + for (let j = 0; j < PQ.length / BLOCK_LEN; j++) { + for (let i = 0; i < BLOCK_LEN; i++) r[i] ^= PQ[j * BLOCK_LEN + i]; + encryptBlock(xk, r); + } + // Let S be the first d bytes of the following string of ⎡d/16⎤ blocks: + // R || CIPHK(R ⊕[1]16) || CIPHK(R ⊕[2]16) ...CIPHK(R ⊕[⎡d / 16⎤ – 1]16). + let s = Array.from(r); + for (let j = 1; s.length < d; j++) { + const block = numberToBytesBE(BigInt(j), 16); + for (let k = 0; k < BLOCK_LEN; k++) block[k] ^= r[k]; + s.push(...Array.from(encryptBlock(xk, block))); + } + let y = bytesToNumberBE(Uint8Array.from(s.slice(0, d))); + s.fill(0); + if (decrypt) y = -y; + const m = i % 2 === 0 ? u : v; + let c = mod(NUMradix(radix, A) + y, BigInt(radix) ** BigInt(m)); + // STR(radix, m, c) + const C = Array(m).fill(0); + for (let i = 0; i < m; i++, c /= BigInt(radix)) C[m - 1 - i] = Number(c % BigInt(radix)); + A.fill(0); + A = B; + B = C; + return [A, B]; + }; + const destroy = () => { + clean(xk, PQ); + }; + return { u, round, destroy }; +} + +const EMPTY_BUF = /* @__PURE__ */ Uint8Array.of(); + +/** + * FPE-FF1 format-preserving encryption. + * @param radix - Alphabet size for each input digit. + * @param key - AES key bytes. + * @param tweak - Optional tweak bytes. + * @returns Encrypt/decrypt helpers over digit arrays. + * @example + * Encrypts decimal digits without changing their format, using a fresh AES key. + * + * ```ts + * import { FF1 } from '@noble/ciphers/ff1.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(16); + * const ff1 = FF1(10, key); + * ff1.encrypt([1, 2, 3]); + * ``` + */ +export function FF1( + radix: number, + key: TArg, + tweak: TArg = EMPTY_BUF +): { encrypt(x: number[]): number[]; decrypt(x: number[]): number[] } { + anumber(radix); + abytes(key); + abytes(tweak); + // This borrows caller key/tweak buffers by reference through the bound closure; mutating them + // after construction changes later encrypt/decrypt outputs. + const PQ = getRound.bind(null, radix, key, tweak); + return { + encrypt(x: number[]): number[] { + const { u, round, destroy } = PQ(x); + let [A, B] = [x.slice(0, u), x.slice(u)]; + for (let i = 0; i < 10; i++) [A, B] = round(A, B, i); + destroy(); + const res = A.concat(B); + A.fill(0); + B.fill(0); + return res; + }, + decrypt(x: number[]): number[] { + const { u, round, destroy } = PQ(x); + // The FF1.Decrypt algorithm is similar to the FF1.Encrypt algorithm; + // the differences are in Step 6, where: + // 1) the order of the indices is reversed, + // 2) the roles of A and B are swapped + // 3) modular addition is replaced by modular subtraction, in Step 6vi. + let [B, A] = [x.slice(0, u), x.slice(u)]; + for (let i = 9; i >= 0; i--) [A, B] = round(A, B, i, true); + destroy(); + const res = B.concat(A); + A.fill(0); + B.fill(0); + return res; + }, + }; +} +// Binary wrapper uses little-endian bit order within each byte so bit 0 stays +// in the first numeral slot for this library-defined byte-array surface. +const binLE = { + encode(bytes: TArg): number[] { + const x = []; + for (let i = 0; i < bytes.length; i++) { + for (let j = 0, tmp = bytes[i]; j < 8; j++, tmp >>= 1) x.push(tmp & 1); + } + return x; + }, + decode(b: number[]): TRet { + if (!Array.isArray(b) || b.length % 8) throw new Error('Invalid binary string'); + const res = new Uint8Array(b.length / 8); + for (let i = 0, j = 0; i < res.length; i++) { + res[i] = b[j++] | (b[j++] << 1) | (b[j++] << 2) | (b[j++] << 3); + res[i] |= (b[j++] << 4) | (b[j++] << 5) | (b[j++] << 6) | (b[j++] << 7); + } + return res as TRet; + }, +}; + +/** + * Binary FPE-FF1 wrapper over byte arrays. + * @param key - AES key bytes. + * @param tweak - Optional tweak bytes. + * @returns Encrypt/decrypt helpers over byte arrays. + * @example + * Encrypts raw bytes through FF1's binary alphabet wrapper with a fresh AES key. + * + * ```ts + * import { BinaryFF1 } from '@noble/ciphers/ff1.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(16); + * const ff1 = BinaryFF1(key); + * ff1.encrypt(new Uint8Array([1, 2, 3])); + * ``` + */ +export function BinaryFF1( + key: TArg, + tweak: TArg = EMPTY_BUF +): TRet { + const ff1 = FF1(2, key, tweak); + return { + encrypt: (x: TArg): TRet => + binLE.decode(ff1.encrypt(binLE.encode(x))) as TRet, + decrypt: (x: TArg): TRet => + binLE.decode(ff1.decrypt(binLE.encode(x))) as TRet, + } as TRet; +} diff --git a/node_modules/@noble/ciphers/src/index.ts b/node_modules/@noble/ciphers/src/index.ts new file mode 100644 index 0000000..466af82 --- /dev/null +++ b/node_modules/@noble/ciphers/src/index.ts @@ -0,0 +1,25 @@ +/** + * Audited & minimal JS implementation of Salsa20, ChaCha and AES. Check out individual modules. + * @example +```js +import { gcm, aessiv } from '@noble/ciphers/aes.js'; +import { xsalsa20poly1305 } from '@noble/ciphers/salsa.js'; +import { secretbox } from '@noble/ciphers/salsa.js'; // == xsalsa20poly1305 +import { chacha20poly1305, xchacha20poly1305 } from '@noble/ciphers/chacha.js'; + +// Unauthenticated encryption: make sure to use HMAC or similar +import { ctr, cfb, cbc, ecb } from '@noble/ciphers/aes.js'; +import { salsa20, xsalsa20 } from '@noble/ciphers/salsa.js'; +import { chacha20, xchacha20, chacha8, chacha12 } from '@noble/ciphers/chacha.js'; + +// KW +import { aeskw, aeskwp } from '@noble/ciphers/aes.js'; + +// Utilities +import { managedNonce, randomBytes, bytesToHex, hexToBytes } from '@noble/ciphers/utils.js'; +import { poly1305 } from '@noble/ciphers/_poly1305.js'; +import { ghash, polyval } from '@noble/ciphers/_polyval.js'; +``` + * @module + */ +throw new Error('root module cannot be imported: import submodules instead. Check out README'); diff --git a/node_modules/@noble/ciphers/src/salsa.ts b/node_modules/@noble/ciphers/src/salsa.ts new file mode 100644 index 0000000..840fbc1 --- /dev/null +++ b/node_modules/@noble/ciphers/src/salsa.ts @@ -0,0 +1,374 @@ +/** + * Salsa20 stream cipher, released in 2005. + * Salsa's goal was to implement AES replacement that does not rely on S-Boxes, + * which are hard to implement in a constant-time manner. + * Salsa20 is usually faster than AES, a big deal on slow, budget mobile phones. + * + * - {@link https://cr.yp.to/snuffle/xsalsa-20110204.pdf | XSalsa20}, + * extended-nonce + * variant was released in 2008. It extends Salsa20's 64-bit nonce to 192 bits, + * and became safe to be picked at random. + * - Nacl / Libsodium popularized term "secretbox", - which is just xsalsa20poly1305. + * We provide the alias and corresponding seal / open methods. + * "crypto_box" and "sealedbox" are available in package + * {@link https://github.com/serenity-kit/noble-sodium | noble-sodium}. + * - Check out + * {@link https://cr.yp.to/snuffle/salsafamily-20071225.pdf | PDF} + * and {@link https://cr.yp.to/snuffle.html | website}. + * @module + */ +import { createCipher, rotl } from './_arx.ts'; +import { poly1305 } from './_poly1305.ts'; +import { + abytes, + clean, + equalBytes, + getOutput, + swap32IfBE, + swap8IfBE, + wrapCipher, + type ARXCipher, + type CipherWithOutput, + type TArg, + type TRet, + type XorStream, +} from './utils.ts'; + +/** + * Salsa20 core function. It is implemented twice: + * 1. Simple loop (salsaCore_small, hsalsa_small) + * 2. Unrolled loop (salsaCore, hsalsa) - 4x faster, but larger & harder to read + * The specific implementation is selected in `createCipher` below. + * Performance numbers for 1MB inputs: + * * default x 779 ops/sec @ 1ms/op + * * if salsa+hsalsa are merged x 459 ops/sec @ 2ms/op + * * small x 132 ops/sec @ 7ms/op + */ + +/** RFC 7914 §3 Salsa20/8 core quarter-round on words a, b, c, d. */ +function salsaQR(x: TArg, a: number, b: number, c: number, d: number) { + x[b] ^= rotl((x[a] + x[d]) | 0, 7); + x[c] ^= rotl((x[b] + x[a]) | 0, 9); + x[d] ^= rotl((x[c] + x[b]) | 0, 13); + x[a] ^= rotl((x[d] + x[c]) | 0, 18); +} + +/** RFC 7914 §3 double-round schedule: four column rounds, then four row rounds. */ +function salsaRound(x: TArg, rounds = 20) { + for (let r = 0; r < rounds; r += 2) { + salsaQR(x, 0, 4, 8, 12); + salsaQR(x, 5, 9, 13, 1); + salsaQR(x, 10, 14, 2, 6); + salsaQR(x, 15, 3, 7, 11); + salsaQR(x, 0, 1, 2, 3); + salsaQR(x, 5, 6, 7, 4); + salsaQR(x, 10, 11, 8, 9); + salsaQR(x, 15, 12, 13, 14); + } +} + +// Shared scratch for the unused auditability helper below; it would be +// non-reentrant under overlapping/nested calls, but current code doesn't invoke it. +const stmp = /* @__PURE__ */ new Uint32Array(16); + +/** Small version of salsa without loop unrolling. Unused, provided for auditability. */ +// prettier-ignore +function salsa( + s: TArg, k: TArg, i: TArg, out: TArg, + isHSalsa: boolean = true, rounds: number = 20 +): void { + // Create initial array using common pattern + const y = Uint32Array.from([ + s[0], k[0], k[1], k[2], // "expa" Key Key Key + k[3], s[1], i[0], i[1], // Key "nd 3" Nonce Nonce + i[2], i[3], s[2], k[4], // Pos. Pos. "2-by" Key + k[5], k[6], k[7], s[3], // Key Key Key "te k" + ]); + const x = stmp; + x.set(y); + // const x = y.slice(); + salsaRound(x, rounds); + + // hsalsa extracts 8 specific words for the 32-byte subkey; salsa adds the original state. + if (isHSalsa) { + const xindexes = [0, 5, 10, 15, 6, 7, 8, 9]; + for (let i = 0; i < 8; i++) out[i] = x[xindexes[i]]; + } else { + for (let i = 0; i < 16; i++) out[i] = (y[i] + x[i]) | 0; + } +} +/** Identical to `salsaCore`. Unused. */ +// @ts-ignore +const salsaCore_small: typeof salsaCore = (s, k, n, out, cnt, rounds) => + salsa(s, k, Uint32Array.from([n[0], n[1], cnt, 0]), out, false, rounds); +/** Identical to `hsalsa`. Unused. */ +// @ts-ignore +const hsalsa_small: typeof hsalsa = salsa; + +/** Identical to `salsaCore_small`. Uses only the low 32 bits of Salsa20's 64-bit counter state. */ +// prettier-ignore +function salsaCore( + s: TArg, k: TArg, n: TArg, out: TArg, cnt: number, rounds = 20 +): void { + // Public wrappers expose only the low 32 bits of Salsa20's 64-bit counter; y09 stays zero. + // Based on {@link https://cr.yp.to/salsa20.html | the Salsa20 reference page}. + let y00 = s[0], y01 = k[0], y02 = k[1], y03 = k[2], // "expa" Key Key Key + y04 = k[3], y05 = s[1], y06 = n[0], y07 = n[1], // Key "nd 3" Nonce Nonce + y08 = cnt, y09 = 0, y10 = s[2], y11 = k[4], // Pos. Pos. "2-by" Key + y12 = k[5], y13 = k[6], y14 = k[7], y15 = s[3]; // Key Key Key "te k" + // Save state to temporary variables + let x00 = y00, x01 = y01, x02 = y02, x03 = y03, + x04 = y04, x05 = y05, x06 = y06, x07 = y07, + x08 = y08, x09 = y09, x10 = y10, x11 = y11, + x12 = y12, x13 = y13, x14 = y14, x15 = y15; + for (let r = 0; r < rounds; r += 2) { + x04 ^= rotl(x00 + x12 | 0, 7); x08 ^= rotl(x04 + x00 | 0, 9); + x12 ^= rotl(x08 + x04 | 0, 13); x00 ^= rotl(x12 + x08 | 0, 18); + x09 ^= rotl(x05 + x01 | 0, 7); x13 ^= rotl(x09 + x05 | 0, 9); + x01 ^= rotl(x13 + x09 | 0, 13); x05 ^= rotl(x01 + x13 | 0, 18); + x14 ^= rotl(x10 + x06 | 0, 7); x02 ^= rotl(x14 + x10 | 0, 9); + x06 ^= rotl(x02 + x14 | 0, 13); x10 ^= rotl(x06 + x02 | 0, 18); + x03 ^= rotl(x15 + x11 | 0, 7); x07 ^= rotl(x03 + x15 | 0, 9); + x11 ^= rotl(x07 + x03 | 0, 13); x15 ^= rotl(x11 + x07 | 0, 18); + x01 ^= rotl(x00 + x03 | 0, 7); x02 ^= rotl(x01 + x00 | 0, 9); + x03 ^= rotl(x02 + x01 | 0, 13); x00 ^= rotl(x03 + x02 | 0, 18); + x06 ^= rotl(x05 + x04 | 0, 7); x07 ^= rotl(x06 + x05 | 0, 9); + x04 ^= rotl(x07 + x06 | 0, 13); x05 ^= rotl(x04 + x07 | 0, 18); + x11 ^= rotl(x10 + x09 | 0, 7); x08 ^= rotl(x11 + x10 | 0, 9); + x09 ^= rotl(x08 + x11 | 0, 13); x10 ^= rotl(x09 + x08 | 0, 18); + x12 ^= rotl(x15 + x14 | 0, 7); x13 ^= rotl(x12 + x15 | 0, 9); + x14 ^= rotl(x13 + x12 | 0, 13); x15 ^= rotl(x14 + x13 | 0, 18); + } + // Write output + let oi = 0; + out[oi++] = (y00 + x00) | 0; out[oi++] = (y01 + x01) | 0; + out[oi++] = (y02 + x02) | 0; out[oi++] = (y03 + x03) | 0; + out[oi++] = (y04 + x04) | 0; out[oi++] = (y05 + x05) | 0; + out[oi++] = (y06 + x06) | 0; out[oi++] = (y07 + x07) | 0; + out[oi++] = (y08 + x08) | 0; out[oi++] = (y09 + x09) | 0; + out[oi++] = (y10 + x10) | 0; out[oi++] = (y11 + x11) | 0; + out[oi++] = (y12 + x12) | 0; out[oi++] = (y13 + x13) | 0; + out[oi++] = (y14 + x14) | 0; out[oi++] = (y15 + x15) | 0; +} + +/** + * hsalsa hashes key and nonce-prefix words into the 32-byte subkey used by XSalsa20. + * Identical to `hsalsa_small`. + * Need to find a way to merge it with `salsaCore` without 25% performance hit. + * @param s - Sigma constants as 32-bit words. + * @param k - Key words. + * @param i - Nonce-prefix words. + * @param out - Output buffer for the derived subkey. + * @example + * Derives the XSalsa20 subkey from sigma, key, and nonce-prefix words. + * + * ```ts + * const sigma = new Uint32Array(4); + * const key = new Uint32Array(8); + * const nonce = new Uint32Array(4); + * const out = new Uint32Array(8); + * hsalsa(sigma, key, nonce, out); + * ``` + */ +// prettier-ignore +export function hsalsa( + s: TArg, k: TArg, i: TArg, out: TArg +): void { + let x00 = swap8IfBE(s[0]), x01 = swap8IfBE(k[0]), x02 = swap8IfBE(k[1]), x03 = swap8IfBE(k[2]), + x04 = swap8IfBE(k[3]), x05 = swap8IfBE(s[1]), x06 = swap8IfBE(i[0]), x07 = swap8IfBE(i[1]), + x08 = swap8IfBE(i[2]), x09 = swap8IfBE(i[3]), x10 = swap8IfBE(s[2]), x11 = swap8IfBE(k[4]), + x12 = swap8IfBE(k[5]), x13 = swap8IfBE(k[6]), x14 = swap8IfBE(k[7]), x15 = swap8IfBE(s[3]); + for (let r = 0; r < 20; r += 2) { + x04 ^= rotl(x00 + x12 | 0, 7); x08 ^= rotl(x04 + x00 | 0, 9); + x12 ^= rotl(x08 + x04 | 0, 13); x00 ^= rotl(x12 + x08 | 0, 18); + x09 ^= rotl(x05 + x01 | 0, 7); x13 ^= rotl(x09 + x05 | 0, 9); + x01 ^= rotl(x13 + x09 | 0, 13); x05 ^= rotl(x01 + x13 | 0, 18); + x14 ^= rotl(x10 + x06 | 0, 7); x02 ^= rotl(x14 + x10 | 0, 9); + x06 ^= rotl(x02 + x14 | 0, 13); x10 ^= rotl(x06 + x02 | 0, 18); + x03 ^= rotl(x15 + x11 | 0, 7); x07 ^= rotl(x03 + x15 | 0, 9); + x11 ^= rotl(x07 + x03 | 0, 13); x15 ^= rotl(x11 + x07 | 0, 18); + x01 ^= rotl(x00 + x03 | 0, 7); x02 ^= rotl(x01 + x00 | 0, 9); + x03 ^= rotl(x02 + x01 | 0, 13); x00 ^= rotl(x03 + x02 | 0, 18); + x06 ^= rotl(x05 + x04 | 0, 7); x07 ^= rotl(x06 + x05 | 0, 9); + x04 ^= rotl(x07 + x06 | 0, 13); x05 ^= rotl(x04 + x07 | 0, 18); + x11 ^= rotl(x10 + x09 | 0, 7); x08 ^= rotl(x11 + x10 | 0, 9); + x09 ^= rotl(x08 + x11 | 0, 13); x10 ^= rotl(x09 + x08 | 0, 18); + x12 ^= rotl(x15 + x14 | 0, 7); x13 ^= rotl(x12 + x15 | 0, 9); + x14 ^= rotl(x13 + x12 | 0, 13); x15 ^= rotl(x14 + x13 | 0, 18); + } + let oi = 0; + // XSalsa20 takes words 0,5,10,15 and 6,7,8,9 as the 32-byte subkey material. + out[oi++] = x00; out[oi++] = x05; + out[oi++] = x10; out[oi++] = x15; + out[oi++] = x06; out[oi++] = x07; + out[oi++] = x08; out[oi++] = x09; + swap32IfBE(out); +} + +/** + * Salsa20 from original paper. 8-byte nonce. + * With smaller nonce, it's not safe to make it random (CSPRNG), due to collision chance. + * @param key - 16-byte or 32-byte key. + * @param nonce - 8-byte nonce. + * @param data - Input bytes to xor with the keystream. + * @param output - Optional destination buffer. + * @param counter - Initial block counter. + * Only the low 32 bits of Salsa20's 64-bit counter state are exposed here; + * the high word stays zero and the implementation still caps the public + * value to 32 bits. + * @returns Encrypted or decrypted bytes. + * @example + * Encrypts bytes with the original 8-byte-nonce Salsa20 stream cipher. + * + * ```ts + * import { salsa20 } from '@noble/ciphers/salsa.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(32); + * const nonce = randomBytes(8); + * salsa20(key, nonce, new Uint8Array([1, 2, 3, 4])); + * ``` + */ +export const salsa20: TRet = /* @__PURE__ */ createCipher(salsaCore, { + allowShortKeys: true, + counterRight: true, +}); + +/** + * XSalsa20 extended-nonce salsa. + * With 24-byte nonce, it's safe to make it random (CSPRNG). + * @param key - 32-byte key. + * This XSalsa20 wrapper does not enable Salsa20's 16-byte legacy key mode. + * @param nonce - 24-byte nonce. + * @param data - Input bytes to xor with the keystream. + * @param output - Optional destination buffer. + * @param counter - Initial block counter. + * @returns Encrypted or decrypted bytes. + * @example + * Encrypts bytes with XSalsa20 and a random 24-byte nonce. + * + * ```ts + * import { xsalsa20 } from '@noble/ciphers/salsa.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(32); + * const nonce = randomBytes(24); + * xsalsa20(key, nonce, new Uint8Array([1, 2, 3, 4])); + * ``` + */ +export const xsalsa20: TRet = /* @__PURE__ */ createCipher(salsaCore, { + counterRight: true, + extendNonceFn: hsalsa, +}); + +/** + * xsalsa20-poly1305 eXtended-nonce (24 bytes) salsa. + * With 24-byte nonce, it's safe to make it random (CSPRNG). + * Also known as `secretbox` from libsodium / nacl. + * No AAD input is supported here. Caller-provided `output` buffers for + * `encrypt()` / `decrypt()` must be `input.length + 32` bytes because the + * implementation uses a 32-byte leading scratch area before returning `+16`. + * @param key - 32-byte key. + * @param nonce - 24-byte nonce. + * @param AAD - Must be omitted; XSalsa20-Poly1305 secretbox does not support associated data. + * @returns AEAD cipher instance. + * @example + * Encrypts and authenticates plaintext with XSalsa20-Poly1305. + * + * ```ts + * import { xsalsa20poly1305 } from '@noble/ciphers/salsa.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(32); + * const nonce = randomBytes(24); + * const cipher = xsalsa20poly1305(key, nonce); + * cipher.encrypt(new Uint8Array([1, 2, 3])); + * ``` + */ +export const xsalsa20poly1305: TRet = /* @__PURE__ */ wrapCipher( + { blockSize: 64, nonceLength: 24, tagLength: 16 }, + (key: TArg, nonce: TArg): TRet => { + // This borrows caller key/nonce buffers by reference; mutating them after construction changes + // later encrypt/decrypt outputs. + return { + encrypt(plaintext: TArg, output?: TArg): TRet { + // xsalsa20poly1305 optimizes by calculating auth key during the same call as encryption. + // Unfortunately, makes it hard to separate tag calculation & encryption itself, + // because 32 bytes is half-block of 64-byte salsa. + // Need 32 extra bytes up front for the auth-key scratch area described above. + output = getOutput(plaintext.length + 32, output, false); + // output[0..32] = Poly1305 auth key, output[32..] = plaintext then ciphertext. + const authKey = output.subarray(0, 32); + const ciphPlaintext = output.subarray(32); + output.set(plaintext, 32); + // authKey is produced by xoring the first 32 bytes with zeros. + clean(authKey); + // output = stream ^ output; authKey = stream ^ zeros(32) + xsalsa20(key, nonce, output, output); + const tag = poly1305(ciphPlaintext, authKey); + output.set(tag, 16); + // Clean up auth-key remnants and the temporary tag copy. + clean(output.subarray(0, 16), tag); + // Return output[16..]. + return output.subarray(16) as TRet; + }, + decrypt(ciphertext: TArg, output?: TArg): TRet { + // tmp part passed tag ciphertext + // [0..32] [32..48] [48..] + // Authenticate the ciphertext before decrypting it; on tag failure the scratch/output + // buffer may already contain copied ciphertext and derived auth-key material. + abytes(ciphertext); + output = getOutput(ciphertext.length + 32, output, false); + // output[0..32] is auth-key scratch, output[32..48] is passed tag, + // output[48..] is ciphertext then plaintext. + const tmp = output.subarray(0, 32); + const passedTag = output.subarray(32, 48); + const ciphPlaintext = output.subarray(48); + output.set(ciphertext, 32); + // authKey is produced by xoring the scratch area with zeros. + clean(tmp); + const authKey = xsalsa20(key, nonce, tmp, tmp); + const tag = poly1305(ciphPlaintext, authKey); + if (!equalBytes(passedTag, tag)) { + clean(output); + throw new Error('invalid tag'); + } + // output = stream ^ output[16..] + xsalsa20(key, nonce, output.subarray(16), output.subarray(16)); + clean(tmp, passedTag, tag); + // Return output[48..], skipping zeroized output[0..48]. + return ciphPlaintext as TRet; + }, + } as TRet; + } +); + +/** + * Alias to `xsalsa20poly1305`, for compatibility with libsodium / nacl. + * Check out {@link https://github.com/serenity-kit/noble-sodium | noble-sodium} + * for `crypto_box`. + * @param key - 32-byte key. + * @param nonce - 24-byte nonce. + * @returns Wrapper with `seal()` and `open()` helpers. + * @example + * Uses the libsodium-style `seal()` and `open()` wrapper. + * + * ```ts + * import { secretbox } from '@noble/ciphers/salsa.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(32); + * const nonce = randomBytes(24); + * const box = secretbox(key, nonce); + * box.seal(new Uint8Array([1, 2, 3])); + * ``` + */ +export function secretbox( + key: TArg, + nonce: TArg +): TRet<{ + seal: (plaintext: TArg, output?: TArg) => TRet; + open: (ciphertext: TArg, output?: TArg) => TRet; +}> { + const xs = xsalsa20poly1305(key, nonce); + return { seal: xs.encrypt, open: xs.decrypt } as TRet<{ + seal: (plaintext: TArg, output?: TArg) => TRet; + open: (ciphertext: TArg, output?: TArg) => TRet; + }>; +} diff --git a/node_modules/@noble/ciphers/src/utils.ts b/node_modules/@noble/ciphers/src/utils.ts new file mode 100644 index 0000000..08b6d0d --- /dev/null +++ b/node_modules/@noble/ciphers/src/utils.ts @@ -0,0 +1,1191 @@ +/** + * Utilities for hex, bytes, CSPRNG. + * @module + */ +/*! noble-ciphers - MIT License (c) 2023 Paul Miller (paulmillr.com) */ + +/** + * Bytes API type helpers for old + new TypeScript. + * + * TS 5.6 has `Uint8Array`, while TS 5.9+ made it generic `Uint8Array`. + * We can't use specific return type, because TS 5.6 will error. + * We can't use generic return type, because most TS 5.9 software will expect specific type. + * + * Maps typed-array input leaves to broad forms. + * These are compatibility adapters, not ownership guarantees. + * + * - `TArg` keeps byte inputs broad. + * - `TRet` marks byte outputs for TS 5.6 and TS 5.9+ compatibility. + */ +export type TypedArg = T extends BigInt64Array + ? BigInt64Array + : T extends BigUint64Array + ? BigUint64Array + : T extends Float32Array + ? Float32Array + : T extends Float64Array + ? Float64Array + : T extends Int16Array + ? Int16Array + : T extends Int32Array + ? Int32Array + : T extends Int8Array + ? Int8Array + : T extends Uint16Array + ? Uint16Array + : T extends Uint32Array + ? Uint32Array + : T extends Uint8ClampedArray + ? Uint8ClampedArray + : T extends Uint8Array + ? Uint8Array + : never; +/** Maps typed-array output leaves to narrow TS-compatible forms. */ +export type TypedRet = T extends BigInt64Array + ? ReturnType + : T extends BigUint64Array + ? ReturnType + : T extends Float32Array + ? ReturnType + : T extends Float64Array + ? ReturnType + : T extends Int16Array + ? ReturnType + : T extends Int32Array + ? ReturnType + : T extends Int8Array + ? ReturnType + : T extends Uint16Array + ? ReturnType + : T extends Uint32Array + ? ReturnType + : T extends Uint8ClampedArray + ? ReturnType + : T extends Uint8Array + ? ReturnType + : never; +/** Recursively adapts byte-carrying API input types. See {@link TypedArg}. */ +export type TArg = + | T + | ([TypedArg] extends [never] + ? T extends (...args: infer A) => infer R + ? ((...args: { [K in keyof A]: TRet }) => TArg) & { + [K in keyof T]: T[K] extends (...args: any) => any ? T[K] : TArg; + } + : T extends [infer A, ...infer R] + ? [TArg, ...{ [K in keyof R]: TArg }] + : T extends readonly [infer A, ...infer R] + ? readonly [TArg, ...{ [K in keyof R]: TArg }] + : T extends (infer A)[] + ? TArg[] + : T extends readonly (infer A)[] + ? readonly TArg[] + : T extends Promise + ? Promise> + : T extends object + ? { [K in keyof T]: TArg } + : T + : TypedArg); +/** Recursively adapts byte-carrying API output types. See {@link TypedArg}. */ +export type TRet = T extends unknown + ? T & + ([TypedRet] extends [never] + ? T extends (...args: infer A) => infer R + ? ((...args: { [K in keyof A]: TArg }) => TRet) & { + [K in keyof T]: T[K] extends (...args: any) => any ? T[K] : TRet; + } + : T extends [infer A, ...infer R] + ? [TRet, ...{ [K in keyof R]: TRet }] + : T extends readonly [infer A, ...infer R] + ? readonly [TRet, ...{ [K in keyof R]: TRet }] + : T extends (infer A)[] + ? TRet[] + : T extends readonly (infer A)[] + ? readonly TRet[] + : T extends Promise + ? Promise> + : T extends object + ? { [K in keyof T]: TRet } + : T + : TypedRet) + : never; + +/** + * Checks if something is Uint8Array. Be careful: nodejs Buffer will return true. + * @param a - Value to inspect. + * @returns `true` when the value is a Uint8Array view, including Node's `Buffer`. + * @example + * Guards a value before treating it as raw key material. + * + * ```ts + * isBytes(new Uint8Array()); + * ``` + */ +export function isBytes(a: unknown): a is Uint8Array { + // Plain `instanceof Uint8Array` is too strict for some Buffer / proxy / + // cross-realm cases. The fallback still requires a real ArrayBuffer view + // so plain JSON-deserialized `{ constructor: ... }` + // spoofing is rejected, and `BYTES_PER_ELEMENT === 1` keeps the fallback on byte-oriented views. + return ( + a instanceof Uint8Array || + (ArrayBuffer.isView(a) && + a.constructor.name === 'Uint8Array' && + 'BYTES_PER_ELEMENT' in a && + a.BYTES_PER_ELEMENT === 1) + ); +} + +/** + * Asserts something is boolean. + * @param b - Value to validate. + * @throws On wrong argument types. {@link TypeError} + * @example + * Validates a boolean option before branching on it. + * + * ```ts + * abool(true); + * ``` + */ +export function abool(b: boolean): void { + if (typeof b !== 'boolean') throw new TypeError(`boolean expected, not ${b}`); +} + +/** + * Asserts something is a non-negative safe integer. + * @param n - Value to validate. + * @throws On wrong argument types. {@link TypeError} + * @throws On wrong argument ranges or values. {@link RangeError} + * @example + * Validates a non-negative length or counter. + * + * ```ts + * anumber(1); + * ``` + */ +export function anumber(n: number): void { + if (typeof n !== 'number') throw new TypeError('number expected, got ' + typeof n); + if (!Number.isSafeInteger(n) || n < 0) + throw new RangeError('positive integer expected, got ' + n); +} + +/** + * Asserts something is Uint8Array. + * @param value - Value to validate. + * @param length - Expected byte length. + * @param title - Optional label used in error messages. + * @returns The validated byte array. + * On Node, `Buffer` is accepted too because it is a Uint8Array view. + * @throws On wrong argument types. {@link TypeError} + * @throws On wrong argument lengths. {@link RangeError} + * @example + * Validates a fixed-length nonce or key buffer. + * + * ```ts + * abytes(new Uint8Array([1, 2]), 2); + * ``` + */ +export function abytes( + value: TArg, + length?: number, + title: string = '' +): TRet { + const bytes = isBytes(value); + const len = value?.length; + const needsLen = length !== undefined; + if (!bytes || (needsLen && len !== length)) { + const prefix = title && `"${title}" `; + const ofLen = needsLen ? ` of length ${length}` : ''; + const got = bytes ? `length=${len}` : `type=${typeof value}`; + const message = prefix + 'expected Uint8Array' + ofLen + ', got ' + got; + if (!bytes) throw new TypeError(message); + throw new RangeError(message); + } + return value as TRet; +} + +/** + * Asserts a hash- or MAC-like instance has not been destroyed or finished. + * @param instance - Stateful instance to validate. + * @param checkFinished - Whether to reject finished instances. + * When `false`, only `destroyed` is checked. + * @throws If the hash instance has already been destroyed or finalized. {@link Error} + * @example + * Guards against calling `update()` or `digest()` on a finished hash. + * + * ```ts + * aexists({ destroyed: false, finished: false }); + * ``` + */ +export function aexists(instance: any, checkFinished = true): void { + if (instance.destroyed) throw new Error('Hash instance has been destroyed'); + if (checkFinished && instance.finished) throw new Error('Hash#digest() has already been called'); +} + +/** + * Asserts output is a properly-sized byte array. + * @param out - Output buffer to validate. + * @param instance - Hash-like instance providing `outputLen`. + * This is the relaxed `digestInto()`-style contract: output must be at least `outputLen`, + * unlike one-shot cipher helpers elsewhere in the repo that often require exact lengths. + * @throws On wrong argument types. {@link TypeError} + * @param onlyAligned - Whether `out` must be 4-byte aligned for zero-allocation word views. + * @throws On wrong output buffer lengths. {@link RangeError} + * @throws On wrong output buffer alignment. {@link Error} + * @example + * Verifies that a caller-provided output buffer is large enough. + * + * ```ts + * aoutput(new Uint8Array(16), { outputLen: 16 }); + * ``` + */ +export function aoutput(out: any, instance: any, onlyAligned = false): void { + abytes(out, undefined, 'output'); + const min = instance.outputLen; + if (out.length < min) { + throw new RangeError('digestInto() expects output buffer of length at least ' + min); + } + if (onlyAligned && !isAligned32(out)) throw new Error('invalid output, must be aligned'); +} + +/** One-shot hash helper with `.create()`. */ +export type IHash = { + (data: string | TArg): TRet; + /** Input block size in bytes. */ + blockLen: number; + /** Digest size in bytes. */ + outputLen: number; + /** Creates a fresh incremental hash instance of the same algorithm. */ + create: any; +}; + +/** One-shot MAC helper with `.create()`. */ +export type CMac = { + (msg: TArg, key: TArg): TRet; + /** Input block size in bytes. */ + blockLen: number; + /** Digest size in bytes. */ + outputLen: number; + /** + * Creates a fresh incremental MAC instance of the same algorithm. + * @param key - MAC key bytes. + * @param args - Additional constructor arguments, when the MAC wrapper needs them. + * @returns Fresh incremental MAC instance. + */ + create(key: TArg, ...args: A): H; +}; + +/** Generic type encompassing 8/16/32-bit typed arrays, but not 64-bit. */ +// prettier-ignore +export type TypedArray = Int8Array | Uint8ClampedArray | Uint8Array | + Uint16Array | Int16Array | Uint32Array | Int32Array; + +/** + * Casts a typed-array view to Uint8Array. + * @param arr - Typed-array view to reinterpret. + * @returns Uint8Array view over the same bytes. + * @example + * Views 32-bit words as raw bytes without copying. + * + * ```ts + * u8(new Uint32Array([1])); + * ``` + */ +export function u8(arr: TArg): TRet { + return new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength) as TRet; +} + +/** + * Casts a typed-array view to Uint32Array. + * @param arr - Typed-array view to reinterpret. + * @returns Uint32Array view over the same bytes. Callers are expected to provide a + * 4-byte-aligned offset; trailing `1..3` bytes are silently dropped. + * @example + * Views a byte buffer as 32-bit words for block processing. + * + * ```ts + * u32(new Uint8Array(4)); + * ``` + */ +export function u32(arr: TArg): TRet { + return new Uint32Array( + arr.buffer, + arr.byteOffset, + Math.floor(arr.byteLength / 4) + ) as TRet; +} + +/** + * Zeroizes typed arrays in place. + * Warning: JS provides no guarantees. + * @param arrays - Arrays to wipe. + * @example + * Wipes a temporary key buffer after use. + * + * ```ts + * const bytes = new Uint8Array([1]); + * clean(bytes); + * ``` + */ +export function clean(...arrays: TArg): void { + for (let i = 0; i < arrays.length; i++) { + arrays[i].fill(0); + } +} + +/** + * Creates a DataView for byte-level manipulation. + * @param arr - Typed-array view to wrap. + * @returns DataView over the same bytes. + * @example + * Creates an endian-aware view for length encoding. + * + * ```ts + * createView(new Uint8Array(4)); + * ``` + */ +export function createView(arr: TArg): DataView { + return new DataView(arr.buffer, arr.byteOffset, arr.byteLength); +} + +/** + * Whether the current platform is little-endian. + * Most are; some IBM systems are not. + */ +export const isLE: boolean = /* @__PURE__ */ (() => + new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44)(); + +/** + * Reverses byte order of one 32-bit word. + * @param word - Unsigned 32-bit word to swap. + * @returns The same word with bytes reversed. + * @example + * Swaps a big-endian word into little-endian byte order. + * + * ```ts + * byteSwap(0x11223344); + * ``` + */ +export const byteSwap = (word: number): number => + ((word << 24) & 0xff000000) | + ((word << 8) & 0xff0000) | + ((word >>> 8) & 0xff00) | + ((word >>> 24) & 0xff); + +/** + * Normalizes one 32-bit word to the little-endian representation expected by cipher cores. + * @param n - Unsigned 32-bit word to normalize. + * @returns Little-endian normalized word on big-endian hosts, else the input word unchanged. + * @example + * Normalizes a host-endian word before passing it into an ARX/AES core. + * + * ```ts + * swap8IfBE(0x11223344); + * ``` + */ +export const swap8IfBE: (n: number) => number = isLE + ? (n: number) => n + : (n: number) => byteSwap(n) >>> 0; + +/** + * Byte-swaps every word of a Uint32Array in place. + * @param arr - Uint32Array whose words should be swapped. + * @returns The same array after in-place byte swapping. + * @example + * Swaps every 32-bit word in a word-view buffer. + * + * ```ts + * byteSwap32(new Uint32Array([0x11223344])); + * ``` + */ +export const byteSwap32 = (arr: TArg): TRet => { + for (let i = 0; i < arr.length; i++) arr[i] = byteSwap(arr[i]); + return arr as TRet; +}; + +/** + * Normalizes a Uint32Array view to the little-endian representation expected by cipher cores. + * @param u - Word view to normalize in place. + * @returns Little-endian normalized word view. + * @example + * Normalizes a word-view buffer before block processing. + * + * ```ts + * swap32IfBE(new Uint32Array([0x11223344])); + * ``` + */ +export const swap32IfBE: (u: TArg) => TRet = isLE + ? (u: TArg) => u as TRet + : byteSwap32; + +// Built-in hex conversion: +// {@link https://caniuse.com/mdn-javascript_builtins_uint8array_fromhex | caniuse entry} +const hasHexBuiltin: boolean = /* @__PURE__ */ (() => + // @ts-ignore + typeof Uint8Array.from([]).toHex === 'function' && typeof Uint8Array.fromHex === 'function')(); + +// Array where index 0xf0 (240) is mapped to string 'f0' +const hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => + i.toString(16).padStart(2, '0') +); + +/** + * Convert byte array to hex string. Uses built-in function, when available. + * @param bytes - Bytes to encode. + * @returns Lowercase hexadecimal string. + * @throws On wrong argument types. {@link TypeError} + * @example + * Formats ciphertext bytes for logs or test vectors. + * + * ```ts + * bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])); // 'cafe0123' + * ``` + */ +export function bytesToHex(bytes: TArg): string { + abytes(bytes); + // @ts-ignore + if (hasHexBuiltin) return bytes.toHex(); + // pre-caching improves the speed 6x + let hex = ''; + for (let i = 0; i < bytes.length; i++) { + hex += hexes[bytes[i]]; + } + return hex; +} + +// We use optimized technique to convert hex string to byte array +const asciis = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 } as const; +function asciiToBase16(ch: number): number | undefined { + if (ch >= asciis._0 && ch <= asciis._9) return ch - asciis._0; // '2' => 50-48 + if (ch >= asciis.A && ch <= asciis.F) return ch - (asciis.A - 10); // 'B' => 66-(65-10) + if (ch >= asciis.a && ch <= asciis.f) return ch - (asciis.a - 10); // 'b' => 98-(97-10) + return; +} + +/** + * Convert hex string to byte array. Uses built-in function, when available. + * @param hex - Hexadecimal string to decode. + * @returns Decoded bytes. + * @throws On wrong argument types. {@link TypeError} + * @throws On malformed hexadecimal input. {@link RangeError} + * @example + * Parses a hex test vector into bytes. + * + * ```ts + * hexToBytes('cafe0123'); // Uint8Array.from([0xca, 0xfe, 0x01, 0x23]) + * ``` + */ +export function hexToBytes(hex: string): TRet { + if (typeof hex !== 'string') throw new TypeError('hex string expected, got ' + typeof hex); + if (hasHexBuiltin) { + try { + return (Uint8Array as any).fromHex(hex); + } catch (error) { + if (error instanceof SyntaxError) throw new RangeError(error.message); + throw error; + } + } + const hl = hex.length; + const al = hl / 2; + if (hl % 2) throw new RangeError('hex string expected, got unpadded hex of length ' + hl); + const array = new Uint8Array(al); + for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) { + const n1 = asciiToBase16(hex.charCodeAt(hi)); + const n2 = asciiToBase16(hex.charCodeAt(hi + 1)); + if (n1 === undefined || n2 === undefined) { + const char = hex[hi] + hex[hi + 1]; + throw new RangeError( + 'hex string expected, got non-hex character "' + char + '" at index ' + hi + ); + } + array[ai] = n1 * 16 + n2; // multiply first octet, e.g. 'a3' => 10*16+3 => 160 + 3 => 163 + } + return array as TRet; +} + +// Used in micro +/** + * Converts a big-endian hex string into bigint. + * @param hex - Hexadecimal string without `0x`. + * @returns Parsed bigint value. The empty string is treated as `0n`. + * @throws On wrong argument types. {@link TypeError} + * @example + * Parses a big-endian field element or counter from hex. + * + * ```ts + * hexToNumber('ff'); + * ``` + */ +export function hexToNumber(hex: string): bigint { + if (typeof hex !== 'string') throw new TypeError('hex string expected, got ' + typeof hex); + return BigInt(hex === '' ? '0' : '0x' + hex); // Big Endian +} + +// Used in ff1 +// BE: Big Endian, LE: Little Endian +/** + * Converts big-endian bytes into bigint. + * @param bytes - Big-endian bytes. + * @returns Parsed bigint value. Empty input is treated as `0n`. + * @throws On invalid byte input passed to the internal hex conversion. {@link TypeError} + * @example + * Reads a big-endian integer from serialized bytes. + * + * ```ts + * bytesToNumberBE(new Uint8Array([1, 0])); + * ``` + */ +export function bytesToNumberBE(bytes: TArg): bigint { + return hexToNumber(bytesToHex(bytes)); +} + +// Used in micro, ff1 +/** + * Converts a number into big-endian bytes of fixed length. + * @param n - Number to encode. + * @param len - Output length in bytes. + * @returns Big-endian bytes padded to `len`. + * Validation is indirect through `hexToBytes(...)`, so negative values, `len = 0`, + * and values that do not fit surface through the downstream hex parser instead of a + * dedicated range guard here. + * @throws On wrong argument types. {@link TypeError} + * @throws If the requested output length cannot represent the encoded value. {@link RangeError} + * @example + * Encodes a counter as fixed-width big-endian bytes. + * + * ```ts + * numberToBytesBE(1, 2); + * ``` + */ +export function numberToBytesBE(n: number | bigint, len: number): TRet { + // Reject coercible non-numeric inputs before string/hex conversion changes behavior. + if (typeof n === 'number') anumber(n); + else if (typeof n !== 'bigint') throw new TypeError(`number or bigint expected, got ${typeof n}`); + anumber(len); + return hexToBytes(n.toString(16).padStart(len * 2, '0')); +} + +// Global symbols, but ts doesn't see them: +// {@link https://github.com/microsoft/TypeScript/issues/31535 | TypeScript issue 31535} +declare const TextEncoder: any; +declare const TextDecoder: any; + +/** + * Converts string to bytes using UTF8 encoding. + * @param str - String to encode. + * @returns UTF-8 bytes in a detached fresh Uint8Array copy. + * @throws On wrong argument types. {@link TypeError} + * @example + * Encodes application text before encryption or MACing. + * + * ```ts + * utf8ToBytes('abc'); // new Uint8Array([97, 98, 99]) + * ``` + */ +export function utf8ToBytes(str: string): TRet { + if (typeof str !== 'string') throw new TypeError('string expected'); + return new Uint8Array(new TextEncoder().encode(str)) as TRet; // {@link https://bugzil.la/1681809 | Firefox bug 1681809} +} + +/** + * Converts bytes to string using UTF8 encoding. + * @param bytes - UTF-8 bytes. + * @returns Decoded string. Input validation is delegated to `TextDecoder`, and malformed + * UTF-8 is replacement-decoded instead of rejected. + * @example + * Decodes UTF-8 plaintext back into a string. + * + * ```ts + * bytesToUtf8(new Uint8Array([97, 98, 99])); // 'abc' + * ``` + */ +export function bytesToUtf8(bytes: TArg): string { + return new TextDecoder().decode(bytes); +} + +/** + * Checks if two U8A use same underlying buffer and overlaps. + * This is invalid and can corrupt data. + * @param a - First byte view. + * @param b - Second byte view. + * @returns `true` when the views overlap in memory. + * @example + * Detects whether two slices alias the same backing buffer. + * + * ```ts + * overlapBytes(new Uint8Array(4), new Uint8Array(4)); + * ``` + */ +export function overlapBytes(a: TArg, b: TArg): boolean { + // Zero-length views cannot overwrite anything, even if their offset sits inside another range. + if (!a.byteLength || !b.byteLength) return false; + return ( + a.buffer === b.buffer && // best we can do, may fail with an obscure Proxy + a.byteOffset < b.byteOffset + b.byteLength && // a starts before b end + b.byteOffset < a.byteOffset + a.byteLength // b starts before a end + ); +} + +/** + * If input and output overlap and input starts before output, we will overwrite end of input before + * we start processing it, so this is not supported for most ciphers + * (except chacha/salsa, which were designed for this) + * @param input - Input bytes. + * @param output - Output bytes. + * @throws If the output view would overwrite unread input bytes. {@link Error} + * @example + * Rejects an in-place layout that would overwrite unread input bytes. + * + * ```ts + * complexOverlapBytes(new Uint8Array(4), new Uint8Array(4)); + * ``` + */ +export function complexOverlapBytes(input: TArg, output: TArg): void { + // This is very cursed. It works somehow, but I'm completely unsure, + // reasoning about overlapping aligned windows is very hard. + if (overlapBytes(input, output) && input.byteOffset < output.byteOffset) + throw new Error('complex overlap of input and output is not supported'); +} + +/** + * Copies several Uint8Arrays into one. + * @param arrays - Byte arrays to concatenate. + * @returns Combined byte array. + * @throws On wrong argument types inside the byte-array list. {@link TypeError} + * @example + * Builds a `nonce || ciphertext` style buffer. + * + * ```ts + * concatBytes(new Uint8Array([1]), new Uint8Array([2])); + * ``` + */ +export function concatBytes(...arrays: TArg): TRet { + let sum = 0; + for (let i = 0; i < arrays.length; i++) { + const a = arrays[i]; + abytes(a); + sum += a.length; + } + const res = new Uint8Array(sum); + for (let i = 0, pad = 0; i < arrays.length; i++) { + const a = arrays[i]; + res.set(a, pad); + pad += a.length; + } + return res as TRet; +} + +// Used in ARX only +type EmptyObj = {}; +/** + * Merges user options into defaults. + * @param defaults - Default option values. + * @param opts - User-provided overrides. + * @returns Combined options object. + * The merge mutates `defaults` in place and returns the same object. + * @throws If options are missing or not an object. {@link Error} + * @example + * Applies user overrides to the default cipher options. + * + * ```ts + * checkOpts({ rounds: 20 }, { rounds: 8 }); + * ``` + */ +export function checkOpts( + defaults: T1, + opts: T2 +): T1 & T2 { + if (opts == null || typeof opts !== 'object') throw new Error('options must be defined'); + const merged = Object.assign(defaults, opts); + return merged as T1 & T2; +} + +/** + * Compares two byte arrays in kinda constant time once lengths already match. + * @param a - First byte array. + * @param b - Second byte array. + * @returns `true` when the arrays contain the same bytes. Different lengths still return early. + * @example + * Compares an expected authentication tag with the received one. + * + * ```ts + * equalBytes(new Uint8Array([1]), new Uint8Array([1])); + * ``` + */ +export function equalBytes(a: TArg, b: TArg): boolean { + if (a.length !== b.length) return false; + let diff = 0; + for (let i = 0; i < a.length; i++) diff |= a[i] ^ b[i]; + return diff === 0; +} + +// TODO: remove +/** Incremental hash interface used internally. */ +export interface IHash2 { + /** Bytes processed per compression block. */ + blockLen: number; + /** Bytes produced by the final digest. */ + outputLen: number; + /** + * Absorbs one more chunk into the hash state. + * @param buf - Data chunk to hash. + * @returns The same hash instance for chaining. + */ + update(buf: string | TArg): this; + /** + * Writes the final digest into a caller-provided buffer. + * @param buf - Destination buffer for the digest bytes. + * @returns Nothing. Implementations write into `buf` in place. + */ + digestInto(buf: TArg): void; + /** + * Finalizes the hash and returns a fresh digest buffer. + * @returns Digest bytes. + */ + digest(): TRet; + /** + * Resets internal state. Makes Hash instance unusable. + * Reset is impossible for keyed hashes if key is consumed into state. If digest is not consumed + * by user, they will need to manually call `destroy()` when zeroing is necessary. + */ + destroy(): void; +} + +/** + * Wraps a keyed MAC constructor into a one-shot helper with `.create()`. + * @param keyLen - Valid probe-key length used to read static metadata once. + * The probe key is only used for `outputLen` / `blockLen`, so callers with several valid key sizes + * can pass any representative size as long as those values stay fixed. + * @param macCons - Keyed MAC constructor or factory. + * @param fromMsg - Optional adapter that derives extra constructor args from the one-shot message. + * @returns Callable MAC helper with `.create()`. + */ +export function wrapMacConstructor( + keyLen: number, + macCons: TArg<(key: Uint8Array, ...args: A) => H>, + fromMsg?: TArg<(msg: Uint8Array) => A> +): TRet> { + const mac = macCons as (key: TArg, ...args: A) => H; + const getArgs = (fromMsg || (() => [] as unknown as A)) as (msg: TArg) => A; + const macC: any = (msg: TArg, key: TArg): TRet => + mac(key, ...getArgs(msg)) + .update(msg) + .digest(); + const tmp = mac(new Uint8Array(keyLen), ...getArgs(new Uint8Array(0))); + macC.outputLen = tmp.outputLen; + macC.blockLen = tmp.blockLen; + macC.create = (key: TArg, ...args: A) => mac(key, ...args); + return macC as TRet>; +} + +// This will allow to re-use with composable things like packed & base encoders +// Also, we probably can make tags composable + +/** Sync cipher: takes byte array and returns byte array. */ +export type Cipher = { + /** + * Encrypts plaintext bytes. + * @param plaintext - Data to encrypt. + * @returns Ciphertext bytes. + */ + encrypt(plaintext: TArg): TRet; + /** + * Decrypts ciphertext bytes. + * @param ciphertext - Data to decrypt. + * @returns Plaintext bytes. + */ + decrypt(ciphertext: TArg): TRet; +}; + +/** Async cipher e.g. from built-in WebCrypto. */ +export type AsyncCipher = { + /** + * Encrypts plaintext bytes. + * @param plaintext - Data to encrypt. + * @returns Promise resolving to ciphertext bytes. + */ + encrypt(plaintext: TArg): Promise>; + /** + * Decrypts ciphertext bytes. + * @param ciphertext - Data to decrypt. + * @returns Promise resolving to plaintext bytes. + */ + decrypt(ciphertext: TArg): Promise>; +}; + +/** Cipher with `output` argument which can optimize by doing 1 less allocation. */ +export type CipherWithOutput = Cipher & { + /** + * Encrypts plaintext bytes into an optional caller-provided buffer. + * @param plaintext - Data to encrypt. + * @param output - Optional destination buffer. + * @returns Ciphertext bytes. + */ + encrypt(plaintext: TArg, output?: TArg): TRet; + /** + * Decrypts ciphertext bytes into an optional caller-provided buffer. + * @param ciphertext - Data to decrypt. + * @param output - Optional destination buffer. + * @returns Plaintext bytes. + */ + decrypt(ciphertext: TArg, output?: TArg): TRet; +}; + +/** + * Params are outside of return type, so it is accessible before calling constructor. + * If function support multiple nonceLength's, we return the best one. + */ +export type CipherParams = { + /** Cipher block size in bytes. */ + blockSize: number; + /** Nonce length in bytes when the cipher uses a fixed nonce size. */ + nonceLength?: number; + /** Authentication-tag length in bytes for AEAD modes. */ + tagLength?: number; + /** Whether nonce length is variable at runtime. */ + varSizeNonce?: boolean; +}; +/** + * ARX AEAD cipher, like salsa or chacha. + * @param key - Secret key bytes. + * @param nonce - Nonce bytes. + * @param AAD - Optional associated data. + * @returns Cipher instance with caller-managed output buffers. + */ +export type ARXCipher = (( + key: TArg, + nonce: TArg, + AAD?: TArg +) => CipherWithOutput) & { + blockSize: number; + nonceLength: number; + tagLength: number; +}; +/** + * Cipher constructor signature. + * @param key - Secret key bytes. + * @param args - Additional constructor arguments, such as nonce or IV. + * @returns Cipher instance. + */ +export type CipherCons = (key: TArg, ...args: T) => Cipher; +/** + * Wraps a cipher: validates args, ensures encrypt() can only be called once. + * Used internally by the exported cipher constructors. + * Output-buffer support is inferred from the wrapped `encrypt` / `decrypt` + * arity (`fn.length === 2`), and tag-bearing constructors are expected to use + * `args[1]` for optional AAD. + * @__NO_SIDE_EFFECTS__ + * @param params - Static cipher metadata. See {@link CipherParams}. + * @param constructor - Cipher constructor. + * @returns Wrapped constructor with validation. + */ +export const wrapCipher = , P extends CipherParams>( + params: P, + constructor: C +): C & P => { + function wrappedCipher(key: TArg, ...args: any[]): TRet { + // Validate key + abytes(key, undefined, 'key'); + + // Validate nonce if nonceLength is present + if (params.nonceLength !== undefined) { + const nonce = args[0]; + abytes(nonce, params.varSizeNonce ? undefined : params.nonceLength, 'nonce'); + } + + // Validate AAD if tagLength present + const tagl = params.tagLength; + if (tagl && args[1] !== undefined) abytes(args[1], undefined, 'AAD'); + + const cipher = constructor(key, ...args); + const checkOutput = (fnLength: number, output?: TArg) => { + if (output !== undefined) { + if (fnLength !== 2) throw new Error('cipher output not supported'); + abytes(output, undefined, 'output'); + } + }; + // Create wrapped cipher with validation and single-use encryption + let called = false; + const wrCipher = { + encrypt(data: TArg, output?: TArg) { + if (called) throw new Error('cannot encrypt() twice with same key + nonce'); + called = true; + abytes(data); + checkOutput(cipher.encrypt.length, output); + return (cipher as CipherWithOutput).encrypt(data, output); + }, + decrypt(data: TArg, output?: TArg) { + abytes(data); + if (tagl && data.length < tagl) + throw new Error('"ciphertext" expected length bigger than tagLength=' + tagl); + checkOutput(cipher.decrypt.length, output); + return (cipher as CipherWithOutput).decrypt(data, output); + }, + }; + + return wrCipher as TRet; + } + + Object.assign(wrappedCipher, params); + return wrappedCipher as C & P; +}; + +/** + * Represents a Salsa or ChaCha xor stream. + * @param key - Secret key bytes. + * @param nonce - Nonce bytes. + * @param data - Input bytes to xor with the keystream. + * @param output - Optional destination buffer. + * @param counter - Optional starting block counter. + * @returns Output bytes. + */ +export type XorStream = ( + key: TArg, + nonce: TArg, + data: TArg, + output?: TArg, + counter?: number +) => TRet; + +/** + * By default, returns u8a of length. + * When out is available, it checks it for validity and uses it. + * @param expectedLength - Required output length. + * @param out - Optional destination buffer. + * @param onlyAligned - Whether `out` must be 4-byte aligned. + * @returns Output buffer ready for writing. + * @throws On wrong argument types. {@link TypeError} + * @throws If the provided output buffer has the wrong size or alignment. {@link Error} + * @example + * Reuses a caller-provided output buffer when lengths match. + * + * ```ts + * getOutput(16, new Uint8Array(16)); + * ``` + */ +export function getOutput( + expectedLength: number, + out?: TArg, + onlyAligned = true +): TRet { + if (out === undefined) return new Uint8Array(expectedLength) as TRet; + // Keep Buffer/cross-realm Uint8Array support here instead of trusting a shape-compatible object. + abytes(out, undefined, 'output'); + if (out.length !== expectedLength) + throw new Error( + '"output" expected Uint8Array of length ' + expectedLength + ', got: ' + out.length + ); + if (onlyAligned && !isAligned32(out)) throw new Error('invalid output, must be aligned'); + return out as TRet; +} + +/** + * Encodes data and AAD bit lengths into a 16-byte buffer. + * @param dataLength - Data length in bits. + * @param aadLength - AAD length in bits. + * The serialized block is still `aadLength || dataLength`, matching GCM/Poly1305 + * conventions even though the helper parameter order is `(dataLength, aadLength)`. + * @param isLE - Whether to encode lengths as little-endian. + * @returns 16-byte length block. + * @throws On wrong argument types passed to the endian validator. {@link TypeError} + * @throws On wrong argument ranges or values. {@link RangeError} + * @example + * Builds the length block appended by GCM and Poly1305. + * + * ```ts + * u64Lengths(16, 8, true); + * ``` + */ +export function u64Lengths(dataLength: number, aadLength: number, isLE: boolean): TRet { + // Reject coercible non-number lengths like '10' and true before BigInt(...) accepts them. + anumber(dataLength); + anumber(aadLength); + abool(isLE); + const num = new Uint8Array(16); + const view = createView(num); + view.setBigUint64(0, BigInt(aadLength), isLE); + view.setBigUint64(8, BigInt(dataLength), isLE); + return num as TRet; +} + +/** + * Checks whether a byte array is aligned to a 4-byte offset. + * @param bytes - Byte array to inspect. + * @returns `true` when the view is 4-byte aligned. + * @example + * Checks whether a buffer can be safely viewed as Uint32Array. + * + * ```ts + * isAligned32(new Uint8Array(4)); + * ``` + */ +export function isAligned32(bytes: TArg): boolean { + return bytes.byteOffset % 4 === 0; +} + +/** + * Copies bytes into a new Uint8Array. + * @param bytes - Bytes to copy. + * @returns Copied byte array. + * @throws On wrong argument types. {@link TypeError} + * @example + * Copies input into an aligned Uint8Array before block processing. + * + * ```ts + * copyBytes(new Uint8Array([1, 2])); + * ``` + */ +export function copyBytes(bytes: TArg): TRet { + // `Uint8Array.from(...)` would also accept arrays / other typed arrays. Keep this helper strict + // because callers use it at byte-validation boundaries before mutating the detached copy. + return Uint8Array.from(abytes(bytes)) as TRet; +} + +/** + * Cryptographically secure PRNG. + * Uses internal OS-level `crypto.getRandomValues`. + * @param bytesLength - Number of bytes to produce. + * Validation is delegated to `Uint8Array(bytesLength)` and `getRandomValues`, so + * non-integers, negative lengths, and oversize requests surface backend/runtime errors. + * @returns Random byte array. + * @throws On wrong argument types. {@link TypeError} + * @throws On wrong argument ranges or values. {@link RangeError} + * @throws If the runtime does not expose `crypto.getRandomValues`. {@link Error} + * @example + * Generates a fresh nonce or key. + * + * ```ts + * randomBytes(16); + * ``` + */ +export function randomBytes(bytesLength = 32): TRet { + // Validate upfront so fractional / coercible lengths do not silently + // truncate through Uint8Array(). + anumber(bytesLength); + const cr = typeof globalThis === 'object' ? (globalThis as any).crypto : null; + if (typeof cr?.getRandomValues !== 'function') + throw new Error('crypto.getRandomValues must be defined'); + return cr.getRandomValues(new Uint8Array(bytesLength)) as TRet; +} + +/** + * The pseudorandom number generator doesn't wipe current state: + * instead, it generates new one based on previous state + entropy. + * Not reseed/rekey, since AES CTR DRBG does rekey on each randomBytes, + * which is in fact `reseed`, since it changes counter too. + */ +export interface PRG { + /** + * Mixes fresh entropy into the current generator state. + * @param seed - Entropy bytes to absorb. + */ + addEntropy(seed: TArg): void; + /** + * Produces a requested number of pseudorandom bytes. + * @param bytesLength - Number of bytes to generate. + * @returns Random byte array. + */ + randomBytes(bytesLength: number): TRet; + /** Destroys the generator state. */ + clean(): void; +} + +/** Removes the nonce argument from a cipher constructor type. */ +export type RemoveNonce any> = T extends ( + arg0: any, + arg1: any, + ...rest: infer R +) => infer Ret + ? (key: TArg, ...args: R) => Ret + : never; +/** + * Cipher constructor that requires a nonce argument. + * @param key - Secret key bytes. + * @param nonce - Nonce bytes. + * @param args - Additional cipher-specific arguments. + * @returns Cipher instance. + */ +export type CipherWithNonce = (( + key: TArg, + nonce: TArg, + ...args: any[] +) => Cipher | AsyncCipher) & { + nonceLength: number; +}; + +/** + * Uses CSPRNG for nonce, nonce injected in ciphertext. + * For `encrypt`, a `nonceBytes`-length buffer is fetched from CSPRNG and + * prepended to encrypted ciphertext. For `decrypt`, first `nonceBytes` of ciphertext + * are treated as nonce. The wrapper always allocates a fresh `nonce || ciphertext` + * buffer on encrypt and intentionally does not support caller-provided destination buffers. + * Too-short decrypt inputs are split into short/empty nonce views and then delegated + * to the wrapped cipher instead of being rejected here first. + * + * NOTE: Under the same key, using random nonces (e.g. `managedNonce`) with AES-GCM and ChaCha + * should be limited to `2**23` (8M) messages to get a collision chance of + * `2**-50`. Stretching to `2**32` (4B) messages would raise that chance to + * `2**-33`, still negligible but creeping up. + * @param fn - Cipher constructor that expects a nonce. + * @param randomBytes_ - Random-byte source used for nonce generation. + * @returns Cipher constructor that prepends the nonce to ciphertext. + * @throws On wrong argument types. {@link TypeError} + * @throws On invalid nonce lengths observed at wrapper construction or use. {@link RangeError} + * @example + * Prepends a fresh random nonce to every ciphertext. + * + * ```ts + * import { gcm } from '@noble/ciphers/aes.js'; + * import { managedNonce, randomBytes } from '@noble/ciphers/utils.js'; + * const wrapped = managedNonce(gcm); + * const key = randomBytes(16); + * const ciphertext = wrapped(key).encrypt(new Uint8Array([1, 2, 3])); + * wrapped(key).decrypt(ciphertext); + * ``` + */ +export function managedNonce( + fn: T, + randomBytes_: typeof randomBytes = randomBytes +): TRet> { + const { nonceLength } = fn; + anumber(nonceLength); + const addNonce = ( + nonce: TArg, + ciphertext: TArg, + plaintext: TArg + ) => { + const out = concatBytes(nonce, ciphertext); + // Wrapped ciphers may alias caller plaintext on encrypt(); never zero + // caller-owned buffers here. + if (!overlapBytes(plaintext, ciphertext)) ciphertext.fill(0); + return out; + }; + // NOTE: we cannot support DST here, it would be mistake: + // - we don't know how much dst length cipher requires + // - nonce may unalign dst and break everything + // - we create new u8a anyway (concatBytes) + // - previously we passed all args to cipher, but that was mistake! + const res = ((key: TArg, ...args: any[]): any => ({ + encrypt(plaintext: TArg) { + abytes(plaintext); + const nonce = randomBytes_(nonceLength); + const encrypted = fn(key, nonce, ...args).encrypt(plaintext); + // @ts-ignore + if (encrypted instanceof Promise) + return encrypted.then((ct) => addNonce(nonce, ct, plaintext)); + return addNonce(nonce, encrypted, plaintext); + }, + decrypt(ciphertext: TArg) { + abytes(ciphertext); + const nonce = ciphertext.subarray(0, nonceLength); + const decrypted = ciphertext.subarray(nonceLength); + return fn(key, nonce, ...args).decrypt(decrypted); + }, + })) as RemoveNonce & { blockSize?: number; tagLength?: number }; + // Auto-nonce wrappers still preserve the wrapped payload geometry. + if ('blockSize' in fn) res.blockSize = (fn as any).blockSize; + if ('tagLength' in fn) res.tagLength = (fn as any).tagLength; + return res as TRet>; +} + +/** `Uint8Array.of()` return type helper for TS 5.9. */ +export type Uint8ArrayBuffer = TRet; diff --git a/node_modules/@noble/ciphers/src/webcrypto.ts b/node_modules/@noble/ciphers/src/webcrypto.ts new file mode 100644 index 0000000..889d91e --- /dev/null +++ b/node_modules/@noble/ciphers/src/webcrypto.ts @@ -0,0 +1,226 @@ +/** + * WebCrypto-based AES gcm/ctr/cbc, `managedNonce` and `randomBytes`. + * We use WebCrypto aka globalThis.crypto, which exists in browsers and node.js 16+. + * @module + */ +import { abytes, anumber, type AsyncCipher, type TArg, type TRet } from './utils.ts'; + +function getWebcryptoSubtle(): any { + const cr = typeof globalThis !== 'undefined' && (globalThis as any).crypto; + if (cr && typeof cr.subtle === 'object' && cr.subtle != null) return cr.subtle; + throw new Error('crypto.subtle must be defined'); +} + +type WebcryptoUtils = { + encrypt( + key: TArg, + keyParams: unknown, + cryptParams: unknown, + plaintext: TArg + ): Promise>; + decrypt( + key: TArg, + keyParams: unknown, + cryptParams: unknown, + ciphertext: TArg + ): Promise>; +}; +/** + * Internal webcrypto utils. Can be overridden if crypto.subtle is not present, + * for example in React Native. + * Raw keys are re-imported on every call; this wrapper intentionally does not + * cache `CryptoKey` objects between operations. + */ +export const utils: TRet = { + async encrypt( + key: TArg, + keyParams: any, + cryptParams: any, + plaintext: TArg + ): Promise> { + const cr = getWebcryptoSubtle(); + const iKey = await cr.importKey('raw', key, keyParams, true, ['encrypt']); + const ciphertext = await cr.encrypt(cryptParams, iKey, plaintext); + return new Uint8Array(ciphertext) as TRet; + }, + async decrypt( + key: TArg, + keyParams: any, + cryptParams: any, + ciphertext: TArg + ): Promise> { + const cr = getWebcryptoSubtle(); + const iKey = await cr.importKey('raw', key, keyParams, true, ['decrypt']); + const plaintext = await cr.decrypt(cryptParams, iKey, ciphertext); + return new Uint8Array(plaintext) as TRet; + }, +}; + +const mode = { + CBC: 'AES-CBC', + CTR: 'AES-CTR', + GCM: 'AES-GCM', +} as const; +type BlockMode = (typeof mode)[keyof typeof mode]; + +function getCryptParams(algo: BlockMode, nonce: TArg, AAD?: TArg) { + if (algo === mode.CBC) return { name: mode.CBC, iv: nonce }; + // WebCrypto allows 1..128 counter bits; use the full block to match sync ctr() / Node CTR wrap. + if (algo === mode.CTR) return { name: mode.CTR, counter: nonce, length: 128 }; + if (algo === mode.GCM) { + // Rely on the backend default tag length (128 bits) instead of setting it explicitly. + if (AAD) return { name: mode.GCM, iv: nonce, additionalData: AAD }; + else return { name: mode.GCM, iv: nonce }; + } + + throw new Error('unknown aes block mode'); +} + +function generate( + algo: BlockMode, + nonceLength: number +): TRet< + ((key: TArg, nonce: TArg, AAD?: TArg) => AsyncCipher) & { + blockSize: number; + nonceLength: number; + } +> { + anumber(nonceLength); + const res = ( + key: TArg, + nonce: TArg, + AAD?: TArg + ): TRet => { + abytes(key); + abytes(nonce); + // Reject falsy non-byte AAD locally; otherwise false/0/''/null silently become "no AAD". + if (AAD !== undefined) abytes(AAD, undefined, 'AAD'); + // Exact nonce-length enforcement and WebCrypto-specific AAD normalization are + // delegated to the backend; locally we only require byte-array inputs here. + // Keep caller key/nonce/AAD by reference; mutating them after + // construction changes later operations. + const keyParams = { name: algo, length: key.length * 8 }; + const cryptParams = getCryptParams(algo, nonce, AAD); + let consumed = false; + return { + // keyLength, + encrypt(plaintext: TArg): Promise> { + abytes(plaintext); + if (consumed) throw new Error('Cannot encrypt() twice with same key / nonce'); + consumed = true; + return utils.encrypt(key, keyParams, cryptParams, plaintext); + }, + decrypt(ciphertext: TArg): Promise> { + abytes(ciphertext); + return utils.decrypt(key, keyParams, cryptParams, ciphertext); + }, + } as TRet; + }; + res.nonceLength = nonceLength; + res.blockSize = 16; // always for AES + return res as TRet< + ((key: TArg, nonce: TArg, AAD?: TArg) => AsyncCipher) & { + blockSize: number; + nonceLength: number; + } + >; +} + +/** + * AES-CBC implemented with WebCrypto. + * Uses WebCrypto's built-in PKCS padding behavior; exact IV-length checks are + * delegated to the backend instead of local `abytes(..., 16)` validation. + * @param key - AES key bytes. + * @param iv - 16-byte initialization vector. + * @returns Async cipher instance. + * @example + * Encrypts a block with the browser or Node WebCrypto backend. + * + * ```ts + * import { cbc } from '@noble/ciphers/webcrypto.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(16); + * const iv = randomBytes(16); + * const cipher = cbc(key, iv); + * await cipher.encrypt(new Uint8Array(16)); + * ``` + */ +export const cbc: TRet< + ((key: TArg, iv: TArg) => AsyncCipher) & { + blockSize: number; + nonceLength: number; + } +> = /* @__PURE__ */ (() => generate(mode.CBC, 16))(); +/** + * AES-CTR implemented with WebCrypto. + * Uses WebCrypto's full 128-bit counter-length setting so the whole + * 16-byte counter block is incremented, matching sync `aes.ts:ctr`. + * @param key - AES key bytes. + * @param nonce - 16-byte counter block incremented as a full big-endian AES counter block. + * @returns Async cipher instance. + * @example + * Encrypts a short payload with WebCrypto AES-CTR. + * + * ```ts + * import { ctr } from '@noble/ciphers/webcrypto.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(16); + * const nonce = randomBytes(16); + * const cipher = ctr(key, nonce); + * await cipher.encrypt(new Uint8Array([1, 2, 3])); + * ``` + */ +export const ctr: TRet< + ((key: TArg, nonce: TArg) => AsyncCipher) & { + blockSize: number; + nonceLength: number; + } +> = /* @__PURE__ */ (() => generate(mode.CTR, 16))(); +/** + * AES-GCM implemented with WebCrypto. + * AAD type normalization and nonce-shape enforcement beyond raw bytes are left + * to the backend WebCrypto implementation. + * @param key - AES key bytes. + * @param nonce - Nonce bytes. + * @param AAD - Additional authenticated data. + * @returns Async cipher instance. + * @example + * Encrypts and authenticates plaintext with WebCrypto AES-GCM. + * + * ```ts + * import { gcm } from '@noble/ciphers/webcrypto.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(16); + * const nonce = randomBytes(12); + * const cipher = gcm(key, nonce); + * await cipher.encrypt(new Uint8Array([1, 2, 3])); + * ``` + */ +export const gcm: TRet< + ((key: TArg, nonce: TArg, AAD?: TArg) => AsyncCipher) & { + blockSize: number; + nonceLength: number; + } +> = /* @__PURE__ */ (() => generate(mode.GCM, 12))(); + +// // Type tests +// import { siv, gcm, ctr, ecb, cbc } from '../aes.ts'; +// import { xsalsa20poly1305 } from '../salsa.ts'; +// import { chacha20poly1305, xchacha20poly1305 } from '../chacha.ts'; + +// const wsiv = managedNonce(siv); +// const wgcm = managedNonce(gcm); +// const wctr = managedNonce(ctr); +// const wcbc = managedNonce(cbc); +// const wsalsapoly = managedNonce(xsalsa20poly1305); +// const wchacha = managedNonce(chacha20poly1305); +// const wxchacha = managedNonce(xchacha20poly1305); + +// // should fail +// const wcbc2 = managedNonce(managedNonce(cbc)); +// const wctr = managedNonce(ctr); +// import { gcm as gcmSync } from '../aes.ts'; +// const x1 = managedNonce(gcmSync); +// // const x1: (key: Uint8Array, AAD?: Uint8Array | undefined) => Cipher +// const x2 = managedNonce(gcm); +// // const x2: (key: Uint8Array, AAD?: Uint8Array | undefined) => AsyncCipher diff --git a/node_modules/@noble/ciphers/utils.d.ts b/node_modules/@noble/ciphers/utils.d.ts new file mode 100644 index 0000000..2aee9df --- /dev/null +++ b/node_modules/@noble/ciphers/utils.d.ts @@ -0,0 +1,717 @@ +/** + * Utilities for hex, bytes, CSPRNG. + * @module + */ +/*! noble-ciphers - MIT License (c) 2023 Paul Miller (paulmillr.com) */ +/** + * Bytes API type helpers for old + new TypeScript. + * + * TS 5.6 has `Uint8Array`, while TS 5.9+ made it generic `Uint8Array`. + * We can't use specific return type, because TS 5.6 will error. + * We can't use generic return type, because most TS 5.9 software will expect specific type. + * + * Maps typed-array input leaves to broad forms. + * These are compatibility adapters, not ownership guarantees. + * + * - `TArg` keeps byte inputs broad. + * - `TRet` marks byte outputs for TS 5.6 and TS 5.9+ compatibility. + */ +export type TypedArg = T extends BigInt64Array ? BigInt64Array : T extends BigUint64Array ? BigUint64Array : T extends Float32Array ? Float32Array : T extends Float64Array ? Float64Array : T extends Int16Array ? Int16Array : T extends Int32Array ? Int32Array : T extends Int8Array ? Int8Array : T extends Uint16Array ? Uint16Array : T extends Uint32Array ? Uint32Array : T extends Uint8ClampedArray ? Uint8ClampedArray : T extends Uint8Array ? Uint8Array : never; +/** Maps typed-array output leaves to narrow TS-compatible forms. */ +export type TypedRet = T extends BigInt64Array ? ReturnType : T extends BigUint64Array ? ReturnType : T extends Float32Array ? ReturnType : T extends Float64Array ? ReturnType : T extends Int16Array ? ReturnType : T extends Int32Array ? ReturnType : T extends Int8Array ? ReturnType : T extends Uint16Array ? ReturnType : T extends Uint32Array ? ReturnType : T extends Uint8ClampedArray ? ReturnType : T extends Uint8Array ? ReturnType : never; +/** Recursively adapts byte-carrying API input types. See {@link TypedArg}. */ +export type TArg = T | ([TypedArg] extends [never] ? T extends (...args: infer A) => infer R ? ((...args: { + [K in keyof A]: TRet; +}) => TArg) & { + [K in keyof T]: T[K] extends (...args: any) => any ? T[K] : TArg; +} : T extends [infer A, ...infer R] ? [TArg, ...{ + [K in keyof R]: TArg; +}] : T extends readonly [infer A, ...infer R] ? readonly [TArg, ...{ + [K in keyof R]: TArg; +}] : T extends (infer A)[] ? TArg[] : T extends readonly (infer A)[] ? readonly TArg[] : T extends Promise ? Promise> : T extends object ? { + [K in keyof T]: TArg; +} : T : TypedArg); +/** Recursively adapts byte-carrying API output types. See {@link TypedArg}. */ +export type TRet = T extends unknown ? T & ([TypedRet] extends [never] ? T extends (...args: infer A) => infer R ? ((...args: { + [K in keyof A]: TArg; +}) => TRet) & { + [K in keyof T]: T[K] extends (...args: any) => any ? T[K] : TRet; +} : T extends [infer A, ...infer R] ? [TRet, ...{ + [K in keyof R]: TRet; +}] : T extends readonly [infer A, ...infer R] ? readonly [TRet, ...{ + [K in keyof R]: TRet; +}] : T extends (infer A)[] ? TRet[] : T extends readonly (infer A)[] ? readonly TRet[] : T extends Promise ? Promise> : T extends object ? { + [K in keyof T]: TRet; +} : T : TypedRet) : never; +/** + * Checks if something is Uint8Array. Be careful: nodejs Buffer will return true. + * @param a - Value to inspect. + * @returns `true` when the value is a Uint8Array view, including Node's `Buffer`. + * @example + * Guards a value before treating it as raw key material. + * + * ```ts + * isBytes(new Uint8Array()); + * ``` + */ +export declare function isBytes(a: unknown): a is Uint8Array; +/** + * Asserts something is boolean. + * @param b - Value to validate. + * @throws On wrong argument types. {@link TypeError} + * @example + * Validates a boolean option before branching on it. + * + * ```ts + * abool(true); + * ``` + */ +export declare function abool(b: boolean): void; +/** + * Asserts something is a non-negative safe integer. + * @param n - Value to validate. + * @throws On wrong argument types. {@link TypeError} + * @throws On wrong argument ranges or values. {@link RangeError} + * @example + * Validates a non-negative length or counter. + * + * ```ts + * anumber(1); + * ``` + */ +export declare function anumber(n: number): void; +/** + * Asserts something is Uint8Array. + * @param value - Value to validate. + * @param length - Expected byte length. + * @param title - Optional label used in error messages. + * @returns The validated byte array. + * On Node, `Buffer` is accepted too because it is a Uint8Array view. + * @throws On wrong argument types. {@link TypeError} + * @throws On wrong argument lengths. {@link RangeError} + * @example + * Validates a fixed-length nonce or key buffer. + * + * ```ts + * abytes(new Uint8Array([1, 2]), 2); + * ``` + */ +export declare function abytes(value: TArg, length?: number, title?: string): TRet; +/** + * Asserts a hash- or MAC-like instance has not been destroyed or finished. + * @param instance - Stateful instance to validate. + * @param checkFinished - Whether to reject finished instances. + * When `false`, only `destroyed` is checked. + * @throws If the hash instance has already been destroyed or finalized. {@link Error} + * @example + * Guards against calling `update()` or `digest()` on a finished hash. + * + * ```ts + * aexists({ destroyed: false, finished: false }); + * ``` + */ +export declare function aexists(instance: any, checkFinished?: boolean): void; +/** + * Asserts output is a properly-sized byte array. + * @param out - Output buffer to validate. + * @param instance - Hash-like instance providing `outputLen`. + * This is the relaxed `digestInto()`-style contract: output must be at least `outputLen`, + * unlike one-shot cipher helpers elsewhere in the repo that often require exact lengths. + * @throws On wrong argument types. {@link TypeError} + * @param onlyAligned - Whether `out` must be 4-byte aligned for zero-allocation word views. + * @throws On wrong output buffer lengths. {@link RangeError} + * @throws On wrong output buffer alignment. {@link Error} + * @example + * Verifies that a caller-provided output buffer is large enough. + * + * ```ts + * aoutput(new Uint8Array(16), { outputLen: 16 }); + * ``` + */ +export declare function aoutput(out: any, instance: any, onlyAligned?: boolean): void; +/** One-shot hash helper with `.create()`. */ +export type IHash = { + (data: string | TArg): TRet; + /** Input block size in bytes. */ + blockLen: number; + /** Digest size in bytes. */ + outputLen: number; + /** Creates a fresh incremental hash instance of the same algorithm. */ + create: any; +}; +/** One-shot MAC helper with `.create()`. */ +export type CMac = { + (msg: TArg, key: TArg): TRet; + /** Input block size in bytes. */ + blockLen: number; + /** Digest size in bytes. */ + outputLen: number; + /** + * Creates a fresh incremental MAC instance of the same algorithm. + * @param key - MAC key bytes. + * @param args - Additional constructor arguments, when the MAC wrapper needs them. + * @returns Fresh incremental MAC instance. + */ + create(key: TArg, ...args: A): H; +}; +/** Generic type encompassing 8/16/32-bit typed arrays, but not 64-bit. */ +export type TypedArray = Int8Array | Uint8ClampedArray | Uint8Array | Uint16Array | Int16Array | Uint32Array | Int32Array; +/** + * Casts a typed-array view to Uint8Array. + * @param arr - Typed-array view to reinterpret. + * @returns Uint8Array view over the same bytes. + * @example + * Views 32-bit words as raw bytes without copying. + * + * ```ts + * u8(new Uint32Array([1])); + * ``` + */ +export declare function u8(arr: TArg): TRet; +/** + * Casts a typed-array view to Uint32Array. + * @param arr - Typed-array view to reinterpret. + * @returns Uint32Array view over the same bytes. Callers are expected to provide a + * 4-byte-aligned offset; trailing `1..3` bytes are silently dropped. + * @example + * Views a byte buffer as 32-bit words for block processing. + * + * ```ts + * u32(new Uint8Array(4)); + * ``` + */ +export declare function u32(arr: TArg): TRet; +/** + * Zeroizes typed arrays in place. + * Warning: JS provides no guarantees. + * @param arrays - Arrays to wipe. + * @example + * Wipes a temporary key buffer after use. + * + * ```ts + * const bytes = new Uint8Array([1]); + * clean(bytes); + * ``` + */ +export declare function clean(...arrays: TArg): void; +/** + * Creates a DataView for byte-level manipulation. + * @param arr - Typed-array view to wrap. + * @returns DataView over the same bytes. + * @example + * Creates an endian-aware view for length encoding. + * + * ```ts + * createView(new Uint8Array(4)); + * ``` + */ +export declare function createView(arr: TArg): DataView; +/** + * Whether the current platform is little-endian. + * Most are; some IBM systems are not. + */ +export declare const isLE: boolean; +/** + * Reverses byte order of one 32-bit word. + * @param word - Unsigned 32-bit word to swap. + * @returns The same word with bytes reversed. + * @example + * Swaps a big-endian word into little-endian byte order. + * + * ```ts + * byteSwap(0x11223344); + * ``` + */ +export declare const byteSwap: (word: number) => number; +/** + * Normalizes one 32-bit word to the little-endian representation expected by cipher cores. + * @param n - Unsigned 32-bit word to normalize. + * @returns Little-endian normalized word on big-endian hosts, else the input word unchanged. + * @example + * Normalizes a host-endian word before passing it into an ARX/AES core. + * + * ```ts + * swap8IfBE(0x11223344); + * ``` + */ +export declare const swap8IfBE: (n: number) => number; +/** + * Byte-swaps every word of a Uint32Array in place. + * @param arr - Uint32Array whose words should be swapped. + * @returns The same array after in-place byte swapping. + * @example + * Swaps every 32-bit word in a word-view buffer. + * + * ```ts + * byteSwap32(new Uint32Array([0x11223344])); + * ``` + */ +export declare const byteSwap32: (arr: TArg) => TRet; +/** + * Normalizes a Uint32Array view to the little-endian representation expected by cipher cores. + * @param u - Word view to normalize in place. + * @returns Little-endian normalized word view. + * @example + * Normalizes a word-view buffer before block processing. + * + * ```ts + * swap32IfBE(new Uint32Array([0x11223344])); + * ``` + */ +export declare const swap32IfBE: (u: TArg) => TRet; +/** + * Convert byte array to hex string. Uses built-in function, when available. + * @param bytes - Bytes to encode. + * @returns Lowercase hexadecimal string. + * @throws On wrong argument types. {@link TypeError} + * @example + * Formats ciphertext bytes for logs or test vectors. + * + * ```ts + * bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])); // 'cafe0123' + * ``` + */ +export declare function bytesToHex(bytes: TArg): string; +/** + * Convert hex string to byte array. Uses built-in function, when available. + * @param hex - Hexadecimal string to decode. + * @returns Decoded bytes. + * @throws On wrong argument types. {@link TypeError} + * @throws On malformed hexadecimal input. {@link RangeError} + * @example + * Parses a hex test vector into bytes. + * + * ```ts + * hexToBytes('cafe0123'); // Uint8Array.from([0xca, 0xfe, 0x01, 0x23]) + * ``` + */ +export declare function hexToBytes(hex: string): TRet; +/** + * Converts a big-endian hex string into bigint. + * @param hex - Hexadecimal string without `0x`. + * @returns Parsed bigint value. The empty string is treated as `0n`. + * @throws On wrong argument types. {@link TypeError} + * @example + * Parses a big-endian field element or counter from hex. + * + * ```ts + * hexToNumber('ff'); + * ``` + */ +export declare function hexToNumber(hex: string): bigint; +/** + * Converts big-endian bytes into bigint. + * @param bytes - Big-endian bytes. + * @returns Parsed bigint value. Empty input is treated as `0n`. + * @throws On invalid byte input passed to the internal hex conversion. {@link TypeError} + * @example + * Reads a big-endian integer from serialized bytes. + * + * ```ts + * bytesToNumberBE(new Uint8Array([1, 0])); + * ``` + */ +export declare function bytesToNumberBE(bytes: TArg): bigint; +/** + * Converts a number into big-endian bytes of fixed length. + * @param n - Number to encode. + * @param len - Output length in bytes. + * @returns Big-endian bytes padded to `len`. + * Validation is indirect through `hexToBytes(...)`, so negative values, `len = 0`, + * and values that do not fit surface through the downstream hex parser instead of a + * dedicated range guard here. + * @throws On wrong argument types. {@link TypeError} + * @throws If the requested output length cannot represent the encoded value. {@link RangeError} + * @example + * Encodes a counter as fixed-width big-endian bytes. + * + * ```ts + * numberToBytesBE(1, 2); + * ``` + */ +export declare function numberToBytesBE(n: number | bigint, len: number): TRet; +/** + * Converts string to bytes using UTF8 encoding. + * @param str - String to encode. + * @returns UTF-8 bytes in a detached fresh Uint8Array copy. + * @throws On wrong argument types. {@link TypeError} + * @example + * Encodes application text before encryption or MACing. + * + * ```ts + * utf8ToBytes('abc'); // new Uint8Array([97, 98, 99]) + * ``` + */ +export declare function utf8ToBytes(str: string): TRet; +/** + * Converts bytes to string using UTF8 encoding. + * @param bytes - UTF-8 bytes. + * @returns Decoded string. Input validation is delegated to `TextDecoder`, and malformed + * UTF-8 is replacement-decoded instead of rejected. + * @example + * Decodes UTF-8 plaintext back into a string. + * + * ```ts + * bytesToUtf8(new Uint8Array([97, 98, 99])); // 'abc' + * ``` + */ +export declare function bytesToUtf8(bytes: TArg): string; +/** + * Checks if two U8A use same underlying buffer and overlaps. + * This is invalid and can corrupt data. + * @param a - First byte view. + * @param b - Second byte view. + * @returns `true` when the views overlap in memory. + * @example + * Detects whether two slices alias the same backing buffer. + * + * ```ts + * overlapBytes(new Uint8Array(4), new Uint8Array(4)); + * ``` + */ +export declare function overlapBytes(a: TArg, b: TArg): boolean; +/** + * If input and output overlap and input starts before output, we will overwrite end of input before + * we start processing it, so this is not supported for most ciphers + * (except chacha/salsa, which were designed for this) + * @param input - Input bytes. + * @param output - Output bytes. + * @throws If the output view would overwrite unread input bytes. {@link Error} + * @example + * Rejects an in-place layout that would overwrite unread input bytes. + * + * ```ts + * complexOverlapBytes(new Uint8Array(4), new Uint8Array(4)); + * ``` + */ +export declare function complexOverlapBytes(input: TArg, output: TArg): void; +/** + * Copies several Uint8Arrays into one. + * @param arrays - Byte arrays to concatenate. + * @returns Combined byte array. + * @throws On wrong argument types inside the byte-array list. {@link TypeError} + * @example + * Builds a `nonce || ciphertext` style buffer. + * + * ```ts + * concatBytes(new Uint8Array([1]), new Uint8Array([2])); + * ``` + */ +export declare function concatBytes(...arrays: TArg): TRet; +type EmptyObj = {}; +/** + * Merges user options into defaults. + * @param defaults - Default option values. + * @param opts - User-provided overrides. + * @returns Combined options object. + * The merge mutates `defaults` in place and returns the same object. + * @throws If options are missing or not an object. {@link Error} + * @example + * Applies user overrides to the default cipher options. + * + * ```ts + * checkOpts({ rounds: 20 }, { rounds: 8 }); + * ``` + */ +export declare function checkOpts(defaults: T1, opts: T2): T1 & T2; +/** + * Compares two byte arrays in kinda constant time once lengths already match. + * @param a - First byte array. + * @param b - Second byte array. + * @returns `true` when the arrays contain the same bytes. Different lengths still return early. + * @example + * Compares an expected authentication tag with the received one. + * + * ```ts + * equalBytes(new Uint8Array([1]), new Uint8Array([1])); + * ``` + */ +export declare function equalBytes(a: TArg, b: TArg): boolean; +/** Incremental hash interface used internally. */ +export interface IHash2 { + /** Bytes processed per compression block. */ + blockLen: number; + /** Bytes produced by the final digest. */ + outputLen: number; + /** + * Absorbs one more chunk into the hash state. + * @param buf - Data chunk to hash. + * @returns The same hash instance for chaining. + */ + update(buf: string | TArg): this; + /** + * Writes the final digest into a caller-provided buffer. + * @param buf - Destination buffer for the digest bytes. + * @returns Nothing. Implementations write into `buf` in place. + */ + digestInto(buf: TArg): void; + /** + * Finalizes the hash and returns a fresh digest buffer. + * @returns Digest bytes. + */ + digest(): TRet; + /** + * Resets internal state. Makes Hash instance unusable. + * Reset is impossible for keyed hashes if key is consumed into state. If digest is not consumed + * by user, they will need to manually call `destroy()` when zeroing is necessary. + */ + destroy(): void; +} +/** + * Wraps a keyed MAC constructor into a one-shot helper with `.create()`. + * @param keyLen - Valid probe-key length used to read static metadata once. + * The probe key is only used for `outputLen` / `blockLen`, so callers with several valid key sizes + * can pass any representative size as long as those values stay fixed. + * @param macCons - Keyed MAC constructor or factory. + * @param fromMsg - Optional adapter that derives extra constructor args from the one-shot message. + * @returns Callable MAC helper with `.create()`. + */ +export declare function wrapMacConstructor(keyLen: number, macCons: TArg<(key: Uint8Array, ...args: A) => H>, fromMsg?: TArg<(msg: Uint8Array) => A>): TRet>; +/** Sync cipher: takes byte array and returns byte array. */ +export type Cipher = { + /** + * Encrypts plaintext bytes. + * @param plaintext - Data to encrypt. + * @returns Ciphertext bytes. + */ + encrypt(plaintext: TArg): TRet; + /** + * Decrypts ciphertext bytes. + * @param ciphertext - Data to decrypt. + * @returns Plaintext bytes. + */ + decrypt(ciphertext: TArg): TRet; +}; +/** Async cipher e.g. from built-in WebCrypto. */ +export type AsyncCipher = { + /** + * Encrypts plaintext bytes. + * @param plaintext - Data to encrypt. + * @returns Promise resolving to ciphertext bytes. + */ + encrypt(plaintext: TArg): Promise>; + /** + * Decrypts ciphertext bytes. + * @param ciphertext - Data to decrypt. + * @returns Promise resolving to plaintext bytes. + */ + decrypt(ciphertext: TArg): Promise>; +}; +/** Cipher with `output` argument which can optimize by doing 1 less allocation. */ +export type CipherWithOutput = Cipher & { + /** + * Encrypts plaintext bytes into an optional caller-provided buffer. + * @param plaintext - Data to encrypt. + * @param output - Optional destination buffer. + * @returns Ciphertext bytes. + */ + encrypt(plaintext: TArg, output?: TArg): TRet; + /** + * Decrypts ciphertext bytes into an optional caller-provided buffer. + * @param ciphertext - Data to decrypt. + * @param output - Optional destination buffer. + * @returns Plaintext bytes. + */ + decrypt(ciphertext: TArg, output?: TArg): TRet; +}; +/** + * Params are outside of return type, so it is accessible before calling constructor. + * If function support multiple nonceLength's, we return the best one. + */ +export type CipherParams = { + /** Cipher block size in bytes. */ + blockSize: number; + /** Nonce length in bytes when the cipher uses a fixed nonce size. */ + nonceLength?: number; + /** Authentication-tag length in bytes for AEAD modes. */ + tagLength?: number; + /** Whether nonce length is variable at runtime. */ + varSizeNonce?: boolean; +}; +/** + * ARX AEAD cipher, like salsa or chacha. + * @param key - Secret key bytes. + * @param nonce - Nonce bytes. + * @param AAD - Optional associated data. + * @returns Cipher instance with caller-managed output buffers. + */ +export type ARXCipher = ((key: TArg, nonce: TArg, AAD?: TArg) => CipherWithOutput) & { + blockSize: number; + nonceLength: number; + tagLength: number; +}; +/** + * Cipher constructor signature. + * @param key - Secret key bytes. + * @param args - Additional constructor arguments, such as nonce or IV. + * @returns Cipher instance. + */ +export type CipherCons = (key: TArg, ...args: T) => Cipher; +/** + * Wraps a cipher: validates args, ensures encrypt() can only be called once. + * Used internally by the exported cipher constructors. + * Output-buffer support is inferred from the wrapped `encrypt` / `decrypt` + * arity (`fn.length === 2`), and tag-bearing constructors are expected to use + * `args[1]` for optional AAD. + * @__NO_SIDE_EFFECTS__ + * @param params - Static cipher metadata. See {@link CipherParams}. + * @param constructor - Cipher constructor. + * @returns Wrapped constructor with validation. + */ +export declare const wrapCipher: , P extends CipherParams>(params: P, constructor: C) => C & P; +/** + * Represents a Salsa or ChaCha xor stream. + * @param key - Secret key bytes. + * @param nonce - Nonce bytes. + * @param data - Input bytes to xor with the keystream. + * @param output - Optional destination buffer. + * @param counter - Optional starting block counter. + * @returns Output bytes. + */ +export type XorStream = (key: TArg, nonce: TArg, data: TArg, output?: TArg, counter?: number) => TRet; +/** + * By default, returns u8a of length. + * When out is available, it checks it for validity and uses it. + * @param expectedLength - Required output length. + * @param out - Optional destination buffer. + * @param onlyAligned - Whether `out` must be 4-byte aligned. + * @returns Output buffer ready for writing. + * @throws On wrong argument types. {@link TypeError} + * @throws If the provided output buffer has the wrong size or alignment. {@link Error} + * @example + * Reuses a caller-provided output buffer when lengths match. + * + * ```ts + * getOutput(16, new Uint8Array(16)); + * ``` + */ +export declare function getOutput(expectedLength: number, out?: TArg, onlyAligned?: boolean): TRet; +/** + * Encodes data and AAD bit lengths into a 16-byte buffer. + * @param dataLength - Data length in bits. + * @param aadLength - AAD length in bits. + * The serialized block is still `aadLength || dataLength`, matching GCM/Poly1305 + * conventions even though the helper parameter order is `(dataLength, aadLength)`. + * @param isLE - Whether to encode lengths as little-endian. + * @returns 16-byte length block. + * @throws On wrong argument types passed to the endian validator. {@link TypeError} + * @throws On wrong argument ranges or values. {@link RangeError} + * @example + * Builds the length block appended by GCM and Poly1305. + * + * ```ts + * u64Lengths(16, 8, true); + * ``` + */ +export declare function u64Lengths(dataLength: number, aadLength: number, isLE: boolean): TRet; +/** + * Checks whether a byte array is aligned to a 4-byte offset. + * @param bytes - Byte array to inspect. + * @returns `true` when the view is 4-byte aligned. + * @example + * Checks whether a buffer can be safely viewed as Uint32Array. + * + * ```ts + * isAligned32(new Uint8Array(4)); + * ``` + */ +export declare function isAligned32(bytes: TArg): boolean; +/** + * Copies bytes into a new Uint8Array. + * @param bytes - Bytes to copy. + * @returns Copied byte array. + * @throws On wrong argument types. {@link TypeError} + * @example + * Copies input into an aligned Uint8Array before block processing. + * + * ```ts + * copyBytes(new Uint8Array([1, 2])); + * ``` + */ +export declare function copyBytes(bytes: TArg): TRet; +/** + * Cryptographically secure PRNG. + * Uses internal OS-level `crypto.getRandomValues`. + * @param bytesLength - Number of bytes to produce. + * Validation is delegated to `Uint8Array(bytesLength)` and `getRandomValues`, so + * non-integers, negative lengths, and oversize requests surface backend/runtime errors. + * @returns Random byte array. + * @throws On wrong argument types. {@link TypeError} + * @throws On wrong argument ranges or values. {@link RangeError} + * @throws If the runtime does not expose `crypto.getRandomValues`. {@link Error} + * @example + * Generates a fresh nonce or key. + * + * ```ts + * randomBytes(16); + * ``` + */ +export declare function randomBytes(bytesLength?: number): TRet; +/** + * The pseudorandom number generator doesn't wipe current state: + * instead, it generates new one based on previous state + entropy. + * Not reseed/rekey, since AES CTR DRBG does rekey on each randomBytes, + * which is in fact `reseed`, since it changes counter too. + */ +export interface PRG { + /** + * Mixes fresh entropy into the current generator state. + * @param seed - Entropy bytes to absorb. + */ + addEntropy(seed: TArg): void; + /** + * Produces a requested number of pseudorandom bytes. + * @param bytesLength - Number of bytes to generate. + * @returns Random byte array. + */ + randomBytes(bytesLength: number): TRet; + /** Destroys the generator state. */ + clean(): void; +} +/** Removes the nonce argument from a cipher constructor type. */ +export type RemoveNonce any> = T extends (arg0: any, arg1: any, ...rest: infer R) => infer Ret ? (key: TArg, ...args: R) => Ret : never; +/** + * Cipher constructor that requires a nonce argument. + * @param key - Secret key bytes. + * @param nonce - Nonce bytes. + * @param args - Additional cipher-specific arguments. + * @returns Cipher instance. + */ +export type CipherWithNonce = ((key: TArg, nonce: TArg, ...args: any[]) => Cipher | AsyncCipher) & { + nonceLength: number; +}; +/** + * Uses CSPRNG for nonce, nonce injected in ciphertext. + * For `encrypt`, a `nonceBytes`-length buffer is fetched from CSPRNG and + * prepended to encrypted ciphertext. For `decrypt`, first `nonceBytes` of ciphertext + * are treated as nonce. The wrapper always allocates a fresh `nonce || ciphertext` + * buffer on encrypt and intentionally does not support caller-provided destination buffers. + * Too-short decrypt inputs are split into short/empty nonce views and then delegated + * to the wrapped cipher instead of being rejected here first. + * + * NOTE: Under the same key, using random nonces (e.g. `managedNonce`) with AES-GCM and ChaCha + * should be limited to `2**23` (8M) messages to get a collision chance of + * `2**-50`. Stretching to `2**32` (4B) messages would raise that chance to + * `2**-33`, still negligible but creeping up. + * @param fn - Cipher constructor that expects a nonce. + * @param randomBytes_ - Random-byte source used for nonce generation. + * @returns Cipher constructor that prepends the nonce to ciphertext. + * @throws On wrong argument types. {@link TypeError} + * @throws On invalid nonce lengths observed at wrapper construction or use. {@link RangeError} + * @example + * Prepends a fresh random nonce to every ciphertext. + * + * ```ts + * import { gcm } from '@noble/ciphers/aes.js'; + * import { managedNonce, randomBytes } from '@noble/ciphers/utils.js'; + * const wrapped = managedNonce(gcm); + * const key = randomBytes(16); + * const ciphertext = wrapped(key).encrypt(new Uint8Array([1, 2, 3])); + * wrapped(key).decrypt(ciphertext); + * ``` + */ +export declare function managedNonce(fn: T, randomBytes_?: typeof randomBytes): TRet>; +/** `Uint8Array.of()` return type helper for TS 5.9. */ +export type Uint8ArrayBuffer = TRet; +export {}; +//# sourceMappingURL=utils.d.ts.map \ No newline at end of file diff --git a/node_modules/@noble/ciphers/utils.d.ts.map b/node_modules/@noble/ciphers/utils.d.ts.map new file mode 100644 index 0000000..8242ae7 --- /dev/null +++ b/node_modules/@noble/ciphers/utils.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["src/utils.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@noble/ciphers/utils.js b/node_modules/@noble/ciphers/utils.js new file mode 100644 index 0000000..692efa0 --- /dev/null +++ b/node_modules/@noble/ciphers/utils.js @@ -0,0 +1,807 @@ +/** + * Utilities for hex, bytes, CSPRNG. + * @module + */ +/*! noble-ciphers - MIT License (c) 2023 Paul Miller (paulmillr.com) */ +/** + * Checks if something is Uint8Array. Be careful: nodejs Buffer will return true. + * @param a - Value to inspect. + * @returns `true` when the value is a Uint8Array view, including Node's `Buffer`. + * @example + * Guards a value before treating it as raw key material. + * + * ```ts + * isBytes(new Uint8Array()); + * ``` + */ +export function isBytes(a) { + // Plain `instanceof Uint8Array` is too strict for some Buffer / proxy / + // cross-realm cases. The fallback still requires a real ArrayBuffer view + // so plain JSON-deserialized `{ constructor: ... }` + // spoofing is rejected, and `BYTES_PER_ELEMENT === 1` keeps the fallback on byte-oriented views. + return (a instanceof Uint8Array || + (ArrayBuffer.isView(a) && + a.constructor.name === 'Uint8Array' && + 'BYTES_PER_ELEMENT' in a && + a.BYTES_PER_ELEMENT === 1)); +} +/** + * Asserts something is boolean. + * @param b - Value to validate. + * @throws On wrong argument types. {@link TypeError} + * @example + * Validates a boolean option before branching on it. + * + * ```ts + * abool(true); + * ``` + */ +export function abool(b) { + if (typeof b !== 'boolean') + throw new TypeError(`boolean expected, not ${b}`); +} +/** + * Asserts something is a non-negative safe integer. + * @param n - Value to validate. + * @throws On wrong argument types. {@link TypeError} + * @throws On wrong argument ranges or values. {@link RangeError} + * @example + * Validates a non-negative length or counter. + * + * ```ts + * anumber(1); + * ``` + */ +export function anumber(n) { + if (typeof n !== 'number') + throw new TypeError('number expected, got ' + typeof n); + if (!Number.isSafeInteger(n) || n < 0) + throw new RangeError('positive integer expected, got ' + n); +} +/** + * Asserts something is Uint8Array. + * @param value - Value to validate. + * @param length - Expected byte length. + * @param title - Optional label used in error messages. + * @returns The validated byte array. + * On Node, `Buffer` is accepted too because it is a Uint8Array view. + * @throws On wrong argument types. {@link TypeError} + * @throws On wrong argument lengths. {@link RangeError} + * @example + * Validates a fixed-length nonce or key buffer. + * + * ```ts + * abytes(new Uint8Array([1, 2]), 2); + * ``` + */ +export function abytes(value, length, title = '') { + const bytes = isBytes(value); + const len = value?.length; + const needsLen = length !== undefined; + if (!bytes || (needsLen && len !== length)) { + const prefix = title && `"${title}" `; + const ofLen = needsLen ? ` of length ${length}` : ''; + const got = bytes ? `length=${len}` : `type=${typeof value}`; + const message = prefix + 'expected Uint8Array' + ofLen + ', got ' + got; + if (!bytes) + throw new TypeError(message); + throw new RangeError(message); + } + return value; +} +/** + * Asserts a hash- or MAC-like instance has not been destroyed or finished. + * @param instance - Stateful instance to validate. + * @param checkFinished - Whether to reject finished instances. + * When `false`, only `destroyed` is checked. + * @throws If the hash instance has already been destroyed or finalized. {@link Error} + * @example + * Guards against calling `update()` or `digest()` on a finished hash. + * + * ```ts + * aexists({ destroyed: false, finished: false }); + * ``` + */ +export function aexists(instance, checkFinished = true) { + if (instance.destroyed) + throw new Error('Hash instance has been destroyed'); + if (checkFinished && instance.finished) + throw new Error('Hash#digest() has already been called'); +} +/** + * Asserts output is a properly-sized byte array. + * @param out - Output buffer to validate. + * @param instance - Hash-like instance providing `outputLen`. + * This is the relaxed `digestInto()`-style contract: output must be at least `outputLen`, + * unlike one-shot cipher helpers elsewhere in the repo that often require exact lengths. + * @throws On wrong argument types. {@link TypeError} + * @param onlyAligned - Whether `out` must be 4-byte aligned for zero-allocation word views. + * @throws On wrong output buffer lengths. {@link RangeError} + * @throws On wrong output buffer alignment. {@link Error} + * @example + * Verifies that a caller-provided output buffer is large enough. + * + * ```ts + * aoutput(new Uint8Array(16), { outputLen: 16 }); + * ``` + */ +export function aoutput(out, instance, onlyAligned = false) { + abytes(out, undefined, 'output'); + const min = instance.outputLen; + if (out.length < min) { + throw new RangeError('digestInto() expects output buffer of length at least ' + min); + } + if (onlyAligned && !isAligned32(out)) + throw new Error('invalid output, must be aligned'); +} +/** + * Casts a typed-array view to Uint8Array. + * @param arr - Typed-array view to reinterpret. + * @returns Uint8Array view over the same bytes. + * @example + * Views 32-bit words as raw bytes without copying. + * + * ```ts + * u8(new Uint32Array([1])); + * ``` + */ +export function u8(arr) { + return new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength); +} +/** + * Casts a typed-array view to Uint32Array. + * @param arr - Typed-array view to reinterpret. + * @returns Uint32Array view over the same bytes. Callers are expected to provide a + * 4-byte-aligned offset; trailing `1..3` bytes are silently dropped. + * @example + * Views a byte buffer as 32-bit words for block processing. + * + * ```ts + * u32(new Uint8Array(4)); + * ``` + */ +export function u32(arr) { + return new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4)); +} +/** + * Zeroizes typed arrays in place. + * Warning: JS provides no guarantees. + * @param arrays - Arrays to wipe. + * @example + * Wipes a temporary key buffer after use. + * + * ```ts + * const bytes = new Uint8Array([1]); + * clean(bytes); + * ``` + */ +export function clean(...arrays) { + for (let i = 0; i < arrays.length; i++) { + arrays[i].fill(0); + } +} +/** + * Creates a DataView for byte-level manipulation. + * @param arr - Typed-array view to wrap. + * @returns DataView over the same bytes. + * @example + * Creates an endian-aware view for length encoding. + * + * ```ts + * createView(new Uint8Array(4)); + * ``` + */ +export function createView(arr) { + return new DataView(arr.buffer, arr.byteOffset, arr.byteLength); +} +/** + * Whether the current platform is little-endian. + * Most are; some IBM systems are not. + */ +export const isLE = /* @__PURE__ */ (() => new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44)(); +/** + * Reverses byte order of one 32-bit word. + * @param word - Unsigned 32-bit word to swap. + * @returns The same word with bytes reversed. + * @example + * Swaps a big-endian word into little-endian byte order. + * + * ```ts + * byteSwap(0x11223344); + * ``` + */ +export const byteSwap = (word) => ((word << 24) & 0xff000000) | + ((word << 8) & 0xff0000) | + ((word >>> 8) & 0xff00) | + ((word >>> 24) & 0xff); +/** + * Normalizes one 32-bit word to the little-endian representation expected by cipher cores. + * @param n - Unsigned 32-bit word to normalize. + * @returns Little-endian normalized word on big-endian hosts, else the input word unchanged. + * @example + * Normalizes a host-endian word before passing it into an ARX/AES core. + * + * ```ts + * swap8IfBE(0x11223344); + * ``` + */ +export const swap8IfBE = isLE + ? (n) => n + : (n) => byteSwap(n) >>> 0; +/** + * Byte-swaps every word of a Uint32Array in place. + * @param arr - Uint32Array whose words should be swapped. + * @returns The same array after in-place byte swapping. + * @example + * Swaps every 32-bit word in a word-view buffer. + * + * ```ts + * byteSwap32(new Uint32Array([0x11223344])); + * ``` + */ +export const byteSwap32 = (arr) => { + for (let i = 0; i < arr.length; i++) + arr[i] = byteSwap(arr[i]); + return arr; +}; +/** + * Normalizes a Uint32Array view to the little-endian representation expected by cipher cores. + * @param u - Word view to normalize in place. + * @returns Little-endian normalized word view. + * @example + * Normalizes a word-view buffer before block processing. + * + * ```ts + * swap32IfBE(new Uint32Array([0x11223344])); + * ``` + */ +export const swap32IfBE = isLE + ? (u) => u + : byteSwap32; +// Built-in hex conversion: +// {@link https://caniuse.com/mdn-javascript_builtins_uint8array_fromhex | caniuse entry} +const hasHexBuiltin = /* @__PURE__ */ (() => +// @ts-ignore +typeof Uint8Array.from([]).toHex === 'function' && typeof Uint8Array.fromHex === 'function')(); +// Array where index 0xf0 (240) is mapped to string 'f0' +const hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, '0')); +/** + * Convert byte array to hex string. Uses built-in function, when available. + * @param bytes - Bytes to encode. + * @returns Lowercase hexadecimal string. + * @throws On wrong argument types. {@link TypeError} + * @example + * Formats ciphertext bytes for logs or test vectors. + * + * ```ts + * bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])); // 'cafe0123' + * ``` + */ +export function bytesToHex(bytes) { + abytes(bytes); + // @ts-ignore + if (hasHexBuiltin) + return bytes.toHex(); + // pre-caching improves the speed 6x + let hex = ''; + for (let i = 0; i < bytes.length; i++) { + hex += hexes[bytes[i]]; + } + return hex; +} +// We use optimized technique to convert hex string to byte array +const asciis = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 }; +function asciiToBase16(ch) { + if (ch >= asciis._0 && ch <= asciis._9) + return ch - asciis._0; // '2' => 50-48 + if (ch >= asciis.A && ch <= asciis.F) + return ch - (asciis.A - 10); // 'B' => 66-(65-10) + if (ch >= asciis.a && ch <= asciis.f) + return ch - (asciis.a - 10); // 'b' => 98-(97-10) + return; +} +/** + * Convert hex string to byte array. Uses built-in function, when available. + * @param hex - Hexadecimal string to decode. + * @returns Decoded bytes. + * @throws On wrong argument types. {@link TypeError} + * @throws On malformed hexadecimal input. {@link RangeError} + * @example + * Parses a hex test vector into bytes. + * + * ```ts + * hexToBytes('cafe0123'); // Uint8Array.from([0xca, 0xfe, 0x01, 0x23]) + * ``` + */ +export function hexToBytes(hex) { + if (typeof hex !== 'string') + throw new TypeError('hex string expected, got ' + typeof hex); + if (hasHexBuiltin) { + try { + return Uint8Array.fromHex(hex); + } + catch (error) { + if (error instanceof SyntaxError) + throw new RangeError(error.message); + throw error; + } + } + const hl = hex.length; + const al = hl / 2; + if (hl % 2) + throw new RangeError('hex string expected, got unpadded hex of length ' + hl); + const array = new Uint8Array(al); + for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) { + const n1 = asciiToBase16(hex.charCodeAt(hi)); + const n2 = asciiToBase16(hex.charCodeAt(hi + 1)); + if (n1 === undefined || n2 === undefined) { + const char = hex[hi] + hex[hi + 1]; + throw new RangeError('hex string expected, got non-hex character "' + char + '" at index ' + hi); + } + array[ai] = n1 * 16 + n2; // multiply first octet, e.g. 'a3' => 10*16+3 => 160 + 3 => 163 + } + return array; +} +// Used in micro +/** + * Converts a big-endian hex string into bigint. + * @param hex - Hexadecimal string without `0x`. + * @returns Parsed bigint value. The empty string is treated as `0n`. + * @throws On wrong argument types. {@link TypeError} + * @example + * Parses a big-endian field element or counter from hex. + * + * ```ts + * hexToNumber('ff'); + * ``` + */ +export function hexToNumber(hex) { + if (typeof hex !== 'string') + throw new TypeError('hex string expected, got ' + typeof hex); + return BigInt(hex === '' ? '0' : '0x' + hex); // Big Endian +} +// Used in ff1 +// BE: Big Endian, LE: Little Endian +/** + * Converts big-endian bytes into bigint. + * @param bytes - Big-endian bytes. + * @returns Parsed bigint value. Empty input is treated as `0n`. + * @throws On invalid byte input passed to the internal hex conversion. {@link TypeError} + * @example + * Reads a big-endian integer from serialized bytes. + * + * ```ts + * bytesToNumberBE(new Uint8Array([1, 0])); + * ``` + */ +export function bytesToNumberBE(bytes) { + return hexToNumber(bytesToHex(bytes)); +} +// Used in micro, ff1 +/** + * Converts a number into big-endian bytes of fixed length. + * @param n - Number to encode. + * @param len - Output length in bytes. + * @returns Big-endian bytes padded to `len`. + * Validation is indirect through `hexToBytes(...)`, so negative values, `len = 0`, + * and values that do not fit surface through the downstream hex parser instead of a + * dedicated range guard here. + * @throws On wrong argument types. {@link TypeError} + * @throws If the requested output length cannot represent the encoded value. {@link RangeError} + * @example + * Encodes a counter as fixed-width big-endian bytes. + * + * ```ts + * numberToBytesBE(1, 2); + * ``` + */ +export function numberToBytesBE(n, len) { + // Reject coercible non-numeric inputs before string/hex conversion changes behavior. + if (typeof n === 'number') + anumber(n); + else if (typeof n !== 'bigint') + throw new TypeError(`number or bigint expected, got ${typeof n}`); + anumber(len); + return hexToBytes(n.toString(16).padStart(len * 2, '0')); +} +/** + * Converts string to bytes using UTF8 encoding. + * @param str - String to encode. + * @returns UTF-8 bytes in a detached fresh Uint8Array copy. + * @throws On wrong argument types. {@link TypeError} + * @example + * Encodes application text before encryption or MACing. + * + * ```ts + * utf8ToBytes('abc'); // new Uint8Array([97, 98, 99]) + * ``` + */ +export function utf8ToBytes(str) { + if (typeof str !== 'string') + throw new TypeError('string expected'); + return new Uint8Array(new TextEncoder().encode(str)); // {@link https://bugzil.la/1681809 | Firefox bug 1681809} +} +/** + * Converts bytes to string using UTF8 encoding. + * @param bytes - UTF-8 bytes. + * @returns Decoded string. Input validation is delegated to `TextDecoder`, and malformed + * UTF-8 is replacement-decoded instead of rejected. + * @example + * Decodes UTF-8 plaintext back into a string. + * + * ```ts + * bytesToUtf8(new Uint8Array([97, 98, 99])); // 'abc' + * ``` + */ +export function bytesToUtf8(bytes) { + return new TextDecoder().decode(bytes); +} +/** + * Checks if two U8A use same underlying buffer and overlaps. + * This is invalid and can corrupt data. + * @param a - First byte view. + * @param b - Second byte view. + * @returns `true` when the views overlap in memory. + * @example + * Detects whether two slices alias the same backing buffer. + * + * ```ts + * overlapBytes(new Uint8Array(4), new Uint8Array(4)); + * ``` + */ +export function overlapBytes(a, b) { + // Zero-length views cannot overwrite anything, even if their offset sits inside another range. + if (!a.byteLength || !b.byteLength) + return false; + return (a.buffer === b.buffer && // best we can do, may fail with an obscure Proxy + a.byteOffset < b.byteOffset + b.byteLength && // a starts before b end + b.byteOffset < a.byteOffset + a.byteLength // b starts before a end + ); +} +/** + * If input and output overlap and input starts before output, we will overwrite end of input before + * we start processing it, so this is not supported for most ciphers + * (except chacha/salsa, which were designed for this) + * @param input - Input bytes. + * @param output - Output bytes. + * @throws If the output view would overwrite unread input bytes. {@link Error} + * @example + * Rejects an in-place layout that would overwrite unread input bytes. + * + * ```ts + * complexOverlapBytes(new Uint8Array(4), new Uint8Array(4)); + * ``` + */ +export function complexOverlapBytes(input, output) { + // This is very cursed. It works somehow, but I'm completely unsure, + // reasoning about overlapping aligned windows is very hard. + if (overlapBytes(input, output) && input.byteOffset < output.byteOffset) + throw new Error('complex overlap of input and output is not supported'); +} +/** + * Copies several Uint8Arrays into one. + * @param arrays - Byte arrays to concatenate. + * @returns Combined byte array. + * @throws On wrong argument types inside the byte-array list. {@link TypeError} + * @example + * Builds a `nonce || ciphertext` style buffer. + * + * ```ts + * concatBytes(new Uint8Array([1]), new Uint8Array([2])); + * ``` + */ +export function concatBytes(...arrays) { + let sum = 0; + for (let i = 0; i < arrays.length; i++) { + const a = arrays[i]; + abytes(a); + sum += a.length; + } + const res = new Uint8Array(sum); + for (let i = 0, pad = 0; i < arrays.length; i++) { + const a = arrays[i]; + res.set(a, pad); + pad += a.length; + } + return res; +} +/** + * Merges user options into defaults. + * @param defaults - Default option values. + * @param opts - User-provided overrides. + * @returns Combined options object. + * The merge mutates `defaults` in place and returns the same object. + * @throws If options are missing or not an object. {@link Error} + * @example + * Applies user overrides to the default cipher options. + * + * ```ts + * checkOpts({ rounds: 20 }, { rounds: 8 }); + * ``` + */ +export function checkOpts(defaults, opts) { + if (opts == null || typeof opts !== 'object') + throw new Error('options must be defined'); + const merged = Object.assign(defaults, opts); + return merged; +} +/** + * Compares two byte arrays in kinda constant time once lengths already match. + * @param a - First byte array. + * @param b - Second byte array. + * @returns `true` when the arrays contain the same bytes. Different lengths still return early. + * @example + * Compares an expected authentication tag with the received one. + * + * ```ts + * equalBytes(new Uint8Array([1]), new Uint8Array([1])); + * ``` + */ +export function equalBytes(a, b) { + if (a.length !== b.length) + return false; + let diff = 0; + for (let i = 0; i < a.length; i++) + diff |= a[i] ^ b[i]; + return diff === 0; +} +/** + * Wraps a keyed MAC constructor into a one-shot helper with `.create()`. + * @param keyLen - Valid probe-key length used to read static metadata once. + * The probe key is only used for `outputLen` / `blockLen`, so callers with several valid key sizes + * can pass any representative size as long as those values stay fixed. + * @param macCons - Keyed MAC constructor or factory. + * @param fromMsg - Optional adapter that derives extra constructor args from the one-shot message. + * @returns Callable MAC helper with `.create()`. + */ +export function wrapMacConstructor(keyLen, macCons, fromMsg) { + const mac = macCons; + const getArgs = (fromMsg || (() => [])); + const macC = (msg, key) => mac(key, ...getArgs(msg)) + .update(msg) + .digest(); + const tmp = mac(new Uint8Array(keyLen), ...getArgs(new Uint8Array(0))); + macC.outputLen = tmp.outputLen; + macC.blockLen = tmp.blockLen; + macC.create = (key, ...args) => mac(key, ...args); + return macC; +} +/** + * Wraps a cipher: validates args, ensures encrypt() can only be called once. + * Used internally by the exported cipher constructors. + * Output-buffer support is inferred from the wrapped `encrypt` / `decrypt` + * arity (`fn.length === 2`), and tag-bearing constructors are expected to use + * `args[1]` for optional AAD. + * @__NO_SIDE_EFFECTS__ + * @param params - Static cipher metadata. See {@link CipherParams}. + * @param constructor - Cipher constructor. + * @returns Wrapped constructor with validation. + */ +export const wrapCipher = (params, constructor) => { + function wrappedCipher(key, ...args) { + // Validate key + abytes(key, undefined, 'key'); + // Validate nonce if nonceLength is present + if (params.nonceLength !== undefined) { + const nonce = args[0]; + abytes(nonce, params.varSizeNonce ? undefined : params.nonceLength, 'nonce'); + } + // Validate AAD if tagLength present + const tagl = params.tagLength; + if (tagl && args[1] !== undefined) + abytes(args[1], undefined, 'AAD'); + const cipher = constructor(key, ...args); + const checkOutput = (fnLength, output) => { + if (output !== undefined) { + if (fnLength !== 2) + throw new Error('cipher output not supported'); + abytes(output, undefined, 'output'); + } + }; + // Create wrapped cipher with validation and single-use encryption + let called = false; + const wrCipher = { + encrypt(data, output) { + if (called) + throw new Error('cannot encrypt() twice with same key + nonce'); + called = true; + abytes(data); + checkOutput(cipher.encrypt.length, output); + return cipher.encrypt(data, output); + }, + decrypt(data, output) { + abytes(data); + if (tagl && data.length < tagl) + throw new Error('"ciphertext" expected length bigger than tagLength=' + tagl); + checkOutput(cipher.decrypt.length, output); + return cipher.decrypt(data, output); + }, + }; + return wrCipher; + } + Object.assign(wrappedCipher, params); + return wrappedCipher; +}; +/** + * By default, returns u8a of length. + * When out is available, it checks it for validity and uses it. + * @param expectedLength - Required output length. + * @param out - Optional destination buffer. + * @param onlyAligned - Whether `out` must be 4-byte aligned. + * @returns Output buffer ready for writing. + * @throws On wrong argument types. {@link TypeError} + * @throws If the provided output buffer has the wrong size or alignment. {@link Error} + * @example + * Reuses a caller-provided output buffer when lengths match. + * + * ```ts + * getOutput(16, new Uint8Array(16)); + * ``` + */ +export function getOutput(expectedLength, out, onlyAligned = true) { + if (out === undefined) + return new Uint8Array(expectedLength); + // Keep Buffer/cross-realm Uint8Array support here instead of trusting a shape-compatible object. + abytes(out, undefined, 'output'); + if (out.length !== expectedLength) + throw new Error('"output" expected Uint8Array of length ' + expectedLength + ', got: ' + out.length); + if (onlyAligned && !isAligned32(out)) + throw new Error('invalid output, must be aligned'); + return out; +} +/** + * Encodes data and AAD bit lengths into a 16-byte buffer. + * @param dataLength - Data length in bits. + * @param aadLength - AAD length in bits. + * The serialized block is still `aadLength || dataLength`, matching GCM/Poly1305 + * conventions even though the helper parameter order is `(dataLength, aadLength)`. + * @param isLE - Whether to encode lengths as little-endian. + * @returns 16-byte length block. + * @throws On wrong argument types passed to the endian validator. {@link TypeError} + * @throws On wrong argument ranges or values. {@link RangeError} + * @example + * Builds the length block appended by GCM and Poly1305. + * + * ```ts + * u64Lengths(16, 8, true); + * ``` + */ +export function u64Lengths(dataLength, aadLength, isLE) { + // Reject coercible non-number lengths like '10' and true before BigInt(...) accepts them. + anumber(dataLength); + anumber(aadLength); + abool(isLE); + const num = new Uint8Array(16); + const view = createView(num); + view.setBigUint64(0, BigInt(aadLength), isLE); + view.setBigUint64(8, BigInt(dataLength), isLE); + return num; +} +/** + * Checks whether a byte array is aligned to a 4-byte offset. + * @param bytes - Byte array to inspect. + * @returns `true` when the view is 4-byte aligned. + * @example + * Checks whether a buffer can be safely viewed as Uint32Array. + * + * ```ts + * isAligned32(new Uint8Array(4)); + * ``` + */ +export function isAligned32(bytes) { + return bytes.byteOffset % 4 === 0; +} +/** + * Copies bytes into a new Uint8Array. + * @param bytes - Bytes to copy. + * @returns Copied byte array. + * @throws On wrong argument types. {@link TypeError} + * @example + * Copies input into an aligned Uint8Array before block processing. + * + * ```ts + * copyBytes(new Uint8Array([1, 2])); + * ``` + */ +export function copyBytes(bytes) { + // `Uint8Array.from(...)` would also accept arrays / other typed arrays. Keep this helper strict + // because callers use it at byte-validation boundaries before mutating the detached copy. + return Uint8Array.from(abytes(bytes)); +} +/** + * Cryptographically secure PRNG. + * Uses internal OS-level `crypto.getRandomValues`. + * @param bytesLength - Number of bytes to produce. + * Validation is delegated to `Uint8Array(bytesLength)` and `getRandomValues`, so + * non-integers, negative lengths, and oversize requests surface backend/runtime errors. + * @returns Random byte array. + * @throws On wrong argument types. {@link TypeError} + * @throws On wrong argument ranges or values. {@link RangeError} + * @throws If the runtime does not expose `crypto.getRandomValues`. {@link Error} + * @example + * Generates a fresh nonce or key. + * + * ```ts + * randomBytes(16); + * ``` + */ +export function randomBytes(bytesLength = 32) { + // Validate upfront so fractional / coercible lengths do not silently + // truncate through Uint8Array(). + anumber(bytesLength); + const cr = typeof globalThis === 'object' ? globalThis.crypto : null; + if (typeof cr?.getRandomValues !== 'function') + throw new Error('crypto.getRandomValues must be defined'); + return cr.getRandomValues(new Uint8Array(bytesLength)); +} +/** + * Uses CSPRNG for nonce, nonce injected in ciphertext. + * For `encrypt`, a `nonceBytes`-length buffer is fetched from CSPRNG and + * prepended to encrypted ciphertext. For `decrypt`, first `nonceBytes` of ciphertext + * are treated as nonce. The wrapper always allocates a fresh `nonce || ciphertext` + * buffer on encrypt and intentionally does not support caller-provided destination buffers. + * Too-short decrypt inputs are split into short/empty nonce views and then delegated + * to the wrapped cipher instead of being rejected here first. + * + * NOTE: Under the same key, using random nonces (e.g. `managedNonce`) with AES-GCM and ChaCha + * should be limited to `2**23` (8M) messages to get a collision chance of + * `2**-50`. Stretching to `2**32` (4B) messages would raise that chance to + * `2**-33`, still negligible but creeping up. + * @param fn - Cipher constructor that expects a nonce. + * @param randomBytes_ - Random-byte source used for nonce generation. + * @returns Cipher constructor that prepends the nonce to ciphertext. + * @throws On wrong argument types. {@link TypeError} + * @throws On invalid nonce lengths observed at wrapper construction or use. {@link RangeError} + * @example + * Prepends a fresh random nonce to every ciphertext. + * + * ```ts + * import { gcm } from '@noble/ciphers/aes.js'; + * import { managedNonce, randomBytes } from '@noble/ciphers/utils.js'; + * const wrapped = managedNonce(gcm); + * const key = randomBytes(16); + * const ciphertext = wrapped(key).encrypt(new Uint8Array([1, 2, 3])); + * wrapped(key).decrypt(ciphertext); + * ``` + */ +export function managedNonce(fn, randomBytes_ = randomBytes) { + const { nonceLength } = fn; + anumber(nonceLength); + const addNonce = (nonce, ciphertext, plaintext) => { + const out = concatBytes(nonce, ciphertext); + // Wrapped ciphers may alias caller plaintext on encrypt(); never zero + // caller-owned buffers here. + if (!overlapBytes(plaintext, ciphertext)) + ciphertext.fill(0); + return out; + }; + // NOTE: we cannot support DST here, it would be mistake: + // - we don't know how much dst length cipher requires + // - nonce may unalign dst and break everything + // - we create new u8a anyway (concatBytes) + // - previously we passed all args to cipher, but that was mistake! + const res = ((key, ...args) => ({ + encrypt(plaintext) { + abytes(plaintext); + const nonce = randomBytes_(nonceLength); + const encrypted = fn(key, nonce, ...args).encrypt(plaintext); + // @ts-ignore + if (encrypted instanceof Promise) + return encrypted.then((ct) => addNonce(nonce, ct, plaintext)); + return addNonce(nonce, encrypted, plaintext); + }, + decrypt(ciphertext) { + abytes(ciphertext); + const nonce = ciphertext.subarray(0, nonceLength); + const decrypted = ciphertext.subarray(nonceLength); + return fn(key, nonce, ...args).decrypt(decrypted); + }, + })); + // Auto-nonce wrappers still preserve the wrapped payload geometry. + if ('blockSize' in fn) + res.blockSize = fn.blockSize; + if ('tagLength' in fn) + res.tagLength = fn.tagLength; + return res; +} +//# sourceMappingURL=utils.js.map \ No newline at end of file diff --git a/node_modules/@noble/ciphers/utils.js.map b/node_modules/@noble/ciphers/utils.js.map new file mode 100644 index 0000000..fd8c6e3 --- /dev/null +++ b/node_modules/@noble/ciphers/utils.js.map @@ -0,0 +1 @@ +{"version":3,"file":"utils.js","sourceRoot":"","sources":["src/utils.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@noble/ciphers/webcrypto.d.ts b/node_modules/@noble/ciphers/webcrypto.d.ts new file mode 100644 index 0000000..4f4985f --- /dev/null +++ b/node_modules/@noble/ciphers/webcrypto.d.ts @@ -0,0 +1,89 @@ +/** + * WebCrypto-based AES gcm/ctr/cbc, `managedNonce` and `randomBytes`. + * We use WebCrypto aka globalThis.crypto, which exists in browsers and node.js 16+. + * @module + */ +import { type AsyncCipher, type TArg, type TRet } from './utils.ts'; +type WebcryptoUtils = { + encrypt(key: TArg, keyParams: unknown, cryptParams: unknown, plaintext: TArg): Promise>; + decrypt(key: TArg, keyParams: unknown, cryptParams: unknown, ciphertext: TArg): Promise>; +}; +/** + * Internal webcrypto utils. Can be overridden if crypto.subtle is not present, + * for example in React Native. + * Raw keys are re-imported on every call; this wrapper intentionally does not + * cache `CryptoKey` objects between operations. + */ +export declare const utils: TRet; +/** + * AES-CBC implemented with WebCrypto. + * Uses WebCrypto's built-in PKCS padding behavior; exact IV-length checks are + * delegated to the backend instead of local `abytes(..., 16)` validation. + * @param key - AES key bytes. + * @param iv - 16-byte initialization vector. + * @returns Async cipher instance. + * @example + * Encrypts a block with the browser or Node WebCrypto backend. + * + * ```ts + * import { cbc } from '@noble/ciphers/webcrypto.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(16); + * const iv = randomBytes(16); + * const cipher = cbc(key, iv); + * await cipher.encrypt(new Uint8Array(16)); + * ``` + */ +export declare const cbc: TRet<((key: TArg, iv: TArg) => AsyncCipher) & { + blockSize: number; + nonceLength: number; +}>; +/** + * AES-CTR implemented with WebCrypto. + * Uses WebCrypto's full 128-bit counter-length setting so the whole + * 16-byte counter block is incremented, matching sync `aes.ts:ctr`. + * @param key - AES key bytes. + * @param nonce - 16-byte counter block incremented as a full big-endian AES counter block. + * @returns Async cipher instance. + * @example + * Encrypts a short payload with WebCrypto AES-CTR. + * + * ```ts + * import { ctr } from '@noble/ciphers/webcrypto.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(16); + * const nonce = randomBytes(16); + * const cipher = ctr(key, nonce); + * await cipher.encrypt(new Uint8Array([1, 2, 3])); + * ``` + */ +export declare const ctr: TRet<((key: TArg, nonce: TArg) => AsyncCipher) & { + blockSize: number; + nonceLength: number; +}>; +/** + * AES-GCM implemented with WebCrypto. + * AAD type normalization and nonce-shape enforcement beyond raw bytes are left + * to the backend WebCrypto implementation. + * @param key - AES key bytes. + * @param nonce - Nonce bytes. + * @param AAD - Additional authenticated data. + * @returns Async cipher instance. + * @example + * Encrypts and authenticates plaintext with WebCrypto AES-GCM. + * + * ```ts + * import { gcm } from '@noble/ciphers/webcrypto.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(16); + * const nonce = randomBytes(12); + * const cipher = gcm(key, nonce); + * await cipher.encrypt(new Uint8Array([1, 2, 3])); + * ``` + */ +export declare const gcm: TRet<((key: TArg, nonce: TArg, AAD?: TArg) => AsyncCipher) & { + blockSize: number; + nonceLength: number; +}>; +export {}; +//# sourceMappingURL=webcrypto.d.ts.map \ No newline at end of file diff --git a/node_modules/@noble/ciphers/webcrypto.d.ts.map b/node_modules/@noble/ciphers/webcrypto.d.ts.map new file mode 100644 index 0000000..b42e059 --- /dev/null +++ b/node_modules/@noble/ciphers/webcrypto.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"webcrypto.d.ts","sourceRoot":"","sources":["src/webcrypto.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAmB,KAAK,WAAW,EAAE,KAAK,IAAI,EAAE,KAAK,IAAI,EAAE,MAAM,YAAY,CAAC;AAQrF,KAAK,cAAc,GAAG;IACpB,OAAO,CACL,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,EACrB,SAAS,EAAE,OAAO,EAClB,WAAW,EAAE,OAAO,EACpB,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,GAC1B,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;IAC7B,OAAO,CACL,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,EACrB,SAAS,EAAE,OAAO,EAClB,WAAW,EAAE,OAAO,EACpB,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,GAC3B,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;CAC9B,CAAC;AACF;;;;;GAKG;AACH,eAAO,MAAM,KAAK,EAAE,IAAI,CAAC,cAAc,CAuBtC,CAAC;AAwEF;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,GAAG,EAAE,IAAI,CACpB,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,KAAK,WAAW,CAAC,GAAG;IAC/D,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB,CACiD,CAAC;AACrD;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,GAAG,EAAE,IAAI,CACpB,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,UAAU,CAAC,KAAK,WAAW,CAAC,GAAG;IAClE,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB,CACiD,CAAC;AACrD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,GAAG,EAAE,IAAI,CACpB,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,UAAU,CAAC,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,KAAK,WAAW,CAAC,GAAG;IAC1F,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB,CACiD,CAAC"} \ No newline at end of file diff --git a/node_modules/@noble/ciphers/webcrypto.js b/node_modules/@noble/ciphers/webcrypto.js new file mode 100644 index 0000000..78e44a5 --- /dev/null +++ b/node_modules/@noble/ciphers/webcrypto.js @@ -0,0 +1,167 @@ +/** + * WebCrypto-based AES gcm/ctr/cbc, `managedNonce` and `randomBytes`. + * We use WebCrypto aka globalThis.crypto, which exists in browsers and node.js 16+. + * @module + */ +import { abytes, anumber } from "./utils.js"; +function getWebcryptoSubtle() { + const cr = typeof globalThis !== 'undefined' && globalThis.crypto; + if (cr && typeof cr.subtle === 'object' && cr.subtle != null) + return cr.subtle; + throw new Error('crypto.subtle must be defined'); +} +/** + * Internal webcrypto utils. Can be overridden if crypto.subtle is not present, + * for example in React Native. + * Raw keys are re-imported on every call; this wrapper intentionally does not + * cache `CryptoKey` objects between operations. + */ +export const utils = { + async encrypt(key, keyParams, cryptParams, plaintext) { + const cr = getWebcryptoSubtle(); + const iKey = await cr.importKey('raw', key, keyParams, true, ['encrypt']); + const ciphertext = await cr.encrypt(cryptParams, iKey, plaintext); + return new Uint8Array(ciphertext); + }, + async decrypt(key, keyParams, cryptParams, ciphertext) { + const cr = getWebcryptoSubtle(); + const iKey = await cr.importKey('raw', key, keyParams, true, ['decrypt']); + const plaintext = await cr.decrypt(cryptParams, iKey, ciphertext); + return new Uint8Array(plaintext); + }, +}; +const mode = { + CBC: 'AES-CBC', + CTR: 'AES-CTR', + GCM: 'AES-GCM', +}; +function getCryptParams(algo, nonce, AAD) { + if (algo === mode.CBC) + return { name: mode.CBC, iv: nonce }; + // WebCrypto allows 1..128 counter bits; use the full block to match sync ctr() / Node CTR wrap. + if (algo === mode.CTR) + return { name: mode.CTR, counter: nonce, length: 128 }; + if (algo === mode.GCM) { + // Rely on the backend default tag length (128 bits) instead of setting it explicitly. + if (AAD) + return { name: mode.GCM, iv: nonce, additionalData: AAD }; + else + return { name: mode.GCM, iv: nonce }; + } + throw new Error('unknown aes block mode'); +} +function generate(algo, nonceLength) { + anumber(nonceLength); + const res = (key, nonce, AAD) => { + abytes(key); + abytes(nonce); + // Reject falsy non-byte AAD locally; otherwise false/0/''/null silently become "no AAD". + if (AAD !== undefined) + abytes(AAD, undefined, 'AAD'); + // Exact nonce-length enforcement and WebCrypto-specific AAD normalization are + // delegated to the backend; locally we only require byte-array inputs here. + // Keep caller key/nonce/AAD by reference; mutating them after + // construction changes later operations. + const keyParams = { name: algo, length: key.length * 8 }; + const cryptParams = getCryptParams(algo, nonce, AAD); + let consumed = false; + return { + // keyLength, + encrypt(plaintext) { + abytes(plaintext); + if (consumed) + throw new Error('Cannot encrypt() twice with same key / nonce'); + consumed = true; + return utils.encrypt(key, keyParams, cryptParams, plaintext); + }, + decrypt(ciphertext) { + abytes(ciphertext); + return utils.decrypt(key, keyParams, cryptParams, ciphertext); + }, + }; + }; + res.nonceLength = nonceLength; + res.blockSize = 16; // always for AES + return res; +} +/** + * AES-CBC implemented with WebCrypto. + * Uses WebCrypto's built-in PKCS padding behavior; exact IV-length checks are + * delegated to the backend instead of local `abytes(..., 16)` validation. + * @param key - AES key bytes. + * @param iv - 16-byte initialization vector. + * @returns Async cipher instance. + * @example + * Encrypts a block with the browser or Node WebCrypto backend. + * + * ```ts + * import { cbc } from '@noble/ciphers/webcrypto.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(16); + * const iv = randomBytes(16); + * const cipher = cbc(key, iv); + * await cipher.encrypt(new Uint8Array(16)); + * ``` + */ +export const cbc = /* @__PURE__ */ (() => generate(mode.CBC, 16))(); +/** + * AES-CTR implemented with WebCrypto. + * Uses WebCrypto's full 128-bit counter-length setting so the whole + * 16-byte counter block is incremented, matching sync `aes.ts:ctr`. + * @param key - AES key bytes. + * @param nonce - 16-byte counter block incremented as a full big-endian AES counter block. + * @returns Async cipher instance. + * @example + * Encrypts a short payload with WebCrypto AES-CTR. + * + * ```ts + * import { ctr } from '@noble/ciphers/webcrypto.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(16); + * const nonce = randomBytes(16); + * const cipher = ctr(key, nonce); + * await cipher.encrypt(new Uint8Array([1, 2, 3])); + * ``` + */ +export const ctr = /* @__PURE__ */ (() => generate(mode.CTR, 16))(); +/** + * AES-GCM implemented with WebCrypto. + * AAD type normalization and nonce-shape enforcement beyond raw bytes are left + * to the backend WebCrypto implementation. + * @param key - AES key bytes. + * @param nonce - Nonce bytes. + * @param AAD - Additional authenticated data. + * @returns Async cipher instance. + * @example + * Encrypts and authenticates plaintext with WebCrypto AES-GCM. + * + * ```ts + * import { gcm } from '@noble/ciphers/webcrypto.js'; + * import { randomBytes } from '@noble/ciphers/utils.js'; + * const key = randomBytes(16); + * const nonce = randomBytes(12); + * const cipher = gcm(key, nonce); + * await cipher.encrypt(new Uint8Array([1, 2, 3])); + * ``` + */ +export const gcm = /* @__PURE__ */ (() => generate(mode.GCM, 12))(); +// // Type tests +// import { siv, gcm, ctr, ecb, cbc } from '../aes.ts'; +// import { xsalsa20poly1305 } from '../salsa.ts'; +// import { chacha20poly1305, xchacha20poly1305 } from '../chacha.ts'; +// const wsiv = managedNonce(siv); +// const wgcm = managedNonce(gcm); +// const wctr = managedNonce(ctr); +// const wcbc = managedNonce(cbc); +// const wsalsapoly = managedNonce(xsalsa20poly1305); +// const wchacha = managedNonce(chacha20poly1305); +// const wxchacha = managedNonce(xchacha20poly1305); +// // should fail +// const wcbc2 = managedNonce(managedNonce(cbc)); +// const wctr = managedNonce(ctr); +// import { gcm as gcmSync } from '../aes.ts'; +// const x1 = managedNonce(gcmSync); +// // const x1: (key: Uint8Array, AAD?: Uint8Array | undefined) => Cipher +// const x2 = managedNonce(gcm); +// // const x2: (key: Uint8Array, AAD?: Uint8Array | undefined) => AsyncCipher +//# sourceMappingURL=webcrypto.js.map \ No newline at end of file diff --git a/node_modules/@noble/ciphers/webcrypto.js.map b/node_modules/@noble/ciphers/webcrypto.js.map new file mode 100644 index 0000000..9c0edf5 --- /dev/null +++ b/node_modules/@noble/ciphers/webcrypto.js.map @@ -0,0 +1 @@ +{"version":3,"file":"webcrypto.js","sourceRoot":"","sources":["src/webcrypto.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@noble/hashes/LICENSE b/node_modules/@noble/hashes/LICENSE new file mode 100644 index 0000000..9297a04 --- /dev/null +++ b/node_modules/@noble/hashes/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2022 Paul Miller (https://paulmillr.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the “Software”), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/node_modules/@noble/hashes/README.md b/node_modules/@noble/hashes/README.md new file mode 100644 index 0000000..7cb8034 --- /dev/null +++ b/node_modules/@noble/hashes/README.md @@ -0,0 +1,563 @@ +# noble-hashes + +Audited & minimal JS implementation of hash functions, MACs and KDFs. + +- 🔒 [**Audited**](#security) by an independent security firm +- 🔻 Tree-shakeable: unused code is excluded from your builds +- 🏎 Fast: hand-optimized for caveats of JS engines +- 🔍 Reliable: chained / sliding window / DoS / ACVP tests and fuzzing +- 🔁 No unrolled loops: makes it easier to verify and reduces source code size up to 5x +- 🦘 Includes SHA, RIPEMD, BLAKE, HMAC, HKDF, PBKDF, Scrypt, Argon2 +- 🥈 Optional, friendly wrapper over native WebCrypto +- 🪶 22KB (gzipped) for everything, 2.4KB for single-hash build + +Use [awasm-noble](https://github.com/paulmillr/awasm-noble) if you need an even faster (WASM) alternative. +Check out [Upgrading](#upgrading) for information about upgrading from previous versions. +Take a glance at [GitHub Discussions](https://github.com/paulmillr/noble-hashes/discussions) for questions and support. + +The library's initial development was funded by [Ethereum Foundation](https://ethereum.org/). + +### This library belongs to _noble_ cryptography + +> **noble cryptography** — high-security, easily auditable set of contained cryptographic libraries and tools. + +- Zero or minimal dependencies +- Highly readable TypeScript / JS code +- PGP-signed releases and transparent NPM builds +- All libraries: + [ciphers](https://github.com/paulmillr/noble-ciphers), + [curves](https://github.com/paulmillr/noble-curves), + [hashes](https://github.com/paulmillr/noble-hashes), + [post-quantum](https://github.com/paulmillr/noble-post-quantum), + 5kb [secp256k1](https://github.com/paulmillr/noble-secp256k1) / + [ed25519](https://github.com/paulmillr/noble-ed25519) +- [Check out the homepage](https://paulmillr.com/noble/) + for reading resources, documentation, and apps built with noble + +## Usage + +> `npm install @noble/hashes` + +> `deno add jsr:@noble/hashes` + +We support all major platforms and runtimes. +For React Native, you may need a [polyfill for getRandomValues](https://github.com/LinusU/react-native-get-random-values). +A standalone file [noble-hashes.js](https://github.com/paulmillr/noble-hashes/releases) is also available. + +```js +// import * from '@noble/hashes'; // Error: use sub-imports, to ensure small app size +import { sha256 as noble_sha256 } from '@noble/hashes/sha2.js'; +const hash = noble_sha256(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])); + +// Available modules +import { sha256, sha384, sha512, sha224, sha512_224, sha512_256 } from '@noble/hashes/sha2.js'; +import { + sha3_256, sha3_512, + keccak_256, keccak_512, + shake128, shake256, +} from '@noble/hashes/sha3.js'; +import { + cshake256, turboshake256, kmac256, tuplehash256, + kt128, kt256, keccakprg, +} from '@noble/hashes/sha3-addons.js'; +import { blake3 } from '@noble/hashes/blake3.js'; +import { blake2b, blake2s } from '@noble/hashes/blake2.js'; +import { blake256, blake512 } from '@noble/hashes/blake1.js'; +import { sha1, md5, ripemd160 } from '@noble/hashes/legacy.js'; +import { hmac } from '@noble/hashes/hmac.js'; +import { hkdf } from '@noble/hashes/hkdf.js'; +import { pbkdf2, pbkdf2Async } from '@noble/hashes/pbkdf2.js'; +import { scrypt, scryptAsync } from '@noble/hashes/scrypt.js'; +import { argon2d, argon2i, argon2id } from '@noble/hashes/argon2.js'; +import * as webcrypto from '@noble/hashes/webcrypto.js'; +// const { sha256, sha384, sha512, hmac, hkdf, pbkdf2 } = webcrypto; +import * as utils from '@noble/hashes/utils.js'; +const { bytesToHex, concatBytes, equalBytes, hexToBytes } = utils; +``` + +- [sha2: sha256, sha384, sha512](#sha2-sha256-sha384-sha512-and-others) +- [sha3: FIPS, SHAKE, Keccak](#sha3-fips-shake-keccak) +- [sha3-addons: cSHAKE, KMAC, KT128, TurboSHAKE](#sha3-addons-cshake-kmac-kt128-turboshake) +- [blake1, blake2, blake3](#blake1-blake2-blake3) +- [legacy: sha1, md5, ripemd160](#legacy-sha1-md5-ripemd160) +- MACs: [hmac](#hmac) | [kmac](#sha3-addons-cshake-kmac-kt128-turboshake) | [blake3 key mode](#blake1-blake2-blake3) +- KDFs: [hkdf](#hkdf) | [pbkdf2](#pbkdf2) | [scrypt](#scrypt) | [argon2](#argon2) +- [webcrypto: friendly wrapper](#webcrypto-friendly-wrapper) +- [utils](#utils) +- [Security](#security) | [Speed](#speed) | [Contributing & testing](#contributing--testing) | [License](#license) + +### Implementations + +Hash functions: + +- `sha256()`: receive & return `Uint8Array` +- `sha256.create().update(a).update(b).digest()`: support partial updates +- `blake3.create({ context: 'e', dkLen: 32 })`: can have options +- support little-endian architecture; also experimentally big-endian +- can hash up to 4GB per chunk, with any amount of chunks + +#### sha2: sha256, sha384, sha512 and others + +```typescript +import { sha224, sha256, sha384, sha512, sha512_224, sha512_256 } from '@noble/hashes/sha2.js'; +const res = sha256(Uint8Array.from([0xbc])); // basic +for (let hash of [sha256, sha384, sha512, sha224, sha512_224, sha512_256]) { + const arr = Uint8Array.from([0x10, 0x20, 0x30]); + const a = hash(arr); + const b = hash.create().update(arr).digest(); +} +``` + +Check out [RFC 4634](https://datatracker.ietf.org/doc/html/rfc4634) and +[the paper on truncated SHA512/256](https://eprint.iacr.org/2010/548.pdf). + +#### sha3: FIPS, SHAKE, Keccak + +```typescript +import { + sha3_224, sha3_256, sha3_384, sha3_512, + keccak_224, keccak_256, keccak_384, keccak_512, + shake128, shake256, +} from '@noble/hashes/sha3.js'; +for (let hash of [ + sha3_224, sha3_256, sha3_384, sha3_512, + keccak_224, keccak_256, keccak_384, keccak_512, +]) { + const arr = Uint8Array.from([0x10, 0x20, 0x30]); + const a = hash(arr); + const b = hash.create().update(arr).digest(); +} +const shka = shake128(Uint8Array.from([0x10]), { dkLen: 512 }); +const shkb = shake256(Uint8Array.from([0x30]), { dkLen: 512 }); +``` + +Check out [FIPS-202](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf), +[Website](https://keccak.team/keccak.html). + +Check out [the differences between SHA-3 and Keccak](https://crypto.stackexchange.com/questions/15727/what-are-the-key-differences-between-the-draft-sha-3-standard-and-the-keccak-sub) + +#### sha3-addons: cSHAKE, KMAC, K12, TurboSHAKE + +```typescript +import { + cshake128, cshake256, kt128, kt256, + keccakprg, kmac128, kmac256, + parallelhash256, tuplehash256, + turboshake128, turboshake256, +} from '@noble/hashes/sha3-addons.js'; +const data = Uint8Array.from([0x10, 0x20, 0x30]); +const personalization = new TextEncoder().encode('def'); +const ec1 = cshake128(data, { personalization }); +const ec2 = cshake256(data, { personalization }); +const et1 = turboshake128(data); +const et2 = turboshake256(data, { D: 0x05 }); +// tuplehash(['ab', 'c']) !== tuplehash(['a', 'bc']) !== tuplehash([data]) +const et3 = tuplehash256([new TextEncoder().encode('ab'), new TextEncoder().encode('c')]); +// Not parallel in JS (similar to blake3 / kt128), added for compat +const ep1 = parallelhash256(data, { blockLen: 8 }); +const kk = Uint8Array.from([0xca]); +const ek10 = kmac128(kk, data); +const ek11 = kmac256(kk, data); +const ek12 = kt128(data); // kangarootwelve 128-bit +const ek13 = kt256(data); // kangarootwelve 256-bit +// pseudo-random generator, first argument is capacity. XKCP recommends 254 bits capacity for 128-bit security strength. +// * with a capacity of 254 bits. +const p = keccakprg(254); +p.addEntropy(Uint8Array.from([1, 2, 3])); +const rand1b = p.randomBytes(32); +``` + +- cSHAKE, KMAC, TupleHash, ParallelHash + XOF are available, matching + [NIST SP 800-185](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-185.pdf) +- Reduced-round Keccak KT128 (KangarooTwelve 🦘, K12) and TurboSHAKE are available, matching + [RFC 9861](https://datatracker.ietf.org/doc/rfc9861/). +- [KeccakPRG](https://keccak.team/files/CSF-0.1.pdf): pseudo-random generator based on Keccak + +#### blake1, blake2, blake3 + +```typescript +import { blake224, blake256, blake384, blake512 } from '@noble/hashes/blake1.js'; +import { blake2b, blake2s } from '@noble/hashes/blake2.js'; +import { blake3 } from '@noble/hashes/blake3.js'; + +for (let hash of [blake224, blake256, blake384, blake512, blake2b, blake2s, blake3]) { + const arr = Uint8Array.from([0x10, 0x20, 0x30]); + const a = hash(arr); + const b = hash.create().update(arr).digest(); +} + +// blake2 advanced usage +const ab = Uint8Array.from([0x01]); +const txt = new TextEncoder(); +blake2s(ab); +blake2s(ab, { key: new Uint8Array(32) }); +blake2s(ab, { personalization: txt.encode('pers1234') }); +blake2s(ab, { salt: txt.encode('salt1234') }); +blake2b(ab); +blake2b(ab, { key: new Uint8Array(64) }); +blake2b(ab, { personalization: txt.encode('pers1234pers1234') }); +blake2b(ab, { salt: txt.encode('salt1234salt1234') }); + +// blake3 advanced usage +blake3(ab); +blake3(ab, { dkLen: 256 }); +blake3(ab, { key: new Uint8Array(32) }); +blake3(ab, { context: txt.encode('application-name') }); +``` + +- Blake1 is legacy hash, one of SHA3 proposals. It is rarely used anywhere. See [pdf](https://www.aumasson.jp/blake/blake.pdf). +- Blake2 is popular fast hash. blake2b focuses on 64-bit platforms while blake2s is for 8-bit to 32-bit ones. See [RFC 7693](https://datatracker.ietf.org/doc/html/rfc7693), [Website](https://www.blake2.net) +- Blake3 is faster, reduced-round blake2. See [Website & specs](https://blake3.io) + +#### legacy: sha1, md5, ripemd160 + +SHA1 (RFC 3174), MD5 (RFC 1321) and RIPEMD160 (RFC 2286) legacy, weak hash functions. +Don't use them in a new protocol. What "weak" means: + +- Collisions can be made with 2^18 effort in MD5, 2^60 in SHA1, 2^80 in RIPEMD160. +- No practical pre-image attacks (only theoretical, 2^123.4) +- HMAC seems kinda ok: https://datatracker.ietf.org/doc/html/rfc6151 + +```typescript +import { md5, ripemd160, sha1 } from '@noble/hashes/legacy.js'; +for (let hash of [md5, ripemd160, sha1]) { + const arr = Uint8Array.from([0x10, 0x20, 0x30]); + const a = hash(arr); + const b = hash.create().update(arr).digest(); +} +``` + +#### hmac + +```typescript +import { hmac } from '@noble/hashes/hmac.js'; +import { sha256 } from '@noble/hashes/sha2.js'; +const key = new Uint8Array(32).fill(1); +const msg = new Uint8Array(32).fill(2); +const mac1 = hmac(sha256, key, msg); +const mac2 = hmac.create(sha256, key).update(msg).digest(); +``` + +Conforms to [RFC 2104](https://datatracker.ietf.org/doc/html/rfc2104). + +#### hkdf + +```typescript +import { hkdf } from '@noble/hashes/hkdf.js'; +import { randomBytes } from '@noble/hashes/utils.js'; +import { sha256 } from '@noble/hashes/sha2.js'; +const inputKey = randomBytes(32); +const salt = randomBytes(32); +const info = new TextEncoder().encode('application-key'); +const hk1 = hkdf(sha256, inputKey, salt, info, 32); + +// == same as +import { extract, expand } from '@noble/hashes/hkdf.js'; +const prk = extract(sha256, inputKey, salt); +const hk2 = expand(sha256, prk, info, 32); +``` + +Conforms to [RFC 5869](https://datatracker.ietf.org/doc/html/rfc5869). + +#### pbkdf2 + +```typescript +import { pbkdf2, pbkdf2Async } from '@noble/hashes/pbkdf2.js'; +import { sha256 } from '@noble/hashes/sha2.js'; +const pbkey1 = pbkdf2(sha256, 'password', 'salt', { c: 524288, dkLen: 32 }); +const pbkey2 = await pbkdf2Async(sha256, 'password', 'salt', { c: 524288, dkLen: 32 }); +const pbkey3 = await pbkdf2Async(sha256, Uint8Array.from([1, 2, 3]), Uint8Array.from([4, 5, 6]), { + c: 524288, + dkLen: 32, +}); +``` + +Conforms to [RFC 2898](https://datatracker.ietf.org/doc/html/rfc2898). + +#### scrypt + +```typescript +import { scrypt, scryptAsync } from '@noble/hashes/scrypt.js'; +const scr1 = scrypt('password', 'salt', { N: 2 ** 16, r: 8, p: 1, dkLen: 32 }); +const scr2 = await scryptAsync('password', 'salt', { N: 2 ** 16, r: 8, p: 1, dkLen: 32 }); +const scr3 = await scryptAsync(Uint8Array.from([1, 2, 3]), Uint8Array.from([4, 5, 6]), { + N: 2 ** 17, + r: 8, + p: 1, + dkLen: 32, + onProgress(percentage) { + console.log('progress', percentage); + }, + maxmem: 2 ** 32 + 128 * 8 * 1, // N * r * p * 128 + (128*r*p) +}); +``` + +Conforms to [RFC 7914](https://datatracker.ietf.org/doc/html/rfc7914), +[Website](https://www.tarsnap.com/scrypt.html) + +- `N, r, p` are work factors. It is common to only adjust N, while keeping `r: 8, p: 1`. + See [the blog post](https://blog.filippo.io/the-scrypt-parameters/). + JS doesn't support parallelization, making increasing `p` meaningless. +- `dkLen` is the length of output bytes e.g. `32` or `64` +- `onProgress` can be used with async version of the function to report progress to a user. +- `maxmem` prevents DoS and is limited to `1GB + 1KB` (`2**30 + 2**10`), but can be adjusted using formula: `N * r * p * 128 + (128 * r * p)` + +Time it takes to derive Scrypt key under different values of N (2\*\*N) on Apple M4 (mobile phones can be 1x-4x slower): + +| N pow | Time | RAM | +| ----- | ---- | ----- | +| 16 | 0.1s | 64MB | +| 17 | 0.2s | 128MB | +| 18 | 0.4s | 256MB | +| 19 | 0.8s | 512MB | +| 20 | 1.5s | 1GB | +| 21 | 3.1s | 2GB | +| 22 | 6.2s | 4GB | +| 23 | 13s | 8GB | +| 24 | 27s | 16GB | + +> [!NOTE] +> We support N larger than `2**20` where available, however, +> not all JS engines support >= 2GB ArrayBuffer-s. +> When using such N, you'll need to manually adjust `maxmem`, using formula above. +> Other JS implementations don't support large N-s. + +#### argon2 + +```ts +import { argon2d, argon2i, argon2id } from '@noble/hashes/argon2.js'; +const arg1 = argon2id('password', 'saltsalt', { t: 2, m: 65536, p: 1, maxmem: 2 ** 32 - 1 }); +``` + +Argon2 [RFC 9106](https://datatracker.ietf.org/doc/html/rfc9106) implementation. + +> [!WARNING] +> Argon2 can't be fast in JS, because there is no fast Uint64Array. +> It is suggested to use [Scrypt](#scrypt) instead. +> Being 5x slower than native code means brute-forcing attackers have bigger advantage. + +#### webcrypto: friendly wrapper + +```js +import { sha256, sha384, sha512, hmac, hkdf, pbkdf2 } from '@noble/hashes/webcrypto.js'; +import { randomBytes } from '@noble/hashes/utils.js'; +const whash = await sha256(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])); + +const key = new Uint8Array(32).fill(1); +const msg = new Uint8Array(32).fill(2); +const wmac = await hmac(sha256, key, msg); + +const inputKey = randomBytes(32); +const salt = randomBytes(32); +const info = new TextEncoder().encode('application-key'); +const hk1 = await hkdf(sha256, inputKey, salt, info, 32); + +const pbkey1 = await pbkdf2(sha256, 'password', 'salt', { c: 524288, dkLen: 32 }); +``` + +Sometimes people want to use built-in `crypto.subtle` instead of pure JS implementation. +However, it has terrible API. + +We simplify access to built-ins with API which mirrors noble-hashes. +The overhead is minimal - just 30+ lines of code, which verify input correctness. + +> [!NOTE] +> Webcrypto methods are always async. + +#### utils + +```typescript +import { bytesToHex as toHex, randomBytes } from '@noble/hashes/utils.js'; +console.log(toHex(randomBytes(32))); +``` + +- `bytesToHex` will convert `Uint8Array` to a hex string +- `randomBytes(bytes)` will produce cryptographically secure random `Uint8Array` of length `bytes` + +## Security + +The library has been audited: + +- at version 2.2.0, in Apr 2026, by ourselves (self-audited) + - Scope: everything + - [Changes since audit](https://github.com/paulmillr/noble-hashes/compare/2.2.0..main) +- at version 1.0.0, in Jan 2022, independently, by [Cure53](https://cure53.de) + - PDFs: [website](https://cure53.de/pentest-report_hashing-libs.pdf), [in-repo](./audit/2022-01-05-cure53-audit-nbl2.pdf) + - Scope: everything, besides `blake3`, `sha3-addons`, `sha1` and `argon2`, which have not been audited + - The audit has been funded by [Ethereum Foundation](https://ethereum.org/en/) with help of [Nomic Labs](https://nomiclabs.io) + +It is tested against property-based, cross-library and Wycheproof vectors, +and is being fuzzed in [the separate repo](https://github.com/paulmillr/fuzzing). + +If you see anything unusual: investigate and report. + +### Constant-timeness + +We're targetting algorithmic constant time. _JIT-compiler_ and _Garbage Collector_ make "constant time" +extremely hard to achieve [timing attack](https://en.wikipedia.org/wiki/Timing_attack) resistance +in a scripting language. Which means _any other JS library can't have +constant-timeness_. Even statically typed Rust, a language without GC, +[makes it harder to achieve constant-time](https://www.chosenplaintext.ca/open-source/rust-timing-shield/security) +for some cases. If your goal is absolute security, don't use any JS lib — including bindings to native ones. +Use low-level libraries & languages. + +### Memory dumping + +The library shares state buffers between hash +function calls. The buffers are zeroed-out after each call. However, if an attacker +can read application memory, you are doomed in any case: + +- At some point, input will be a string and strings are immutable in JS: + there is no way to overwrite them with zeros. For example: deriving + key from `scrypt(password, salt)` where password and salt are strings +- Input from a file will stay in file buffers +- Input / output will be re-used multiple times in application which means it could stay in memory +- `await anything()` will always write all internal variables (including numbers) + to memory. With async functions / Promises there are no guarantees when the code + chunk would be executed. Which means attacker can have plenty of time to read data from memory +- There is no way to guarantee anything about zeroing sensitive data without + complex tests-suite which will dump process memory and verify that there is + no sensitive data left. For JS it means testing all browsers (incl. mobile), + which is complex. And of course it will be useless without using the same + test-suite in the actual application that consumes the library + +### Supply chain security + +- **Commits** are signed with PGP keys to prevent forgery. Be sure to verify the commit signatures +- **Releases** are made transparently through token-less GitHub CI and Trusted Publishing. Be sure to verify the [provenance logs](https://docs.npmjs.com/generating-provenance-statements) for authenticity. +- **Rare releasing** is practiced to minimize the need for re-audits by end-users. +- **Dependencies** are minimized and strictly pinned to reduce supply-chain risk. + - We use as few dependencies as possible. + - Version ranges are locked, and changes are checked with npm-diff. +- **Dev dependencies** are excluded from end-user installs; they’re only used for development and build steps. + +For this package, there are 0 dependencies; and a few dev dependencies: + +- jsbt contains helpers for building, benchmarking & testing secure JS apps. It is developed by the same author +- prettier, fast-check and typescript are used for code quality / test generation / ts compilation + +### Randomness + +We rely on the built-in +[`crypto.getRandomValues`](https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues), +which is considered a cryptographically secure PRNG. + +Browsers have had weaknesses in the past - and could again - but implementing a userspace CSPRNG is even worse, as there’s no reliable userspace source of high-quality entropy. + +### Quantum computers + +Cryptographically relevant quantum computer, if built, will allow to +utilize Grover's algorithm to break hashes in 2^n/2 operations, instead of 2^n. + +This means SHA256 should be replaced with SHA512, SHA3-256 with SHA3-512, SHAKE128 with SHAKE256 etc. + +Australian ASD prohibits SHA256 and similar hashes [after 2030](https://www.cyber.gov.au/resources-business-and-government/essential-cyber-security/ism/cyber-security-guidelines/guidelines-cryptography). + +## Upgrading + +Supported node.js versions: + +- v2: v20.19+ (ESM-only) +- v1: v14.21+ (ESM & CJS) + +v2.0 changelog: + +- The package is now ESM-only. ESM can finally be loaded from common.js on node v20.19+ +- `.js` extension must be used for all modules + - Old: `@noble/hashes/sha3` + - New: `@noble/hashes/sha3.js` + - This simplifies working in browsers natively without transpilers +- Only allow Uint8Array as hash inputs, prohibit `string` + - Strict validation checks improve security + - To replicate previous behavior, use `utils.utf8ToBytes` +- Rename / remove some modules for consistency. Previously, sha384 resided in sha512, which was weird + - `sha256`, `sha512` => `sha2.js` (consistent with `sha3.js`) + - `blake2b`, `blake2s` => `blake2.js` (consistent with `blake3.js`, `blake1.js`) + - `ripemd160`, `sha1`, `md5` => `legacy.js` (all low-security hashes are there) + - `_assert` => `utils.js` + - `crypto` internal module got removed: use built-in WebCrypto instead +- Improve typescript types & option autocomplete +- Bump compilation target from es2020 to es2022 + +## Contributing & testing + +`test/misc` directory contains implementations of loop unrolling and md5. + +- `npm install && npm run build && npm test` will build the code and run tests. +- `npm run lint` / `npm run format` will run linter / fix linter issues. +- `npm run bench` will run benchmarks +- `npm run build:release` will build single file +- There is **additional** 20-min DoS test `npm run test:dos` and 2-hour multicore test `npm run test:slow`. + See [our approach to testing](./test/README.md) + +Some hashes are outside of scope of the library: +- [Pedersen in micro-zk-proofs](https://github.com/paulmillr/micro-zk-proofs/blob/1ed5ce1253583b2e540eef7f3477fb52bf5344ff/src/pedersen.ts) +- [Poseidon in noble-curves](https://github.com/paulmillr/noble-curves/blob/3d124dd3ecec8b6634cc0b2ba1c183aded5304f9/src/abstract/poseidon.ts) +- [Poly1305 & GHash in noble-ciphers](https://github.com/paulmillr/noble-ciphers) + +See [paulmillr.com/noble](https://paulmillr.com/noble/) for useful resources, articles, documentation and demos related to the library. + +## Speed + +```sh +npm run bench +``` + +Benchmarks measured on Apple M4. If you need truly exemplar performance, switch to [awasm-noble](https://github.com/paulmillr/awasm-noble). + +``` +# 32B +sha256 x 2,016,129 ops/sec @ 496ns/op +sha512 x 740,740 ops/sec @ 1μs/op +sha3_256 x 287,686 ops/sec @ 3μs/op +sha3_512 x 288,267 ops/sec @ 3μs/op +k12 x 476,190 ops/sec @ 2μs/op +blake2b x 410,340 ops/sec @ 2μs/op +blake2s x 942,507 ops/sec @ 1μs/op +blake3 x 1,006,036 ops/sec @ 994ns/op +ripemd160 x 1,410,437 ops/sec @ 709ns/op +md5 x 1,663,893 ops/sec @ 601ns/op +sha1 x 1,589,825 ops/sec @ 629ns/op + +# 1MB +sha256 x 331 ops/sec @ 3ms/op +sha512 x 128 ops/sec @ 7ms/op +sha3_256 x 39 ops/sec @ 25ms/op +sha3_512 x 21 ops/sec @ 46ms/op +kt128 x 91 ops/sec @ 10ms/op +kt256 x 75 ops/sec @ 13ms/op +turboshake128 x 93 ops/sec @ 10ms/op +blake256 x 57 ops/sec @ 17ms/op +blake2b x 61 ops/sec @ 16ms/op +blake2s x 78 ops/sec @ 12ms/op +blake3 x 95 ops/sec @ 10ms/op +ripemd160 x 177 ops/sec @ 5ms/op +md5 x 250 ops/sec @ 3ms/op +sha1 x 416 ops/sec @ 2ms/op + +# MAC +hmac(sha256) x 599,880 ops/sec @ 1μs/op +hmac(sha512) x 197,122 ops/sec @ 5μs/op +kmac256 x 87,981 ops/sec @ 11μs/op +blake3(key) x 796,812 ops/sec @ 1μs/op + +# KDF +hkdf(sha256) x 259,942 ops/sec @ 3μs/op +blake3(context) x 424,808 ops/sec @ 2μs/op +pbkdf2(sha256, c: 2 ** 18) x 5 ops/sec @ 197ms/op +pbkdf2(sha512, c: 2 ** 18) x 1 ops/sec @ 630ms/op +scrypt(n: 2 ** 18, r: 8, p: 1) x 2 ops/sec @ 400ms/op +argon2id(t: 1, m: 256MB) 2881ms +``` + +The library could be 3x faster by utilizing loop unrolling. It isn't used because +unrolling a) would increase bundle size b) make lib un-readable c) current perf is "fast enough" +for most use-cases. + +## License + +The MIT License (MIT) + +Copyright (c) 2022 Paul Miller [(https://paulmillr.com)](https://paulmillr.com) + +See LICENSE file. diff --git a/node_modules/@noble/hashes/_blake.d.ts b/node_modules/@noble/hashes/_blake.d.ts new file mode 100644 index 0000000..e509cf5 --- /dev/null +++ b/node_modules/@noble/hashes/_blake.d.ts @@ -0,0 +1,21 @@ +/** + * Internal helpers for blake hash. + * @module + */ +import { type TRet } from './utils.ts'; +/** + * Internal blake permutation table. + * Rows `0..9` serve BLAKE2s, rows `0..11` serve BLAKE2b with `10..11 = 0..1`, and Blake1 also + * reuses the later rows shown below. Blake1 expands rounds `10..15` as `SIGMA[i % 10]`, so rows + * `10..15` intentionally repeat rows `0..5` for the 14-round (256) and 16-round (512) variants. + */ +export declare const BSIGMA: TRet; +export type Num4 = { + a: number; + b: number; + c: number; + d: number; +}; +export declare function G1s(a: number, b: number, c: number, d: number, x: number): Num4; +export declare function G2s(a: number, b: number, c: number, d: number, x: number): Num4; +//# sourceMappingURL=_blake.d.ts.map \ No newline at end of file diff --git a/node_modules/@noble/hashes/_blake.d.ts.map b/node_modules/@noble/hashes/_blake.d.ts.map new file mode 100644 index 0000000..c7de007 --- /dev/null +++ b/node_modules/@noble/hashes/_blake.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"_blake.d.ts","sourceRoot":"","sources":["src/_blake.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAQ,KAAK,IAAI,EAAE,MAAM,YAAY,CAAC;AAE7C;;;;;GAKG;AAEH,eAAO,MAAM,MAAM,EAAE,IAAI,CAAC,UAAU,CAkBlC,CAAC;AAGH,MAAM,MAAM,IAAI,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;CAAE,CAAC;AAKnE,wBAAgB,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAM/E;AAKD,wBAAgB,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAM/E"} \ No newline at end of file diff --git a/node_modules/@noble/hashes/_blake.js b/node_modules/@noble/hashes/_blake.js new file mode 100644 index 0000000..23a11c6 --- /dev/null +++ b/node_modules/@noble/hashes/_blake.js @@ -0,0 +1,52 @@ +/** + * Internal helpers for blake hash. + * @module + */ +import { rotr } from "./utils.js"; +/** + * Internal blake permutation table. + * Rows `0..9` serve BLAKE2s, rows `0..11` serve BLAKE2b with `10..11 = 0..1`, and Blake1 also + * reuses the later rows shown below. Blake1 expands rounds `10..15` as `SIGMA[i % 10]`, so rows + * `10..15` intentionally repeat rows `0..5` for the 14-round (256) and 16-round (512) variants. + */ +// prettier-ignore +export const BSIGMA = /* @__PURE__ */ Uint8Array.from([ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3, + 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4, + 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8, + 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13, + 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9, + 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11, + 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10, + 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5, + 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3, + // Blake1, unused in others + 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4, + 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8, + 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13, + 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9, +]); +// 32-bit / BLAKE2s first half of G, with the fixed `(16, 12)` rotation pair. +// Parameter `x` is the RFC 7693 first-half message word, or Blake1's pre-mixed +// `m[sigma[r][2i]] ^ u[sigma[r][2i+1]]` addend in the 32-bit path. +export function G1s(a, b, c, d, x) { + a = (a + b + x) | 0; + d = rotr(d ^ a, 16); + c = (c + d) | 0; + b = rotr(b ^ c, 12); + return { a, b, c, d }; +} +// 32-bit / BLAKE2s second half of G. +// Parameter `x` is the RFC 7693 second-half (`y`) message word, or Blake1's pre-mixed +// `m[sigma[r][2i + 1]] ^ u[sigma[r][2i]]` addend in the 32-bit path. +export function G2s(a, b, c, d, x) { + a = (a + b + x) | 0; + d = rotr(d ^ a, 8); + c = (c + d) | 0; + b = rotr(b ^ c, 7); + return { a, b, c, d }; +} +//# sourceMappingURL=_blake.js.map \ No newline at end of file diff --git a/node_modules/@noble/hashes/_blake.js.map b/node_modules/@noble/hashes/_blake.js.map new file mode 100644 index 0000000..1869f1b --- /dev/null +++ b/node_modules/@noble/hashes/_blake.js.map @@ -0,0 +1 @@ +{"version":3,"file":"_blake.js","sourceRoot":"","sources":["src/_blake.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,IAAI,EAAa,MAAM,YAAY,CAAC;AAE7C;;;;;GAKG;AACH,kBAAkB;AAClB,MAAM,CAAC,MAAM,MAAM,GAAqB,eAAe,CAAC,UAAU,CAAC,IAAI,CAAC;IACtE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE;IACpD,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;IACpD,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;IACpD,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC;IACpD,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE;IACpD,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC;IACpD,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE;IACpD,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE;IACpD,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC;IACpD,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;IACpD,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE;IACpD,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;IACpD,2BAA2B;IAC3B,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;IACpD,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC;IACpD,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE;IACpD,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC;CACrD,CAAC,CAAC;AAKH,6EAA6E;AAC7E,+EAA+E;AAC/E,mEAAmE;AACnE,MAAM,UAAU,GAAG,CAAC,CAAS,EAAE,CAAS,EAAE,CAAS,EAAE,CAAS,EAAE,CAAS;IACvE,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;IACpB,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;IACpB,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;IAChB,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;IACpB,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;AACxB,CAAC;AAED,qCAAqC;AACrC,sFAAsF;AACtF,qEAAqE;AACrE,MAAM,UAAU,GAAG,CAAC,CAAS,EAAE,CAAS,EAAE,CAAS,EAAE,CAAS,EAAE,CAAS;IACvE,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;IACpB,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IACnB,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;IAChB,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IACnB,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;AACxB,CAAC"} \ No newline at end of file diff --git a/node_modules/@noble/hashes/_md.d.ts b/node_modules/@noble/hashes/_md.d.ts new file mode 100644 index 0000000..44b0272 --- /dev/null +++ b/node_modules/@noble/hashes/_md.d.ts @@ -0,0 +1,99 @@ +/** + * Internal Merkle-Damgard hash utils. + * @module + */ +import { type Hash, type TArg, type TRet } from './utils.ts'; +/** + * Shared 32-bit conditional boolean primitive reused by SHA-256, SHA-1, and MD5 `F`. + * Returns bits from `b` when `a` is set, otherwise from `c`. + * The XOR form is equivalent to MD5's `F(X,Y,Z) = XY v not(X)Z` because the masked terms never + * set the same bit. + * @param a - selector word + * @param b - word chosen when selector bit is set + * @param c - word chosen when selector bit is clear + * @returns Mixed 32-bit word. + * @example + * Combine three words with the shared 32-bit choice primitive. + * ```ts + * Chi(0xffffffff, 0x12345678, 0x87654321); + * ``` + */ +export declare function Chi(a: number, b: number, c: number): number; +/** + * Shared 32-bit majority primitive reused by SHA-256 and SHA-1. + * Returns bits shared by at least two inputs. + * @param a - first input word + * @param b - second input word + * @param c - third input word + * @returns Mixed 32-bit word. + * @example + * Combine three words with the shared 32-bit majority primitive. + * ```ts + * Maj(0xffffffff, 0x12345678, 0x87654321); + * ``` + */ +export declare function Maj(a: number, b: number, c: number): number; +/** + * Merkle-Damgard hash construction base class. + * Could be used to create MD5, RIPEMD, SHA1, SHA2. + * Accepts only byte-aligned `Uint8Array` input, even when the underlying spec describes bit + * strings with partial-byte tails. + * @param blockLen - internal block size in bytes + * @param outputLen - digest size in bytes + * @param padOffset - trailing length field size in bytes + * @param isLE - whether length and state words are encoded in little-endian + * @example + * Use a concrete subclass to get the shared Merkle-Damgard update/digest flow. + * ```ts + * import { _SHA1 } from '@noble/hashes/legacy.js'; + * const hash = new _SHA1(); + * hash.update(new Uint8Array([97, 98, 99])); + * hash.digest(); + * ``` + */ +export declare abstract class HashMD> implements Hash { + protected abstract process(buf: DataView, offset: number): void; + protected abstract get(): number[]; + protected abstract set(...args: number[]): void; + abstract destroy(): void; + protected abstract roundClean(): void; + readonly blockLen: number; + readonly outputLen: number; + readonly canXOF = false; + readonly padOffset: number; + readonly isLE: boolean; + protected buffer: Uint8Array; + protected view: DataView; + protected finished: boolean; + protected length: number; + protected pos: number; + protected destroyed: boolean; + constructor(blockLen: number, outputLen: number, padOffset: number, isLE: boolean); + update(data: TArg): this; + digestInto(out: TArg): void; + digest(): TRet; + _cloneInto(to?: T): T; + clone(): T; +} +/** + * Initial SHA-2 state: fractional parts of square roots of first 16 primes 2..53. + * Check out `test/misc/sha2-gen-iv.js` for recomputation guide. + */ +/** Initial SHA256 state from RFC 6234 §6.1: the first 32 bits of the fractional parts of the + * square roots of the first eight prime numbers. Exported as a shared table; callers must treat + * it as read-only because constructors copy words from it by index. */ +export declare const SHA256_IV: TRet; +/** Initial SHA224 state `H(0)` from RFC 6234 §6.1. Exported as a shared table; callers must + * treat it as read-only because constructors copy words from it by index. */ +export declare const SHA224_IV: TRet; +/** Initial SHA384 state from RFC 6234 §6.3: eight RFC 64-bit `H(0)` words stored as sixteen + * big-endian 32-bit halves. Derived from the fractional parts of the square roots of the ninth + * through sixteenth prime numbers. Exported as a shared table; callers must treat it as read-only + * because constructors copy halves from it by index. */ +export declare const SHA384_IV: TRet; +/** Initial SHA512 state from RFC 6234 §6.3: eight RFC 64-bit `H(0)` words stored as sixteen + * big-endian 32-bit halves. Derived from the fractional parts of the square roots of the first + * eight prime numbers. Exported as a shared table; callers must treat it as read-only because + * constructors copy halves from it by index. */ +export declare const SHA512_IV: TRet; +//# sourceMappingURL=_md.d.ts.map \ No newline at end of file diff --git a/node_modules/@noble/hashes/_md.d.ts.map b/node_modules/@noble/hashes/_md.d.ts.map new file mode 100644 index 0000000..0d42283 --- /dev/null +++ b/node_modules/@noble/hashes/_md.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"_md.d.ts","sourceRoot":"","sources":["src/_md.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAML,KAAK,IAAI,EACT,KAAK,IAAI,EACT,KAAK,IAAI,EACV,MAAM,YAAY,CAAC;AAEpB;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,8BAAsB,MAAM,CAAC,CAAC,SAAS,MAAM,CAAC,CAAC,CAAC,CAAE,YAAW,IAAI,CAAC,CAAC,CAAC;IAGlE,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAC/D,SAAS,CAAC,QAAQ,CAAC,GAAG,IAAI,MAAM,EAAE;IAClC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI;IAC/C,QAAQ,CAAC,OAAO,IAAI,IAAI;IACxB,SAAS,CAAC,QAAQ,CAAC,UAAU,IAAI,IAAI;IAErC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,SAAS;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAGvB,SAAS,CAAC,MAAM,EAAE,UAAU,CAAC;IAC7B,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC;IACzB,SAAS,CAAC,QAAQ,UAAS;IAC3B,SAAS,CAAC,MAAM,SAAK;IACrB,SAAS,CAAC,GAAG,SAAK;IAClB,SAAS,CAAC,SAAS,UAAS;gBAEhB,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO;IAQjF,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,GAAG,IAAI;IA0BpC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,GAAG,IAAI;IAkCvC,MAAM,IAAI,IAAI,CAAC,UAAU,CAAC;IAS1B,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC;IAarB,KAAK,IAAI,CAAC;CAGX;AAED;;;GAGG;AAEH;;uEAEuE;AACvE,eAAO,MAAM,SAAS,EAAE,IAAI,CAAC,WAAW,CAEtC,CAAC;AAEH;6EAC6E;AAC7E,eAAO,MAAM,SAAS,EAAE,IAAI,CAAC,WAAW,CAEtC,CAAC;AAEH;;;wDAGwD;AACxD,eAAO,MAAM,SAAS,EAAE,IAAI,CAAC,WAAW,CAGtC,CAAC;AAEH;;;gDAGgD;AAChD,eAAO,MAAM,SAAS,EAAE,IAAI,CAAC,WAAW,CAGtC,CAAC"} \ No newline at end of file diff --git a/node_modules/@noble/hashes/_md.js b/node_modules/@noble/hashes/_md.js new file mode 100644 index 0000000..0fda375 --- /dev/null +++ b/node_modules/@noble/hashes/_md.js @@ -0,0 +1,202 @@ +/** + * Internal Merkle-Damgard hash utils. + * @module + */ +import { abytes, aexists, aoutput, clean, createView, } from "./utils.js"; +/** + * Shared 32-bit conditional boolean primitive reused by SHA-256, SHA-1, and MD5 `F`. + * Returns bits from `b` when `a` is set, otherwise from `c`. + * The XOR form is equivalent to MD5's `F(X,Y,Z) = XY v not(X)Z` because the masked terms never + * set the same bit. + * @param a - selector word + * @param b - word chosen when selector bit is set + * @param c - word chosen when selector bit is clear + * @returns Mixed 32-bit word. + * @example + * Combine three words with the shared 32-bit choice primitive. + * ```ts + * Chi(0xffffffff, 0x12345678, 0x87654321); + * ``` + */ +export function Chi(a, b, c) { + return (a & b) ^ (~a & c); +} +/** + * Shared 32-bit majority primitive reused by SHA-256 and SHA-1. + * Returns bits shared by at least two inputs. + * @param a - first input word + * @param b - second input word + * @param c - third input word + * @returns Mixed 32-bit word. + * @example + * Combine three words with the shared 32-bit majority primitive. + * ```ts + * Maj(0xffffffff, 0x12345678, 0x87654321); + * ``` + */ +export function Maj(a, b, c) { + return (a & b) ^ (a & c) ^ (b & c); +} +/** + * Merkle-Damgard hash construction base class. + * Could be used to create MD5, RIPEMD, SHA1, SHA2. + * Accepts only byte-aligned `Uint8Array` input, even when the underlying spec describes bit + * strings with partial-byte tails. + * @param blockLen - internal block size in bytes + * @param outputLen - digest size in bytes + * @param padOffset - trailing length field size in bytes + * @param isLE - whether length and state words are encoded in little-endian + * @example + * Use a concrete subclass to get the shared Merkle-Damgard update/digest flow. + * ```ts + * import { _SHA1 } from '@noble/hashes/legacy.js'; + * const hash = new _SHA1(); + * hash.update(new Uint8Array([97, 98, 99])); + * hash.digest(); + * ``` + */ +export class HashMD { + blockLen; + outputLen; + canXOF = false; + padOffset; + isLE; + // For partial updates less than block size + buffer; + view; + finished = false; + length = 0; + pos = 0; + destroyed = false; + constructor(blockLen, outputLen, padOffset, isLE) { + this.blockLen = blockLen; + this.outputLen = outputLen; + this.padOffset = padOffset; + this.isLE = isLE; + this.buffer = new Uint8Array(blockLen); + this.view = createView(this.buffer); + } + update(data) { + aexists(this); + abytes(data); + const { view, buffer, blockLen } = this; + const len = data.length; + for (let pos = 0; pos < len;) { + const take = Math.min(blockLen - this.pos, len - pos); + // Fast path only when there is no buffered partial block: `take === blockLen` implies + // `this.pos === 0`, so we can process full blocks directly from the input view. + if (take === blockLen) { + const dataView = createView(data); + for (; blockLen <= len - pos; pos += blockLen) + this.process(dataView, pos); + continue; + } + buffer.set(data.subarray(pos, pos + take), this.pos); + this.pos += take; + pos += take; + if (this.pos === blockLen) { + this.process(view, 0); + this.pos = 0; + } + } + this.length += data.length; + this.roundClean(); + return this; + } + digestInto(out) { + aexists(this); + aoutput(out, this); + this.finished = true; + // Padding + // We can avoid allocation of buffer for padding completely if it + // was previously not allocated here. But it won't change performance. + const { buffer, view, blockLen, isLE } = this; + let { pos } = this; + // append the bit '1' to the message + buffer[pos++] = 0b10000000; + clean(this.buffer.subarray(pos)); + // we have less than padOffset left in buffer, so we cannot put length in + // current block, need process it and pad again + if (this.padOffset > blockLen - pos) { + this.process(view, 0); + pos = 0; + } + // Pad until full block byte with zeros + for (let i = pos; i < blockLen; i++) + buffer[i] = 0; + // `padOffset` reserves the whole length field. For SHA-384/512 the high 64 bits stay zero from + // the padding fill above, and JS will overflow before user input can make that half non-zero. + // So we only need to write the low 64 bits here. + view.setBigUint64(blockLen - 8, BigInt(this.length * 8), isLE); + this.process(view, 0); + const oview = createView(out); + const len = this.outputLen; + // NOTE: we do division by 4 later, which must be fused in single op with modulo by JIT + if (len % 4) + throw new Error('_sha2: outputLen must be aligned to 32bit'); + const outLen = len / 4; + const state = this.get(); + if (outLen > state.length) + throw new Error('_sha2: outputLen bigger than state'); + for (let i = 0; i < outLen; i++) + oview.setUint32(4 * i, state[i], isLE); + } + digest() { + const { buffer, outputLen } = this; + this.digestInto(buffer); + // Copy before destroy(): subclasses wipe `buffer` during cleanup, but `digest()` must return + // fresh bytes to the caller. + const res = buffer.slice(0, outputLen); + this.destroy(); + return res; + } + _cloneInto(to) { + to ||= new this.constructor(); + to.set(...this.get()); + const { blockLen, buffer, length, finished, destroyed, pos } = this; + to.destroyed = destroyed; + to.finished = finished; + to.length = length; + to.pos = pos; + // Only partial-block bytes need copying: when `length % blockLen === 0`, `pos === 0` and + // later `update()` / `digestInto()` overwrite `to.buffer` from the start before reading it. + if (length % blockLen) + to.buffer.set(buffer); + return to; + } + clone() { + return this._cloneInto(); + } +} +/** + * Initial SHA-2 state: fractional parts of square roots of first 16 primes 2..53. + * Check out `test/misc/sha2-gen-iv.js` for recomputation guide. + */ +/** Initial SHA256 state from RFC 6234 §6.1: the first 32 bits of the fractional parts of the + * square roots of the first eight prime numbers. Exported as a shared table; callers must treat + * it as read-only because constructors copy words from it by index. */ +export const SHA256_IV = /* @__PURE__ */ Uint32Array.from([ + 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19, +]); +/** Initial SHA224 state `H(0)` from RFC 6234 §6.1. Exported as a shared table; callers must + * treat it as read-only because constructors copy words from it by index. */ +export const SHA224_IV = /* @__PURE__ */ Uint32Array.from([ + 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4, +]); +/** Initial SHA384 state from RFC 6234 §6.3: eight RFC 64-bit `H(0)` words stored as sixteen + * big-endian 32-bit halves. Derived from the fractional parts of the square roots of the ninth + * through sixteenth prime numbers. Exported as a shared table; callers must treat it as read-only + * because constructors copy halves from it by index. */ +export const SHA384_IV = /* @__PURE__ */ Uint32Array.from([ + 0xcbbb9d5d, 0xc1059ed8, 0x629a292a, 0x367cd507, 0x9159015a, 0x3070dd17, 0x152fecd8, 0xf70e5939, + 0x67332667, 0xffc00b31, 0x8eb44a87, 0x68581511, 0xdb0c2e0d, 0x64f98fa7, 0x47b5481d, 0xbefa4fa4, +]); +/** Initial SHA512 state from RFC 6234 §6.3: eight RFC 64-bit `H(0)` words stored as sixteen + * big-endian 32-bit halves. Derived from the fractional parts of the square roots of the first + * eight prime numbers. Exported as a shared table; callers must treat it as read-only because + * constructors copy halves from it by index. */ +export const SHA512_IV = /* @__PURE__ */ Uint32Array.from([ + 0x6a09e667, 0xf3bcc908, 0xbb67ae85, 0x84caa73b, 0x3c6ef372, 0xfe94f82b, 0xa54ff53a, 0x5f1d36f1, + 0x510e527f, 0xade682d1, 0x9b05688c, 0x2b3e6c1f, 0x1f83d9ab, 0xfb41bd6b, 0x5be0cd19, 0x137e2179, +]); +//# sourceMappingURL=_md.js.map \ No newline at end of file diff --git a/node_modules/@noble/hashes/_md.js.map b/node_modules/@noble/hashes/_md.js.map new file mode 100644 index 0000000..9f2e86c --- /dev/null +++ b/node_modules/@noble/hashes/_md.js.map @@ -0,0 +1 @@ +{"version":3,"file":"_md.js","sourceRoot":"","sources":["src/_md.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@noble/hashes/_u64.d.ts b/node_modules/@noble/hashes/_u64.d.ts new file mode 100644 index 0000000..306b1c5 --- /dev/null +++ b/node_modules/@noble/hashes/_u64.d.ts @@ -0,0 +1,63 @@ +/** + * Internal helpers for u64. + * BigUint64Array is too slow as per 2026, so we implement it using + * Uint32Array. + * @privateRemarks TODO: re-check {@link https://issues.chromium.org/issues/42212588} + * @module + */ +import type { TRet } from './utils.ts'; +declare function fromBig(n: bigint, le?: boolean): { + h: number; + l: number; +}; +declare function split(lst: bigint[], le?: boolean): TRet; +declare const toBig: (h: number, l: number) => bigint; +declare const shrSH: (h: number, _l: number, s: number) => number; +declare const shrSL: (h: number, l: number, s: number) => number; +declare const rotrSH: (h: number, l: number, s: number) => number; +declare const rotrSL: (h: number, l: number, s: number) => number; +declare const rotrBH: (h: number, l: number, s: number) => number; +declare const rotrBL: (h: number, l: number, s: number) => number; +declare const rotr32H: (_h: number, l: number) => number; +declare const rotr32L: (h: number, _l: number) => number; +declare const rotlSH: (h: number, l: number, s: number) => number; +declare const rotlSL: (h: number, l: number, s: number) => number; +declare const rotlBH: (h: number, l: number, s: number) => number; +declare const rotlBL: (h: number, l: number, s: number) => number; +declare function add(Ah: number, Al: number, Bh: number, Bl: number): { + h: number; + l: number; +}; +declare const add3L: (Al: number, Bl: number, Cl: number) => number; +declare const add3H: (low: number, Ah: number, Bh: number, Ch: number) => number; +declare const add4L: (Al: number, Bl: number, Cl: number, Dl: number) => number; +declare const add4H: (low: number, Ah: number, Bh: number, Ch: number, Dh: number) => number; +declare const add5L: (Al: number, Bl: number, Cl: number, Dl: number, El: number) => number; +declare const add5H: (low: number, Ah: number, Bh: number, Ch: number, Dh: number, Eh: number) => number; +export { add, add3H, add3L, add4H, add4L, add5H, add5L, fromBig, rotlBH, rotlBL, rotlSH, rotlSL, rotr32H, rotr32L, rotrBH, rotrBL, rotrSH, rotrSL, shrSH, shrSL, split, toBig }; +declare const u64: { + fromBig: typeof fromBig; + split: typeof split; + toBig: (h: number, l: number) => bigint; + shrSH: (h: number, _l: number, s: number) => number; + shrSL: (h: number, l: number, s: number) => number; + rotrSH: (h: number, l: number, s: number) => number; + rotrSL: (h: number, l: number, s: number) => number; + rotrBH: (h: number, l: number, s: number) => number; + rotrBL: (h: number, l: number, s: number) => number; + rotr32H: (_h: number, l: number) => number; + rotr32L: (h: number, _l: number) => number; + rotlSH: (h: number, l: number, s: number) => number; + rotlSL: (h: number, l: number, s: number) => number; + rotlBH: (h: number, l: number, s: number) => number; + rotlBL: (h: number, l: number, s: number) => number; + add: typeof add; + add3L: (Al: number, Bl: number, Cl: number) => number; + add3H: (low: number, Ah: number, Bh: number, Ch: number) => number; + add4L: (Al: number, Bl: number, Cl: number, Dl: number) => number; + add4H: (low: number, Ah: number, Bh: number, Ch: number, Dh: number) => number; + add5H: (low: number, Ah: number, Bh: number, Ch: number, Dh: number, Eh: number) => number; + add5L: (Al: number, Bl: number, Cl: number, Dl: number, El: number) => number; +}; +export default u64; +//# sourceMappingURL=_u64.d.ts.map \ No newline at end of file diff --git a/node_modules/@noble/hashes/_u64.d.ts.map b/node_modules/@noble/hashes/_u64.d.ts.map new file mode 100644 index 0000000..6fa63a4 --- /dev/null +++ b/node_modules/@noble/hashes/_u64.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"_u64.d.ts","sourceRoot":"","sources":["src/_u64.ts"],"names":[],"mappings":"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IAAC,KAAK,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAAC,KAAK,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAAC,KAAK,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAAC,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAAC,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAAC,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAAC,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAAC,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAAC,OAAO,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,MAAM,CAAC;IAAC,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAAC,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAAC,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAAC,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAAC,GAAG,EAAE,OAAO,GAAG,CAAC;IAAC,KAAK,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,MAAM,CAAC;IAAC,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,MAAM,CAAC;IAAC,KAAK,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,MAAM,CAAC;IAAC,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,MAAM,CAAC;IAAC,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,MAAM,CAAC;IAAC,KAAK,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,MAAM,CAAC;CAOrpC,CAAC;AAEF,eAAe,GAAG,CAAC"} \ No newline at end of file diff --git a/node_modules/@noble/hashes/_u64.js b/node_modules/@noble/hashes/_u64.js new file mode 100644 index 0000000..e66551e --- /dev/null +++ b/node_modules/@noble/hashes/_u64.js @@ -0,0 +1,84 @@ +const U32_MASK64 = /* @__PURE__ */ BigInt(2 ** 32 - 1); +const _32n = /* @__PURE__ */ BigInt(32); +// Split bigint into two 32-bit halves. With `le=true`, returned fields become `{ h: low, l: high +// }` to match little-endian word order rather than the property names. +function fromBig(n, le = false) { + if (le) + return { h: Number(n & U32_MASK64), l: Number((n >> _32n) & U32_MASK64) }; + return { h: Number((n >> _32n) & U32_MASK64) | 0, l: Number(n & U32_MASK64) | 0 }; +} +// Split bigint list into `[highWords, lowWords]` when `le=false`; with `le=true`, the first array +// holds the low halves because `fromBig(...)` swaps the semantic meaning of `h` and `l`. +function split(lst, le = false) { + const len = lst.length; + let Ah = new Uint32Array(len); + let Al = new Uint32Array(len); + for (let i = 0; i < len; i++) { + const { h, l } = fromBig(lst[i], le); + [Ah[i], Al[i]] = [h, l]; + } + return [Ah, Al]; +} +// Combine explicit `(high, low)` 32-bit halves into a bigint; `>>> 0` normalizes signed JS +// bitwise results back to uint32 first, and little-endian callers must swap. +const toBig = (h, l) => (BigInt(h >>> 0) << _32n) | BigInt(l >>> 0); +// High 32-bit half of a 64-bit logical right shift for `s` in `0..31`. +const shrSH = (h, _l, s) => h >>> s; +// Low 32-bit half of a 64-bit logical right shift, valid for `s` in `1..31`. +const shrSL = (h, l, s) => (h << (32 - s)) | (l >>> s); +// High 32-bit half of a 64-bit right rotate, valid for `s` in `1..31`. +const rotrSH = (h, l, s) => (h >>> s) | (l << (32 - s)); +// Low 32-bit half of a 64-bit right rotate, valid for `s` in `1..31`. +const rotrSL = (h, l, s) => (h << (32 - s)) | (l >>> s); +// High 32-bit half of a 64-bit right rotate, valid for `s` in `33..63`; `32` uses `rotr32*`. +const rotrBH = (h, l, s) => (h << (64 - s)) | (l >>> (s - 32)); +// Low 32-bit half of a 64-bit right rotate, valid for `s` in `33..63`; `32` uses `rotr32*`. +const rotrBL = (h, l, s) => (h >>> (s - 32)) | (l << (64 - s)); +// High 32-bit half of a 64-bit right rotate for `s === 32`; this is just the swapped low half. +const rotr32H = (_h, l) => l; +// Low 32-bit half of a 64-bit right rotate for `s === 32`; this is just the swapped high half. +const rotr32L = (h, _l) => h; +// High 32-bit half of a 64-bit left rotate, valid for `s` in `1..31`. +const rotlSH = (h, l, s) => (h << s) | (l >>> (32 - s)); +// Low 32-bit half of a 64-bit left rotate, valid for `s` in `1..31`. +const rotlSL = (h, l, s) => (l << s) | (h >>> (32 - s)); +// High 32-bit half of a 64-bit left rotate, valid for `s` in `33..63`; `32` uses `rotr32*`. +const rotlBH = (h, l, s) => (l << (s - 32)) | (h >>> (64 - s)); +// Low 32-bit half of a 64-bit left rotate, valid for `s` in `33..63`; `32` uses `rotr32*`. +const rotlBL = (h, l, s) => (h << (s - 32)) | (l >>> (64 - s)); +// Add two split 64-bit words and return the split `{ h, l }` sum. +// JS uses 32-bit signed integers for bitwise operations, so we cannot simply shift the carry out +// of the low sum and instead use division. +function add(Ah, Al, Bh, Bl) { + const l = (Al >>> 0) + (Bl >>> 0); + return { h: (Ah + Bh + ((l / 2 ** 32) | 0)) | 0, l: l | 0 }; +} +// Addition with more than 2 elements +// Unmasked low-word accumulator for 3-way addition; pass the raw result into `add3H(...)`. +const add3L = (Al, Bl, Cl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0); +// High-word finalize step for 3-way addition; `low` must be the untruncated output of `add3L(...)`. +const add3H = (low, Ah, Bh, Ch) => (Ah + Bh + Ch + ((low / 2 ** 32) | 0)) | 0; +// Unmasked low-word accumulator for 4-way addition; pass the raw result into `add4H(...)`. +const add4L = (Al, Bl, Cl, Dl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0); +// High-word finalize step for 4-way addition; `low` must be the untruncated output of `add4L(...)`. +const add4H = (low, Ah, Bh, Ch, Dh) => (Ah + Bh + Ch + Dh + ((low / 2 ** 32) | 0)) | 0; +// Unmasked low-word accumulator for 5-way addition; pass the raw result into `add5H(...)`. +const add5L = (Al, Bl, Cl, Dl, El) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0) + (El >>> 0); +// High-word finalize step for 5-way addition; `low` must be the untruncated output of `add5L(...)`. +const add5H = (low, Ah, Bh, Ch, Dh, Eh) => (Ah + Bh + Ch + Dh + Eh + ((low / 2 ** 32) | 0)) | 0; +// prettier-ignore +export { add, add3H, add3L, add4H, add4L, add5H, add5L, fromBig, rotlBH, rotlBL, rotlSH, rotlSL, rotr32H, rotr32L, rotrBH, rotrBL, rotrSH, rotrSL, shrSH, shrSL, split, toBig }; +// Canonical grouped namespace for callers that prefer one object. +// Named exports stay for direct imports. +// prettier-ignore +const u64 = { + fromBig, split, toBig, + shrSH, shrSL, + rotrSH, rotrSL, rotrBH, rotrBL, + rotr32H, rotr32L, + rotlSH, rotlSL, rotlBH, rotlBL, + add, add3L, add3H, add4L, add4H, add5H, add5L, +}; +// Default export mirrors named `u64` for compatibility with object-style imports. +export default u64; +//# sourceMappingURL=_u64.js.map \ No newline at end of file diff --git a/node_modules/@noble/hashes/_u64.js.map b/node_modules/@noble/hashes/_u64.js.map new file mode 100644 index 0000000..538e533 --- /dev/null +++ b/node_modules/@noble/hashes/_u64.js.map @@ -0,0 +1 @@ +{"version":3,"file":"_u64.js","sourceRoot":"","sources":["src/_u64.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@noble/hashes/argon2.d.ts b/node_modules/@noble/hashes/argon2.d.ts new file mode 100644 index 0000000..541fdac --- /dev/null +++ b/node_modules/@noble/hashes/argon2.d.ts @@ -0,0 +1,112 @@ +import { type KDFInput, type TArg, type TRet } from './utils.ts'; +/** Argon2 cost, output, and optional secret/personalization inputs. */ +export type ArgonOpts = { + /** Time cost measured in iterations. */ + t: number; + /** Memory cost in kibibytes. */ + m: number; + /** Parallelization parameter. */ + p: number; + /** Argon2 version number. Defaults to `0x13`. */ + version?: number; + /** Optional secret key mixed into initialization. */ + key?: KDFInput; + /** Optional personalization string or bytes. */ + personalization?: KDFInput; + /** Desired output length in bytes. RFC 9106 §3.1 requires `T` in the 4..(2^32 - 1) range. */ + dkLen?: number; + /** Max scheduler block time in milliseconds for the async variants. */ + asyncTick?: number; + /** Maximum temporary memory budget in bytes. */ + maxmem?: number; + /** + * Optional progress callback invoked during long-running derivations. + * param progress - completion fraction in the `0..1` range + */ + onProgress?: (progress: number) => void; +}; +/** + * Argon2d GPU-resistant version. + * @param password - password or input key material + * @param salt - unique salt value + * @param opts - Argon2 cost and optional tuning parameters. See {@link ArgonOpts}. + * @returns Derived key bytes. + * @throws If the Argon2 input or cost parameters are invalid. {@link Error} + * @example + * Derive a key with Argon2d. + * ```ts + * argon2d('password', 'salt1234', { t: 1, m: 8, p: 1, dkLen: 32 }); + * ``` + */ +export declare const argon2d: (password: TArg, salt: TArg, opts: TArg) => TRet; +/** + * Argon2i side-channel-resistant version. + * @param password - password or input key material + * @param salt - unique salt value + * @param opts - Argon2 cost and optional tuning parameters. See {@link ArgonOpts}. + * @returns Derived key bytes. + * @throws If the Argon2 input or cost parameters are invalid. {@link Error} + * @example + * Derive a key with Argon2i. + * ```ts + * argon2i('password', 'salt1234', { t: 1, m: 8, p: 1, dkLen: 32 }); + * ``` + */ +export declare const argon2i: (password: TArg, salt: TArg, opts: TArg) => TRet; +/** + * Argon2id, combining i+d, the most popular version from RFC 9106. + * @param password - password or input key material + * @param salt - unique salt value + * @param opts - Argon2 cost and optional tuning parameters. See {@link ArgonOpts}. + * @returns Derived key bytes. + * @throws If the Argon2 input or cost parameters are invalid. {@link Error} + * @example + * Derive a key with Argon2id. + * ```ts + * argon2id('password', 'salt1234', { t: 1, m: 8, p: 1, dkLen: 32 }); + * ``` + */ +export declare const argon2id: (password: TArg, salt: TArg, opts: TArg) => TRet; +/** + * Argon2d async GPU-resistant version. + * @param password - password or input key material + * @param salt - unique salt value + * @param opts - Argon2 cost and optional tuning parameters. See {@link ArgonOpts}. + * @returns Promise resolving to derived key bytes. + * @throws If the Argon2 input or cost parameters are invalid. {@link Error} + * @example + * Derive a key with Argon2d asynchronously. + * ```ts + * await argon2dAsync('password', 'salt1234', { t: 1, m: 8, p: 1, dkLen: 32 }); + * ``` + */ +export declare const argon2dAsync: (password: TArg, salt: TArg, opts: TArg) => Promise>; +/** + * Argon2i async side-channel-resistant version. + * @param password - password or input key material + * @param salt - unique salt value + * @param opts - Argon2 cost and optional tuning parameters. See {@link ArgonOpts}. + * @returns Promise resolving to derived key bytes. + * @throws If the Argon2 input or cost parameters are invalid. {@link Error} + * @example + * Derive a key with Argon2i asynchronously. + * ```ts + * await argon2iAsync('password', 'salt1234', { t: 1, m: 8, p: 1, dkLen: 32 }); + * ``` + */ +export declare const argon2iAsync: (password: TArg, salt: TArg, opts: TArg) => Promise>; +/** + * Argon2id async, combining i+d, the most popular version from RFC 9106. + * @param password - password or input key material + * @param salt - unique salt value + * @param opts - Argon2 cost and optional tuning parameters. See {@link ArgonOpts}. + * @returns Promise resolving to derived key bytes. + * @throws If the Argon2 input or cost parameters are invalid. {@link Error} + * @example + * Derive a key with Argon2id asynchronously. + * ```ts + * await argon2idAsync('password', 'salt1234', { t: 1, m: 8, p: 1, dkLen: 32 }); + * ``` + */ +export declare const argon2idAsync: (password: TArg, salt: TArg, opts: TArg) => Promise>; +//# sourceMappingURL=argon2.d.ts.map \ No newline at end of file diff --git a/node_modules/@noble/hashes/argon2.d.ts.map b/node_modules/@noble/hashes/argon2.d.ts.map new file mode 100644 index 0000000..6d0f0d8 --- /dev/null +++ b/node_modules/@noble/hashes/argon2.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"argon2.d.ts","sourceRoot":"","sources":["src/argon2.ts"],"names":[],"mappings":"AAYA,OAAO,EASL,KAAK,QAAQ,EACb,KAAK,IAAI,EACT,KAAK,IAAI,EACV,MAAM,YAAY,CAAC;AAuLpB,uEAAuE;AACvE,MAAM,MAAM,SAAS,GAAG;IACtB,wCAAwC;IACxC,CAAC,EAAE,MAAM,CAAC;IACV,gCAAgC;IAChC,CAAC,EAAE,MAAM,CAAC;IACV,iCAAiC;IACjC,CAAC,EAAE,MAAM,CAAC;IACV,iDAAiD;IACjD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qDAAqD;IACrD,GAAG,CAAC,EAAE,QAAQ,CAAC;IACf,gDAAgD;IAChD,eAAe,CAAC,EAAE,QAAQ,CAAC;IAC3B,6FAA6F;IAC7F,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gDAAgD;IAChD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CACzC,CAAC;AA6PF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,OAAO,GAClB,UAAU,IAAI,CAAC,QAAQ,CAAC,EACxB,MAAM,IAAI,CAAC,QAAQ,CAAC,EACpB,MAAM,IAAI,CAAC,SAAS,CAAC,KACpB,IAAI,CAAC,UAAU,CAA8C,CAAC;AACjE;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,OAAO,GAClB,UAAU,IAAI,CAAC,QAAQ,CAAC,EACxB,MAAM,IAAI,CAAC,QAAQ,CAAC,EACpB,MAAM,IAAI,CAAC,SAAS,CAAC,KACpB,IAAI,CAAC,UAAU,CAA6C,CAAC;AAChE;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,QAAQ,GACnB,UAAU,IAAI,CAAC,QAAQ,CAAC,EACxB,MAAM,IAAI,CAAC,QAAQ,CAAC,EACpB,MAAM,IAAI,CAAC,SAAS,CAAC,KACpB,IAAI,CAAC,UAAU,CAA8C,CAAC;AA2EjE;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,YAAY,GACvB,UAAU,IAAI,CAAC,QAAQ,CAAC,EACxB,MAAM,IAAI,CAAC,QAAQ,CAAC,EACpB,MAAM,IAAI,CAAC,SAAS,CAAC,KACpB,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAmD,CAAC;AAC/E;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,YAAY,GACvB,UAAU,IAAI,CAAC,QAAQ,CAAC,EACxB,MAAM,IAAI,CAAC,QAAQ,CAAC,EACpB,MAAM,IAAI,CAAC,SAAS,CAAC,KACpB,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAkD,CAAC;AAC9E;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,aAAa,GACxB,UAAU,IAAI,CAAC,QAAQ,CAAC,EACxB,MAAM,IAAI,CAAC,QAAQ,CAAC,EACpB,MAAM,IAAI,CAAC,SAAS,CAAC,KACpB,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAmD,CAAC"} \ No newline at end of file diff --git a/node_modules/@noble/hashes/argon2.js b/node_modules/@noble/hashes/argon2.js new file mode 100644 index 0000000..b2fcd1f --- /dev/null +++ b/node_modules/@noble/hashes/argon2.js @@ -0,0 +1,517 @@ +/** + * Argon2 KDF from RFC 9106. Can be used to create a key from password and salt. + * We suggest to use Scrypt. JS Argon is 2-10x slower than native code because of 64-bitness: + * * argon uses uint64, but JS doesn't have fast uint64array + * * uint64 multiplication is 1/3 of time + * * `P` function would be very nice with u64, because most of value will be in registers, + * hovewer with u32 it will require 32 registers, which is too much. + * * JS arrays do slow bound checks, so reading from `A2_BUF` slows it down + * @module + */ +import { add3H, add3L, rotr32H, rotr32L, rotrBH, rotrBL, rotrSH, rotrSL } from "./_u64.js"; +import { blake2b } from "./blake2.js"; +import { anumber, clean, kdfInputToBytes, nextTick, swap32IfBE, swap8IfBE, u32, u8, } from "./utils.js"; +// RFC 9106 §3.1 type `y`: 0 = Argon2d, 1 = Argon2i, 2 = Argon2id. The numeric values are the +// spec-bound part here; the object keys are internal labels. +const AT = { Argond2d: 0, Argon2i: 1, Argon2id: 2 }; +// RFC 9106 sync points constant `SL = 4`, fixed by the design rather than exposed as a tuning knob. +const ARGON2_SYNC_POINTS = 4; +// Preserve Argon2's `LE32(len(X)) || X` encoding for omitted +// optional fields by emitting empty bytes. +const abytesOrZero = (buf, errorTitle = '') => { + if (buf === undefined) + return Uint8Array.of(); + return kdfInputToBytes(buf, errorTitle); +}; +// Unsigned `u32 * u32 = { h, l }`, returned as split 64-bit halves. +function mul(a, b) { + // Split into 16-bit limbs so each partial product stays exact under `Math.imul`. + const aL = a & 0xffff; + const aH = a >>> 16; + const bL = b & 0xffff; + const bH = b >>> 16; + const ll = Math.imul(aL, bL); + const hl = Math.imul(aH, bL); + const lh = Math.imul(aL, bH); + const hh = Math.imul(aH, bH); + const carry = (ll >>> 16) + (hl & 0xffff) + lh; + const high = (hh + (hl >>> 16) + (carry >>> 16)) | 0; + const low = (carry << 16) | (ll & 0xffff); + return { h: high, l: low }; +} +function mul2(a, b) { + // Double the split 64-bit product; carry from `l` is folded back into `h` via `l >>> 31`. + const { h, l } = mul(a, b); + return { h: ((h << 1) | (l >>> 31)) & 0xffff_ffff, l: (l << 1) & 0xffff_ffff }; +} +// BlaMka permutation for Argon2 +// `A + B + 2 * trunc(A) * trunc(B)`, where `trunc(...)` means the low 32-bit halves. +function blamka(Ah, Al, Bh, Bl) { + const { h: Ch, l: Cl } = mul2(Al, Bl); + // A + B + (2 * A * B) + const Rll = add3L(Al, Bl, Cl); + return { h: add3H(Rll, Ah, Bh, Ch), l: Rll | 0 }; +} +// Temporary block buffer. +// 1024-byte block: 256 u32 = 128 interleaved low/high halves = RFC's +// 8x8 matrix of 16-byte registers. +const A2_BUF = new Uint32Array(256); +// Quarter-round over 64-bit word indices into `A2_BUF`; each index maps to adjacent low/high u32s. +function G(a, b, c, d) { + let Al = A2_BUF[2 * a], Ah = A2_BUF[2 * a + 1]; // prettier-ignore + let Bl = A2_BUF[2 * b], Bh = A2_BUF[2 * b + 1]; // prettier-ignore + let Cl = A2_BUF[2 * c], Ch = A2_BUF[2 * c + 1]; // prettier-ignore + let Dl = A2_BUF[2 * d], Dh = A2_BUF[2 * d + 1]; // prettier-ignore + // RFC 9106 Figure 19 GB rotates by 32, 24, 16, and 63 bits after each XOR step. + ({ h: Ah, l: Al } = blamka(Ah, Al, Bh, Bl)); + ({ Dh, Dl } = { Dh: Dh ^ Ah, Dl: Dl ^ Al }); + ({ Dh, Dl } = { Dh: rotr32H(Dh, Dl), Dl: rotr32L(Dh, Dl) }); + ({ h: Ch, l: Cl } = blamka(Ch, Cl, Dh, Dl)); + ({ Bh, Bl } = { Bh: Bh ^ Ch, Bl: Bl ^ Cl }); + ({ Bh, Bl } = { Bh: rotrSH(Bh, Bl, 24), Bl: rotrSL(Bh, Bl, 24) }); + ({ h: Ah, l: Al } = blamka(Ah, Al, Bh, Bl)); + ({ Dh, Dl } = { Dh: Dh ^ Ah, Dl: Dl ^ Al }); + ({ Dh, Dl } = { Dh: rotrSH(Dh, Dl, 16), Dl: rotrSL(Dh, Dl, 16) }); + ({ h: Ch, l: Cl } = blamka(Ch, Cl, Dh, Dl)); + ({ Bh, Bl } = { Bh: Bh ^ Ch, Bl: Bl ^ Cl }); + ({ Bh, Bl } = { Bh: rotrBH(Bh, Bl, 63), Bl: rotrBL(Bh, Bl, 63) }); + ((A2_BUF[2 * a] = Al), (A2_BUF[2 * a + 1] = Ah)); + ((A2_BUF[2 * b] = Bl), (A2_BUF[2 * b + 1] = Bh)); + ((A2_BUF[2 * c] = Cl), (A2_BUF[2 * c + 1] = Ch)); + ((A2_BUF[2 * d] = Dl), (A2_BUF[2 * d + 1] = Dh)); +} +// Argon2 permutation over 16 register indices into `A2_BUF`, not the register values themselves. +// RFC 9106 Figure 17: these arguments are the 16 `v0..v15` 64-bit word +// indices inside eight 16-byte inputs, not copied word values. +// prettier-ignore +function P(v00, v01, v02, v03, v04, v05, v06, v07, v08, v09, v10, v11, v12, v13, v14, v15) { + // RFC 9106 Figure 18: first apply GB across rows, then across columns of the 8x8 register matrix. + G(v00, v04, v08, v12); + G(v01, v05, v09, v13); + G(v02, v06, v10, v14); + G(v03, v07, v11, v15); + G(v00, v05, v10, v15); + G(v01, v06, v11, v12); + G(v02, v07, v08, v13); + G(v03, v04, v09, v14); +} +function block(x, xPos, yPos, outPos, needXor) { + for (let i = 0; i < 256; i++) + A2_BUF[i] = x[xPos + i] ^ x[yPos + i]; + // rows (8 consecutive 16-register groups) + for (let i = 0; i < 128; i += 16) { + // prettier-ignore + P(i, i + 1, i + 2, i + 3, i + 4, i + 5, i + 6, i + 7, i + 8, i + 9, i + 10, i + 11, i + 12, i + 13, i + 14, i + 15); + } + // columns (8 strided 16-register groups) + for (let i = 0; i < 16; i += 2) { + // prettier-ignore + P(i, i + 1, i + 16, i + 17, i + 32, i + 33, i + 48, i + 49, i + 64, i + 65, i + 80, i + 81, i + 96, i + 97, i + 112, i + 113); + } + // RFC 9106 step 6: passes after the first XOR the old destination block into the new G(X, Y). + if (needXor) + for (let i = 0; i < 256; i++) + x[outPos + i] ^= A2_BUF[i] ^ x[xPos + i] ^ x[yPos + i]; + else + for (let i = 0; i < 256; i++) + x[outPos + i] = A2_BUF[i] ^ x[xPos + i] ^ x[yPos + i]; + clean(A2_BUF); +} +// Variable-Length Hash Function H' +// Returns bytes, not words; 1024-byte block callers explicitly reinterpret with `u32(...)`. +function Hp(A, dkLen) { + const A8 = u8(A); + const T = new Uint32Array(1); + const T8 = u8(T); + // Argon2 H' prefixes dkLen as LE32; native Uint32Array writes would serialize as BE on s390x. + T[0] = swap8IfBE(dkLen); + // Fast path + if (dkLen <= 64) + return blake2b.create({ dkLen }).update(T8).update(A8).digest(); + const out = new Uint8Array(dkLen); + let V = blake2b.create({}).update(T8).update(A8).digest(); + let pos = 0; + // RFC 9106 Figure 8: each intermediate `V_i` contributes only `W_i`, its first 32 bytes; only + // `V_{r+1}` is emitted in full at the remaining length. + out.set(V.subarray(0, 32)); + pos += 32; + // Rest blocks + for (; dkLen - pos > 64; pos += 32) { + const Vh = blake2b.create({}).update(V); + Vh.digestInto(V); + Vh.destroy(); + out.set(V.subarray(0, 32), pos); + } + // Last block + out.set(blake2b(V, { dkLen: dkLen - pos }), pos); + clean(V, T); + // H' is byte-oriented; returning `u32(out)` would silently drop dkLen % 4 tail bytes. + return out; +} +// Used only inside process block! +function indexAlpha(r, s, laneLen, segmentLen, index, randL, sameLane = false) { + // RFC 9106 §3.4.2 Figures 12-13: map `J1` / `J2` into the current lane's reference area `W`. + let area; + if (r === 0) { + if (s === 0) + area = index - 1; + else if (sameLane) + area = s * segmentLen + index - 1; + else + area = s * segmentLen + (index == 0 ? -1 : 0); + } + else if (sameLane) + area = laneLen - segmentLen + index - 1; + else + area = laneLen - segmentLen + (index == 0 ? -1 : 0); + const startPos = r !== 0 && s !== ARGON2_SYNC_POINTS - 1 ? (s + 1) * segmentLen : 0; + // RFC 9106 Figure 13: `mul(randL, randL).h` is `floor(J_1^2 / 2^32)`, and the outer high-half + // multiply computes `floor(|W| * x / 2^32)` without floating-point math. + const rel = area - 1 - mul(area, mul(randL, randL).h).h; + return (startPos + rel) % laneLen; +} +// Exclusive `2^32` sentinel used by `isU32(...)`, not the inclusive maximum u32 value. +const maxUint32 = Math.pow(2, 32); +// Validate safe JS integers in `[0, 2^32 - 1]`. +function isU32(num) { + return Number.isSafeInteger(num) && num >= 0 && num < maxUint32; +} +function argon2Opts(opts) { + const merged = { + version: 0x13, + dkLen: 32, + maxmem: maxUint32 - 1, + asyncTick: 10, + }; + // Unknown keys are copied through unchanged here and later ignored unless + // destructuring consumes them. + for (let [k, v] of Object.entries(opts)) + if (v !== undefined) + merged[k] = v; + const { dkLen, p, m, t, version, onProgress, asyncTick } = merged; + // RFC 9106 §3.1: tag length `T` MUST be an integer number of bytes from 4 to 2^32-1. + if (!isU32(dkLen) || dkLen < 4) + throw new Error('"dkLen" must be 4..'); + if (!isU32(p) || p < 1 || p >= Math.pow(2, 24)) + throw new Error('"p" must be 1..2^24'); + if (!isU32(m)) + throw new Error('"m" must be 0..2^32'); + if (!isU32(t) || t < 1) + throw new Error('"t" (iterations) must be 1..2^32'); + if (onProgress !== undefined && typeof onProgress !== 'function') + throw new Error('"progressCb" must be a function'); + anumber(asyncTick, 'asyncTick'); + /* + Memory size m MUST be an integer number of kibibytes from 8*p + to 2^(32)-1. The actual number of blocks is m', which is m + rounded down to the nearest multiple of 4*p. + */ + if (!isU32(m) || m < 8 * p) + throw new Error('"m" (memory) must be at least 8*p bytes'); + // Accept legacy `0x10` for compatibility even though RFC 9106 profiles standardize `0x13`. + if (version !== 0x10 && version !== 0x13) + throw new Error('"version" must be 0x10 or 0x13, got ' + version); + return merged; +} +function argon2Init(password, salt, type, opts) { + password = kdfInputToBytes(password, 'password'); + salt = kdfInputToBytes(salt, 'salt'); + if (!isU32(password.length)) + throw new Error('"password" must be less of length 1..4Gb'); + // RFC 9106 §3.1 only requires S <= 2^32-1 bytes and says 16 bytes is RECOMMENDED for password + // hashing; this library intentionally takes the stricter common >=8-byte salt path. + if (!isU32(salt.length) || salt.length < 8) + throw new Error('"salt" must be of length 8..4Gb'); + if (!Object.values(AT).includes(type)) + throw new Error('"type" was invalid'); + let { p, dkLen, m, t, version, key, personalization, maxmem, onProgress, asyncTick } = argon2Opts(opts); + // Validation + key = abytesOrZero(key, 'key'); + personalization = abytesOrZero(personalization, 'personalization'); + // H_0 = H^(64)(LE32(p) || LE32(T) || LE32(m) || LE32(t) || + // LE32(v) || LE32(y) || LE32(length(P)) || P || + // LE32(length(S)) || S || LE32(length(K)) || K || + // LE32(length(X)) || X) + const h = blake2b.create(); + const BUF = new Uint32Array(1); + const BUF8 = u8(BUF); + for (let item of [p, dkLen, m, t, version, type]) { + // RFC 9106 H0 encodes these scalars as LE32, so normalize the host word before exposing bytes. + BUF[0] = swap8IfBE(item); + h.update(BUF8); + } + for (let i of [password, salt, key, personalization]) { + BUF[0] = swap8IfBE(i.length); // BUF is u32 array, this is valid once normalized to LE bytes + h.update(BUF8).update(i); + } + // Reserve two extra LE32 words after the 64-byte `H_0` so Figures 3-4 can append + // `LE32(0 or 1) || LE32(i)` in place for the lane-starting blocks. + const H0 = new Uint32Array(18); + const H0_8 = u8(H0); + h.digestInto(H0_8); + // 256 u32 = 1024 (BLOCK_SIZE), fills A2_BUF on processing + // Params + const lanes = p; + // m' = 4 * p * floor (m / 4p) + const mP = 4 * p * Math.floor(m / (ARGON2_SYNC_POINTS * p)); + //q = m' / p columns + const laneLen = Math.floor(mP / p); + const segmentLen = Math.floor(laneLen / ARGON2_SYNC_POINTS); + // `maxmem` is documented in bytes; compare against the actual 1024-byte block allocation. + const memUsed = mP * 1024; + if (!isU32(maxmem)) + throw new Error('"maxmem" expected <2**32, got ' + maxmem); + if (memUsed > maxmem) + throw new Error('"maxmem" limit was hit: memUsed(mP*1024)=' + memUsed + ', maxmem=' + maxmem); + const B = new Uint32Array(memUsed / 4); + // Fill first blocks + for (let l = 0; l < p; l++) { + const i = 256 * laneLen * l; + // B[i][0] = H'^(1024)(H_0 || LE32(0) || LE32(i)) + H0[17] = swap8IfBE(l); + H0[16] = swap8IfBE(0); + B.set(swap32IfBE(u32(Hp(H0, 1024))), i); + // B[i][1] = H'^(1024)(H_0 || LE32(1) || LE32(i)) + H0[16] = swap8IfBE(1); + B.set(swap32IfBE(u32(Hp(H0, 1024))), i + 256); + } + let perBlock = () => { }; + if (onProgress) { + // The first segment of the first pass skips two preinitialized blocks per lane. + const totalBlock = t * ARGON2_SYNC_POINTS * p * segmentLen - 2 * p; + // Invoke callback if progress changes from 10.01 to 10.02 + // Allows to draw smooth progress bar on up to 8K screen + const callbackPer = Math.max(Math.floor(totalBlock / 10000), 1); + let blockCnt = 0; + perBlock = () => { + blockCnt++; + if (onProgress && (!(blockCnt % callbackPer) || blockCnt === totalBlock)) + onProgress(blockCnt / totalBlock); + }; + } + clean(BUF, H0); + return { type, mP, p, t, version, B, laneLen, lanes, segmentLen, dkLen, perBlock, asyncTick }; +} +function argon2Output(B, p, laneLen, dkLen) { + const B_final = new Uint32Array(256); + for (let l = 0; l < p; l++) + for (let j = 0; j < 256; j++) + B_final[j] ^= B[256 * (laneLen * l + laneLen - 1) + j]; + // RFC 9106 steps 7-8 feed the byte string `C` into `H'^T(C)`, so normalize the xor'ed words + // back to spec byte order before `Hp(...)` reinterprets them as bytes. + const res = Hp(swap32IfBE(B_final), dkLen); + // Wipe both the xor scratch and the full working matrix once final digest bytes exist. + // JS cleanup is still only best-effort, but this local buffer is no longer needed here. + clean(B, B_final); + return res; +} +function processBlock(B, address, l, r, s, index, laneLen, segmentLen, lanes, offset, prev, dataIndependent, needXor) { + if (offset % laneLen) + prev = offset - 1; + let randL, randH; + if (dataIndependent) { + let i128 = index % 128; + // RFC 9106 §3.4.1.2: each 1024-byte address block yields 128 `(J1, J2)` pairs, so regenerate + // it whenever the segment index crosses a multiple of 128. + if (i128 === 0) { + address[256 + 12]++; + block(address, 256, 2 * 256, 0, false); + block(address, 0, 2 * 256, 0, false); + } + randL = address[2 * i128]; + randH = address[2 * i128 + 1]; + } + else { + const T = 256 * prev; + randL = B[T]; + randH = B[T + 1]; + } + // Address-block path selects `J1` / `J2`, then maps them to the reference + // lane/block per RFC 9106 §3.4. + const refLane = r === 0 && s === 0 ? l : randH % lanes; + const refPos = indexAlpha(r, s, laneLen, segmentLen, index, randL, refLane == l); + const refBlock = laneLen * refLane + refPos; + // B[i][j] = G(B[i][j-1], B[l][z]) + block(B, 256 * prev, 256 * refBlock, offset * 256, needXor); +} +function argon2(type, password, salt, opts) { + const { mP, p, t, version, B, laneLen, lanes, segmentLen, dkLen, perBlock } = argon2Init(password, salt, type, opts); + // Pre-loop setup + // [address, input, zero_block] format so we can pass single U32 to block function + const address = new Uint32Array(3 * 256); + address[256 + 6] = mP; + address[256 + 8] = t; + address[256 + 10] = type; + for (let r = 0; r < t; r++) { + // RFC 9106 step 6 applies the XOR-on-later-passes rule only for version `0x13`; legacy + // `0x10` keeps the older overwrite behavior used by the v16 test vectors. + const needXor = r !== 0 && version === 0x13; + address[256 + 0] = r; + for (let s = 0; s < ARGON2_SYNC_POINTS; s++) { + address[256 + 4] = s; + // RFC 9106 §3.4.1.3: Argon2id uses Argon2i's data-independent `J1` / `J2` generation only + // in pass 0, slices 0 and 1; Argon2i uses it in every segment. + const dataIndependent = type == AT.Argon2i || (type == AT.Argon2id && r === 0 && s < 2); + for (let l = 0; l < p; l++) { + address[256 + 2] = l; + address[256 + 12] = 0; + let startPos = 0; + if (r === 0 && s === 0) { + startPos = 2; + if (dataIndependent) { + address[256 + 12]++; + block(address, 256, 2 * 256, 0, false); + block(address, 0, 2 * 256, 0, false); + } + } + // current block postion + let offset = l * laneLen + s * segmentLen + startPos; + // previous block position + let prev = offset % laneLen ? offset - 1 : offset + laneLen - 1; + for (let index = startPos; index < segmentLen; index++, offset++, prev++) { + perBlock(); + processBlock(B, address, l, r, s, index, laneLen, segmentLen, lanes, offset, prev, dataIndependent, needXor); + } + } + } + } + clean(address); + return argon2Output(B, p, laneLen, dkLen); +} +/** + * Argon2d GPU-resistant version. + * @param password - password or input key material + * @param salt - unique salt value + * @param opts - Argon2 cost and optional tuning parameters. See {@link ArgonOpts}. + * @returns Derived key bytes. + * @throws If the Argon2 input or cost parameters are invalid. {@link Error} + * @example + * Derive a key with Argon2d. + * ```ts + * argon2d('password', 'salt1234', { t: 1, m: 8, p: 1, dkLen: 32 }); + * ``` + */ +export const argon2d = (password, salt, opts) => argon2(AT.Argond2d, password, salt, opts); +/** + * Argon2i side-channel-resistant version. + * @param password - password or input key material + * @param salt - unique salt value + * @param opts - Argon2 cost and optional tuning parameters. See {@link ArgonOpts}. + * @returns Derived key bytes. + * @throws If the Argon2 input or cost parameters are invalid. {@link Error} + * @example + * Derive a key with Argon2i. + * ```ts + * argon2i('password', 'salt1234', { t: 1, m: 8, p: 1, dkLen: 32 }); + * ``` + */ +export const argon2i = (password, salt, opts) => argon2(AT.Argon2i, password, salt, opts); +/** + * Argon2id, combining i+d, the most popular version from RFC 9106. + * @param password - password or input key material + * @param salt - unique salt value + * @param opts - Argon2 cost and optional tuning parameters. See {@link ArgonOpts}. + * @returns Derived key bytes. + * @throws If the Argon2 input or cost parameters are invalid. {@link Error} + * @example + * Derive a key with Argon2id. + * ```ts + * argon2id('password', 'salt1234', { t: 1, m: 8, p: 1, dkLen: 32 }); + * ``` + */ +export const argon2id = (password, salt, opts) => argon2(AT.Argon2id, password, salt, opts); +async function argon2Async(type, password, salt, opts) { + const { mP, p, t, version, B, laneLen, lanes, segmentLen, dkLen, perBlock, asyncTick } = argon2Init(password, salt, type, opts); + // Pre-loop setup + // [address, input, zero_block] format so we can pass single U32 to block function + const address = new Uint32Array(3 * 256); + address[256 + 6] = mP; + address[256 + 8] = t; + address[256 + 10] = type; + let ts = Date.now(); + for (let r = 0; r < t; r++) { + // RFC 9106 step 6 applies the XOR-on-later-passes rule only for version `0x13`; legacy + // `0x10` keeps the older overwrite behavior used by the v16 test vectors. + const needXor = r !== 0 && version === 0x13; + address[256 + 0] = r; + for (let s = 0; s < ARGON2_SYNC_POINTS; s++) { + address[256 + 4] = s; + // RFC 9106 §3.4.1.3: Argon2id uses Argon2i's data-independent `J1` / `J2` generation only + // in pass 0, slices 0 and 1; Argon2i uses it in every segment. + const dataIndependent = type == AT.Argon2i || (type == AT.Argon2id && r === 0 && s < 2); + for (let l = 0; l < p; l++) { + address[256 + 2] = l; + address[256 + 12] = 0; + let startPos = 0; + if (r === 0 && s === 0) { + startPos = 2; + if (dataIndependent) { + address[256 + 12]++; + block(address, 256, 2 * 256, 0, false); + block(address, 0, 2 * 256, 0, false); + } + } + // current block postion + let offset = l * laneLen + s * segmentLen + startPos; + // previous block position + let prev = offset % laneLen ? offset - 1 : offset + laneLen - 1; + for (let index = startPos; index < segmentLen; index++, offset++, prev++) { + perBlock(); + processBlock(B, address, l, r, s, index, laneLen, segmentLen, lanes, offset, prev, dataIndependent, needXor); + // Date.now() is not monotonic. If the clock goes backwards, + // still yield control. + const diff = Date.now() - ts; + if (!(diff >= 0 && diff < asyncTick)) { + await nextTick(); + ts += diff; + } + } + } + } + } + clean(address); + return argon2Output(B, p, laneLen, dkLen); +} +/** + * Argon2d async GPU-resistant version. + * @param password - password or input key material + * @param salt - unique salt value + * @param opts - Argon2 cost and optional tuning parameters. See {@link ArgonOpts}. + * @returns Promise resolving to derived key bytes. + * @throws If the Argon2 input or cost parameters are invalid. {@link Error} + * @example + * Derive a key with Argon2d asynchronously. + * ```ts + * await argon2dAsync('password', 'salt1234', { t: 1, m: 8, p: 1, dkLen: 32 }); + * ``` + */ +export const argon2dAsync = (password, salt, opts) => argon2Async(AT.Argond2d, password, salt, opts); +/** + * Argon2i async side-channel-resistant version. + * @param password - password or input key material + * @param salt - unique salt value + * @param opts - Argon2 cost and optional tuning parameters. See {@link ArgonOpts}. + * @returns Promise resolving to derived key bytes. + * @throws If the Argon2 input or cost parameters are invalid. {@link Error} + * @example + * Derive a key with Argon2i asynchronously. + * ```ts + * await argon2iAsync('password', 'salt1234', { t: 1, m: 8, p: 1, dkLen: 32 }); + * ``` + */ +export const argon2iAsync = (password, salt, opts) => argon2Async(AT.Argon2i, password, salt, opts); +/** + * Argon2id async, combining i+d, the most popular version from RFC 9106. + * @param password - password or input key material + * @param salt - unique salt value + * @param opts - Argon2 cost and optional tuning parameters. See {@link ArgonOpts}. + * @returns Promise resolving to derived key bytes. + * @throws If the Argon2 input or cost parameters are invalid. {@link Error} + * @example + * Derive a key with Argon2id asynchronously. + * ```ts + * await argon2idAsync('password', 'salt1234', { t: 1, m: 8, p: 1, dkLen: 32 }); + * ``` + */ +export const argon2idAsync = (password, salt, opts) => argon2Async(AT.Argon2id, password, salt, opts); +//# sourceMappingURL=argon2.js.map \ No newline at end of file diff --git a/node_modules/@noble/hashes/argon2.js.map b/node_modules/@noble/hashes/argon2.js.map new file mode 100644 index 0000000..d98e07e --- /dev/null +++ b/node_modules/@noble/hashes/argon2.js.map @@ -0,0 +1 @@ +{"version":3,"file":"argon2.js","sourceRoot":"","sources":["src/argon2.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAC3F,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EACL,OAAO,EACP,KAAK,EACL,eAAe,EACf,QAAQ,EACR,UAAU,EACV,SAAS,EACT,GAAG,EACH,EAAE,GAIH,MAAM,YAAY,CAAC;AAEpB,6FAA6F;AAC7F,6DAA6D;AAC7D,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAW,CAAC;AAG7D,oGAAoG;AACpG,MAAM,kBAAkB,GAAG,CAAC,CAAC;AAC7B,6DAA6D;AAC7D,2CAA2C;AAC3C,MAAM,YAAY,GAAG,CAAC,GAAoB,EAAE,UAAU,GAAG,EAAE,EAAoB,EAAE;IAC/E,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,UAAU,CAAC,EAAE,EAAE,CAAC;IAC9C,OAAO,eAAe,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;AAC1C,CAAC,CAAC;AAEF,oEAAoE;AACpE,SAAS,GAAG,CAAC,CAAS,EAAE,CAAS;IAC/B,iFAAiF;IACjF,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC;IACtB,MAAM,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC;IACpB,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC;IACtB,MAAM,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC;IACpB,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAC7B,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAC7B,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAC7B,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAC7B,MAAM,KAAK,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,MAAM,CAAC,GAAG,EAAE,CAAC;IAC/C,MAAM,IAAI,GAAG,CAAC,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;IACrD,MAAM,GAAG,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,MAAM,CAAC,CAAC;IAC1C,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC;AAC7B,CAAC;AAED,SAAS,IAAI,CAAC,CAAS,EAAE,CAAS;IAChC,0FAA0F;IAC1F,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC3B,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,WAAW,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,WAAW,EAAE,CAAC;AACjF,CAAC;AAED,gCAAgC;AAChC,qFAAqF;AACrF,SAAS,MAAM,CAAC,EAAU,EAAE,EAAU,EAAE,EAAU,EAAE,EAAU;IAC5D,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IACtC,sBAAsB;IACtB,MAAM,GAAG,GAAG,KAAK,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IAC9B,OAAO,EAAE,CAAC,EAAE,KAAK,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,GAAG,CAAC,EAAE,CAAC;AACnD,CAAC;AAED,0BAA0B;AAC1B,qEAAqE;AACrE,mCAAmC;AACnC,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,GAAG,CAAC,CAAC;AAEpC,mGAAmG;AACnG,SAAS,CAAC,CAAC,CAAS,EAAE,CAAS,EAAE,CAAS,EAAE,CAAS;IACnD,IAAI,EAAE,GAAG,MAAM,CAAC,CAAC,GAAC,CAAC,CAAC,EAAE,EAAE,GAAG,MAAM,CAAC,CAAC,GAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,kBAAkB;IAC9D,IAAI,EAAE,GAAG,MAAM,CAAC,CAAC,GAAC,CAAC,CAAC,EAAE,EAAE,GAAG,MAAM,CAAC,CAAC,GAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,kBAAkB;IAC9D,IAAI,EAAE,GAAG,MAAM,CAAC,CAAC,GAAC,CAAC,CAAC,EAAE,EAAE,GAAG,MAAM,CAAC,CAAC,GAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,kBAAkB;IAC9D,IAAI,EAAE,GAAG,MAAM,CAAC,CAAC,GAAC,CAAC,CAAC,EAAE,EAAE,GAAG,MAAM,CAAC,CAAC,GAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,kBAAkB;IAE9D,gFAAgF;IAChF,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IAC5C,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;IAC5C,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;IAE5D,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IAC5C,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;IAC5C,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;IAElE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IAC5C,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;IAC5C,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;IAElE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IAC5C,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;IAC5C,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;IAElE,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IACjD,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IACjD,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC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"} \ No newline at end of file diff --git a/node_modules/@noble/hashes/blake1.d.ts b/node_modules/@noble/hashes/blake1.d.ts new file mode 100644 index 0000000..11d8782 --- /dev/null +++ b/node_modules/@noble/hashes/blake1.d.ts @@ -0,0 +1,156 @@ +import { type CHash, type Hash, type TArg, type TRet } from './utils.ts'; +/** Blake1 options. Basically just `salt`. */ +export type BlakeOpts = { + /** Optional salt mixed into initialization. */ + salt?: Uint8Array; +}; +declare abstract class BLAKE1> implements Hash { + readonly canXOF = false; + protected finished: boolean; + protected length: number; + protected pos: number; + protected destroyed: boolean; + protected buffer: Uint8Array; + protected view: DataView; + protected salt: Uint32Array; + abstract compress(view: DataView, offset: number, withLength?: boolean): void; + protected abstract get(): number[]; + protected abstract set(...args: number[]): void; + readonly blockLen: number; + readonly outputLen: number; + private lengthFlag; + private counterLen; + protected constants: Uint32Array; + constructor(blockLen: number, outputLen: number, lengthFlag: number, counterLen: number, saltLen: number, constants: Uint32Array, opts?: BlakeOpts); + update(data: TArg): this; + destroy(): void; + _cloneInto(to?: T): T; + clone(): T; + digestInto(out: TArg): void; + digest(): TRet; +} +declare class BLAKE1_32B extends BLAKE1 { + private v0; + private v1; + private v2; + private v3; + private v4; + private v5; + private v6; + private v7; + constructor(outputLen: number, IV: Uint32Array, lengthFlag: number, opts?: BlakeOpts); + protected get(): [number, number, number, number, number, number, number, number]; + protected set(v0: number, v1: number, v2: number, v3: number, v4: number, v5: number, v6: number, v7: number): void; + destroy(): void; + compress(view: DataView, offset: number, withLength?: boolean): void; +} +declare class BLAKE1_64B extends BLAKE1 { + private v0l; + private v0h; + private v1l; + private v1h; + private v2l; + private v2h; + private v3l; + private v3h; + private v4l; + private v4h; + private v5l; + private v5h; + private v6l; + private v6h; + private v7l; + private v7h; + constructor(outputLen: number, IV: Uint32Array, lengthFlag: number, opts?: BlakeOpts); + protected get(): [ + number, + number, + number, + number, + number, + number, + number, + number, + number, + number, + number, + number, + number, + number, + number, + number + ]; + protected set(v0l: number, v0h: number, v1l: number, v1h: number, v2l: number, v2h: number, v3l: number, v3h: number, v4l: number, v4h: number, v5l: number, v5h: number, v6l: number, v6h: number, v7l: number, v7h: number): void; + destroy(): void; + compress(view: DataView, offset: number, withLength?: boolean): void; +} +/** Internal blake1-224 hash class. */ +export declare class _BLAKE224 extends BLAKE1_32B { + constructor(opts?: BlakeOpts); +} +/** Internal blake1-256 hash class. */ +export declare class _BLAKE256 extends BLAKE1_32B { + constructor(opts?: BlakeOpts); +} +/** Internal blake1-384 hash class. */ +export declare class _BLAKE384 extends BLAKE1_64B { + constructor(opts?: BlakeOpts); +} +/** Internal blake1-512 hash class. */ +export declare class _BLAKE512 extends BLAKE1_64B { + constructor(opts?: BlakeOpts); +} +/** + * Blake1-224 hash function. + * @param msg - message bytes to hash + * @param opts - Optional Blake1 settings. See {@link BlakeOpts}. If set, + * `opts.salt` must be exactly 16 bytes. + * @returns Digest bytes. + * @example + * Hash a message with Blake1-224. + * ```ts + * blake224(new Uint8Array([97, 98, 99])); + * ``` + */ +export declare const blake224: TRet>; +/** + * Blake1-256 hash function. + * @param msg - message bytes to hash + * @param opts - Optional Blake1 settings. See {@link BlakeOpts}. If set, + * `opts.salt` must be exactly 16 bytes. + * @returns Digest bytes. + * @example + * Hash a message with Blake1-256. + * ```ts + * blake256(new Uint8Array([97, 98, 99])); + * ``` + */ +export declare const blake256: TRet>; +/** + * Blake1-384 hash function. + * @param msg - message bytes to hash + * @param opts - Optional Blake1 settings. See {@link BlakeOpts}. If set, + * `opts.salt` must be exactly 32 bytes. + * @returns Digest bytes. + * @example + * Hash a message with Blake1-384. + * ```ts + * blake384(new Uint8Array([97, 98, 99])); + * ``` + */ +export declare const blake384: TRet>; +/** + * Blake1-512 hash function. + * @param msg - message bytes to hash + * @param opts - Optional Blake1 settings. See {@link BlakeOpts}. If set, + * `opts.salt` must be exactly 32 bytes. + * @returns Digest bytes. + * @example + * Hash a message with Blake1-512. + * ```ts + * blake512(new Uint8Array([97, 98, 99])); + * ``` + */ +export declare const blake512: TRet>; +export {}; +//# sourceMappingURL=blake1.d.ts.map \ No newline at end of file diff --git a/node_modules/@noble/hashes/blake1.d.ts.map b/node_modules/@noble/hashes/blake1.d.ts.map new file mode 100644 index 0000000..16d351e --- /dev/null +++ b/node_modules/@noble/hashes/blake1.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"blake1.d.ts","sourceRoot":"","sources":["src/blake1.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@noble/hashes/blake1.js b/node_modules/@noble/hashes/blake1.js new file mode 100644 index 0000000..01ff8e0 --- /dev/null +++ b/node_modules/@noble/hashes/blake1.js @@ -0,0 +1,560 @@ +/** + * Blake1 legacy hash function, one of SHA3 proposals. + * Rarely used. Check out blake2 or blake3 instead. + * {@link https://www.aumasson.jp/blake/blake.pdf} + * + * In the best case, there are 0 allocations. + * + * Differences from blake2: + * + * - BE instead of LE + * - Paddings, similar to MD5, RIPEMD, SHA1, SHA2, but: + * - length flag is located before actual length + * - padding block is compressed differently (no lengths) + * Instead of msg[sigma[k]], we have `msg[sigma[k]] ^ constants[sigma[k-1]]` + * (-1 for g1, g2 without -1) + * - Salt is XOR-ed into constants instead of state + * - Salt is XOR-ed with output in `compress` + * - Additional rows (+64 bytes) in SIGMA for new rounds + * - Different round count: + * - 14 / 10 rounds in blake256 / blake2s + * - 16 / 12 rounds in blake512 / blake2b + * - blake512: G1b: rotr 24 -> 25, G2b: rotr 63 -> 11 + * @module + */ +import { BSIGMA, G1s, G2s } from "./_blake.js"; +import { SHA224_IV, SHA256_IV, SHA384_IV, SHA512_IV } from "./_md.js"; +import * as u64 from "./_u64.js"; +// prettier-ignore +import { abytes, aexists, aoutput, clean, createHasher, createView } from "./utils.js"; +// Shared unsalted sentinel, sized for the 64-bit path and reused by the 32-bit path via prefix. +const EMPTY_SALT = /* @__PURE__ */ new Uint32Array(8); +// Base destroy logic only clears salt-derived state; the partial message buffer and length/position +// bookkeeping remain until the instance or backing buffer is reused. +class BLAKE1 { + canXOF = false; + finished = false; + length = 0; + pos = 0; + destroyed = false; + // For partial updates less than block size + buffer; + view; + salt; + blockLen; + outputLen; + lengthFlag; + counterLen; + constants; + constructor(blockLen, outputLen, lengthFlag, counterLen, saltLen, constants, opts = {}) { + const { salt } = opts; + this.blockLen = blockLen; + this.outputLen = outputLen; + this.lengthFlag = lengthFlag; + this.counterLen = counterLen; + this.buffer = new Uint8Array(blockLen); + this.view = createView(this.buffer); + if (salt !== undefined) { + let slt = salt; + abytes(slt, 4 * saltLen, 'salt'); + // if (slt.length !== 4 * saltLen) throw new Error('wrong salt length'); + const salt32 = (this.salt = new Uint32Array(saltLen)); + const sv = createView(slt); + this.constants = constants.slice(); + for (let i = 0, offset = 0; i < salt32.length; i++, offset += 4) { + salt32[i] = sv.getUint32(offset, false); + this.constants[i] ^= salt32[i]; + } + } + else { + this.salt = EMPTY_SALT; + this.constants = constants; + } + } + update(data) { + aexists(this); + abytes(data); + // From _md, but update length before each compress + const { view, buffer, blockLen } = this; + const len = data.length; + let dataView; + for (let pos = 0; pos < len;) { + const take = Math.min(blockLen - this.pos, len - pos); + // Fast path only when there is no buffered partial block: `take === blockLen` implies + // `this.pos === 0`, so we can process full blocks directly from the input view. + if (take === blockLen) { + if (!dataView) + dataView = createView(data); + for (; blockLen <= len - pos; pos += blockLen) { + this.length += blockLen; + this.compress(dataView, pos); + } + continue; + } + buffer.set(data.subarray(pos, pos + take), this.pos); + this.pos += take; + pos += take; + if (this.pos === blockLen) { + this.length += blockLen; + this.compress(view, 0, true); + this.pos = 0; + } + } + return this; + } + destroy() { + this.destroyed = true; + if (this.salt !== EMPTY_SALT) { + clean(this.salt, this.constants); + } + } + _cloneInto(to) { + to ||= new this.constructor(); + to.set(...this.get()); + const { buffer, length, finished, destroyed, constants, salt, pos } = this; + to.buffer.set(buffer); + // Clone salt-derived arrays by value so destroying the clone cannot wipe the source instance. + to.constants = constants.slice(); + to.destroyed = destroyed; + to.finished = finished; + to.length = length; + to.pos = pos; + to.salt = salt.slice(); + return to; + } + clone() { + return this._cloneInto(); + } + digestInto(out) { + aexists(this); + aoutput(out, this); + this.finished = true; + // Padding + const { buffer, blockLen, counterLen, lengthFlag, view } = this; + clean(buffer.subarray(this.pos)); // clean buf + const counter = BigInt((this.length + this.pos) * 8); + const counterPos = blockLen - counterLen - 1; + buffer[this.pos] |= 0b1000_0000; // End block flag + this.length += this.pos; // add unwritten length + // Not enough in buffer for length: write what we have. + if (this.pos > counterPos) { + this.compress(view, 0); + clean(buffer); + this.pos = 0; + } + // Difference with md: here we have lengthFlag! + buffer[counterPos] |= lengthFlag; // Length flag + // We always set 8 byte length flag. Because length will overflow significantly sooner. + view.setBigUint64(blockLen - 8, counter, false); + // Blake1 omits the counter from the extra all-padding block; only the block that still carries + // message bytes mixes in the final bit length. + this.compress(view, 0, this.pos !== 0); + // Write output + clean(buffer); + const v = createView(out); + const state = this.get(); + for (let i = 0; i < this.outputLen / 4; ++i) + v.setUint32(i * 4, state[i]); + } + digest() { + const { buffer, outputLen } = this; + this.digestInto(buffer); + // Return a copy so callers do not alias the instance scratch buffer used during finalization. + const res = buffer.slice(0, outputLen); + this.destroy(); + return res; + } +} +// Blake1-512 / Blake1-384 constant table `C512`. +// Stored as sixteen 64-bit constants split into `[high32, low32]` halves so +// the Blake1-64 path can reuse one layout for both `v8..v15` initialization +// and the permuted constant lookups. +const B64C = /* @__PURE__ */ Uint32Array.from([ + 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, + 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, + 0x9216d5d9, 0x8979fb1b, 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96, + 0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, +]); +// Blake1-256 / Blake1-224 constant table `C256`, derived as the first half of `C512`. +const B32C = /* @__PURE__ */ B64C.slice(0, 16); +// Blake1-256 IV cloned from SHA-256. +const B256_IV = /* @__PURE__ */ SHA256_IV.slice(); +// Blake1-224 IV cloned from SHA-224. +const B224_IV = /* @__PURE__ */ SHA224_IV.slice(); +// Blake1-384 IV cloned from the SHA-384 high-then-low 32-bit halves. +const B384_IV = /* @__PURE__ */ SHA384_IV.slice(); +// Blake1-512 IV cloned from the SHA-512 high-then-low 32-bit halves. +const B512_IV = /* @__PURE__ */ SHA512_IV.slice(); +// Precompute the odd/even companion constants used by all 14 Blake1-32 rounds. +// Each pair stores `u[sigma[2i + 1]]` then `u[sigma[2i]]`, matching the `G1s` / `G2s` xor order. +function generateTBL256() { + const TBL = []; + for (let i = 0, j = 0; i < 14; i++, j += 16) { + for (let offset = 1; offset < 16; offset += 2) { + TBL.push(B32C[BSIGMA[j + offset]]); + TBL.push(B32C[BSIGMA[j + offset - 1]]); + } + } + return new Uint32Array(TBL); +} +// Full 14-round companion-constant table for Blake1-32. +const TBL256 = /* @__PURE__ */ generateTBL256(); +// Shared synchronous message-word scratch for the 32-bit Blake1 path. +const BLAKE256_W = /* @__PURE__ */ new Uint32Array(16); +class BLAKE1_32B extends BLAKE1 { + v0; + v1; + v2; + v3; + v4; + v5; + v6; + v7; + constructor(outputLen, IV, lengthFlag, opts = {}) { + super(64, outputLen, lengthFlag, 8, 4, B32C, opts); + this.v0 = IV[0] | 0; + this.v1 = IV[1] | 0; + this.v2 = IV[2] | 0; + this.v3 = IV[3] | 0; + this.v4 = IV[4] | 0; + this.v5 = IV[5] | 0; + this.v6 = IV[6] | 0; + this.v7 = IV[7] | 0; + } + get() { + const { v0, v1, v2, v3, v4, v5, v6, v7 } = this; + return [v0, v1, v2, v3, v4, v5, v6, v7]; + } + // prettier-ignore + set(v0, v1, v2, v3, v4, v5, v6, v7) { + this.v0 = v0 | 0; + this.v1 = v1 | 0; + this.v2 = v2 | 0; + this.v3 = v3 | 0; + this.v4 = v4 | 0; + this.v5 = v5 | 0; + this.v6 = v6 | 0; + this.v7 = v7 | 0; + } + destroy() { + super.destroy(); + this.set(0, 0, 0, 0, 0, 0, 0, 0); + } + compress(view, offset, withLength = true) { + for (let i = 0; i < 16; i++, offset += 4) + BLAKE256_W[i] = view.getUint32(offset, false); + // Cannot reuse blake2s compress: Blake1 mixes each message word with the companion constants + // precomputed in `TBL256`, rather than using the raw schedule words directly. + let v00 = this.v0 | 0; + let v01 = this.v1 | 0; + let v02 = this.v2 | 0; + let v03 = this.v3 | 0; + let v04 = this.v4 | 0; + let v05 = this.v5 | 0; + let v06 = this.v6 | 0; + let v07 = this.v7 | 0; + let v08 = this.constants[0] | 0; + let v09 = this.constants[1] | 0; + let v10 = this.constants[2] | 0; + let v11 = this.constants[3] | 0; + // Blake1-32 injects the 64-bit bit counter as `[t0, t0, t1, t1]` across `v12..v15`; the + // final all-padding block passes `withLength = false`, leaving these lanes as raw constants. + const { h, l } = u64.fromBig(BigInt(withLength ? this.length * 8 : 0)); + let v12 = (this.constants[4] ^ l) >>> 0; + let v13 = (this.constants[5] ^ l) >>> 0; + let v14 = (this.constants[6] ^ h) >>> 0; + let v15 = (this.constants[7] ^ h) >>> 0; + // prettier-ignore + for (let i = 0, k = 0, j = 0; i < 14; i++) { + ({ a: v00, b: v04, c: v08, d: v12 } = G1s(v00, v04, v08, v12, BLAKE256_W[BSIGMA[k++]] ^ TBL256[j++])); + ({ a: v00, b: v04, c: v08, d: v12 } = G2s(v00, v04, v08, v12, BLAKE256_W[BSIGMA[k++]] ^ TBL256[j++])); + ({ a: v01, b: v05, c: v09, d: v13 } = G1s(v01, v05, v09, v13, BLAKE256_W[BSIGMA[k++]] ^ TBL256[j++])); + ({ a: v01, b: v05, c: v09, d: v13 } = G2s(v01, v05, v09, v13, BLAKE256_W[BSIGMA[k++]] ^ TBL256[j++])); + ({ a: v02, b: v06, c: v10, d: v14 } = G1s(v02, v06, v10, v14, BLAKE256_W[BSIGMA[k++]] ^ TBL256[j++])); + ({ a: v02, b: v06, c: v10, d: v14 } = G2s(v02, v06, v10, v14, BLAKE256_W[BSIGMA[k++]] ^ TBL256[j++])); + ({ a: v03, b: v07, c: v11, d: v15 } = G1s(v03, v07, v11, v15, BLAKE256_W[BSIGMA[k++]] ^ TBL256[j++])); + ({ a: v03, b: v07, c: v11, d: v15 } = G2s(v03, v07, v11, v15, BLAKE256_W[BSIGMA[k++]] ^ TBL256[j++])); + ({ a: v00, b: v05, c: v10, d: v15 } = G1s(v00, v05, v10, v15, BLAKE256_W[BSIGMA[k++]] ^ TBL256[j++])); + ({ a: v00, b: v05, c: v10, d: v15 } = G2s(v00, v05, v10, v15, BLAKE256_W[BSIGMA[k++]] ^ TBL256[j++])); + ({ a: v01, b: v06, c: v11, d: v12 } = G1s(v01, v06, v11, v12, BLAKE256_W[BSIGMA[k++]] ^ TBL256[j++])); + ({ a: v01, b: v06, c: v11, d: v12 } = G2s(v01, v06, v11, v12, BLAKE256_W[BSIGMA[k++]] ^ TBL256[j++])); + ({ a: v02, b: v07, c: v08, d: v13 } = G1s(v02, v07, v08, v13, BLAKE256_W[BSIGMA[k++]] ^ TBL256[j++])); + ({ a: v02, b: v07, c: v08, d: v13 } = G2s(v02, v07, v08, v13, BLAKE256_W[BSIGMA[k++]] ^ TBL256[j++])); + ({ a: v03, b: v04, c: v09, d: v14 } = G1s(v03, v04, v09, v14, BLAKE256_W[BSIGMA[k++]] ^ TBL256[j++])); + ({ a: v03, b: v04, c: v09, d: v14 } = G2s(v03, v04, v09, v14, BLAKE256_W[BSIGMA[k++]] ^ TBL256[j++])); + } + this.v0 = (this.v0 ^ v00 ^ v08 ^ this.salt[0]) >>> 0; + this.v1 = (this.v1 ^ v01 ^ v09 ^ this.salt[1]) >>> 0; + this.v2 = (this.v2 ^ v02 ^ v10 ^ this.salt[2]) >>> 0; + this.v3 = (this.v3 ^ v03 ^ v11 ^ this.salt[3]) >>> 0; + this.v4 = (this.v4 ^ v04 ^ v12 ^ this.salt[0]) >>> 0; + this.v5 = (this.v5 ^ v05 ^ v13 ^ this.salt[1]) >>> 0; + this.v6 = (this.v6 ^ v06 ^ v14 ^ this.salt[2]) >>> 0; + this.v7 = (this.v7 ^ v07 ^ v15 ^ this.salt[3]) >>> 0; + clean(BLAKE256_W); + } +} +// Shared Blake1-64 work vector storing 16 working words as adjacent high/low 32-bit halves. +const BBUF = /* @__PURE__ */ new Uint32Array(32); +// Shared synchronous message-word scratch for the 64-bit Blake1 path. +const BLAKE512_W = /* @__PURE__ */ new Uint32Array(32); +// Precompute the high/low companion constants used by all 16 Blake1-64 rounds. +// Each quartet stores `u[sigma[2i + 1]]` high/low halves, then `u[sigma[2i]]` high/low halves. +function generateTBL512() { + const TBL = []; + for (let r = 0, k = 0; r < 16; r++, k += 16) { + for (let offset = 1; offset < 16; offset += 2) { + TBL.push(B64C[BSIGMA[k + offset] * 2 + 0]); + TBL.push(B64C[BSIGMA[k + offset] * 2 + 1]); + TBL.push(B64C[BSIGMA[k + offset - 1] * 2 + 0]); + TBL.push(B64C[BSIGMA[k + offset - 1] * 2 + 1]); + } + } + return new Uint32Array(TBL); +} +// Full 16-round companion-constant table as high/low halves. +const TBL512 = /* @__PURE__ */ generateTBL512(); +// Blake1-64 first half-round with rotations `32` and `25`; `k` is the half-call schedule index. +function G1b(a, b, c, d, msg, k) { + const Xpos = 2 * BSIGMA[k]; + const Xl = msg[Xpos + 1] ^ TBL512[k * 2 + 1], Xh = msg[Xpos] ^ TBL512[k * 2]; // prettier-ignore + let Al = BBUF[2 * a + 1], Ah = BBUF[2 * a]; // prettier-ignore + let Bl = BBUF[2 * b + 1], Bh = BBUF[2 * b]; // prettier-ignore + let Cl = BBUF[2 * c + 1], Ch = BBUF[2 * c]; // prettier-ignore + let Dl = BBUF[2 * d + 1], Dh = BBUF[2 * d]; // prettier-ignore + // v[a] = (v[a] + v[b] + x) | 0; + let ll = u64.add3L(Al, Bl, Xl); + Ah = u64.add3H(ll, Ah, Bh, Xh) >>> 0; + Al = (ll | 0) >>> 0; + // v[d] = rotr(v[d] ^ v[a], 32) + ({ Dh, Dl } = { Dh: Dh ^ Ah, Dl: Dl ^ Al }); + ({ Dh, Dl } = { Dh: u64.rotr32H(Dh, Dl), Dl: u64.rotr32L(Dh, Dl) }); + // v[c] = (v[c] + v[d]) | 0; + ({ h: Ch, l: Cl } = u64.add(Ch, Cl, Dh, Dl)); + // v[b] = rotr(v[b] ^ v[c], 25) + ({ Bh, Bl } = { Bh: Bh ^ Ch, Bl: Bl ^ Cl }); + ({ Bh, Bl } = { Bh: u64.rotrSH(Bh, Bl, 25), Bl: u64.rotrSL(Bh, Bl, 25) }); + ((BBUF[2 * a + 1] = Al), (BBUF[2 * a] = Ah)); + ((BBUF[2 * b + 1] = Bl), (BBUF[2 * b] = Bh)); + ((BBUF[2 * c + 1] = Cl), (BBUF[2 * c] = Ch)); + ((BBUF[2 * d + 1] = Dl), (BBUF[2 * d] = Dh)); +} +// Blake1-64 second half-round with rotations `16` and `11`; `k` is the half-call schedule index. +function G2b(a, b, c, d, msg, k) { + const Xpos = 2 * BSIGMA[k]; + const Xl = msg[Xpos + 1] ^ TBL512[k * 2 + 1], Xh = msg[Xpos] ^ TBL512[k * 2]; // prettier-ignore + let Al = BBUF[2 * a + 1], Ah = BBUF[2 * a]; // prettier-ignore + let Bl = BBUF[2 * b + 1], Bh = BBUF[2 * b]; // prettier-ignore + let Cl = BBUF[2 * c + 1], Ch = BBUF[2 * c]; // prettier-ignore + let Dl = BBUF[2 * d + 1], Dh = BBUF[2 * d]; // prettier-ignore + // v[a] = (v[a] + v[b] + x) | 0; + let ll = u64.add3L(Al, Bl, Xl); + Ah = u64.add3H(ll, Ah, Bh, Xh); + Al = ll | 0; + // v[d] = rotr(v[d] ^ v[a], 16) + ({ Dh, Dl } = { Dh: Dh ^ Ah, Dl: Dl ^ Al }); + ({ Dh, Dl } = { Dh: u64.rotrSH(Dh, Dl, 16), Dl: u64.rotrSL(Dh, Dl, 16) }); + // v[c] = (v[c] + v[d]) | 0; + ({ h: Ch, l: Cl } = u64.add(Ch, Cl, Dh, Dl)); + // v[b] = rotr(v[b] ^ v[c], 11) + ({ Bh, Bl } = { Bh: Bh ^ Ch, Bl: Bl ^ Cl }); + ({ Bh, Bl } = { Bh: u64.rotrSH(Bh, Bl, 11), Bl: u64.rotrSL(Bh, Bl, 11) }); + ((BBUF[2 * a + 1] = Al), (BBUF[2 * a] = Ah)); + ((BBUF[2 * b + 1] = Bl), (BBUF[2 * b] = Bh)); + ((BBUF[2 * c + 1] = Cl), (BBUF[2 * c] = Ch)); + ((BBUF[2 * d + 1] = Dl), (BBUF[2 * d] = Dh)); +} +// Legacy field names keep the local `l/h` spelling, but array/state order stays `[high, low]` to +// match the IV tables and `BBUF` layout. +class BLAKE1_64B extends BLAKE1 { + v0l; + v0h; + v1l; + v1h; + v2l; + v2h; + v3l; + v3h; + v4l; + v4h; + v5l; + v5h; + v6l; + v6h; + v7l; + v7h; + constructor(outputLen, IV, lengthFlag, opts = {}) { + super(128, outputLen, lengthFlag, 16, 8, B64C, opts); + this.v0l = IV[0] | 0; + this.v0h = IV[1] | 0; + this.v1l = IV[2] | 0; + this.v1h = IV[3] | 0; + this.v2l = IV[4] | 0; + this.v2h = IV[5] | 0; + this.v3l = IV[6] | 0; + this.v3h = IV[7] | 0; + this.v4l = IV[8] | 0; + this.v4h = IV[9] | 0; + this.v5l = IV[10] | 0; + this.v5h = IV[11] | 0; + this.v6l = IV[12] | 0; + this.v6h = IV[13] | 0; + this.v7l = IV[14] | 0; + this.v7h = IV[15] | 0; + } + // prettier-ignore + get() { + let { v0l, v0h, v1l, v1h, v2l, v2h, v3l, v3h, v4l, v4h, v5l, v5h, v6l, v6h, v7l, v7h } = this; + return [v0l, v0h, v1l, v1h, v2l, v2h, v3l, v3h, v4l, v4h, v5l, v5h, v6l, v6h, v7l, v7h]; + } + // prettier-ignore + set(v0l, v0h, v1l, v1h, v2l, v2h, v3l, v3h, v4l, v4h, v5l, v5h, v6l, v6h, v7l, v7h) { + this.v0l = v0l | 0; + this.v0h = v0h | 0; + this.v1l = v1l | 0; + this.v1h = v1h | 0; + this.v2l = v2l | 0; + this.v2h = v2h | 0; + this.v3l = v3l | 0; + this.v3h = v3h | 0; + this.v4l = v4l | 0; + this.v4h = v4h | 0; + this.v5l = v5l | 0; + this.v5h = v5h | 0; + this.v6l = v6l | 0; + this.v6h = v6h | 0; + this.v7l = v7l | 0; + this.v7h = v7h | 0; + } + destroy() { + super.destroy(); + this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + } + compress(view, offset, withLength = true) { + for (let i = 0; i < 32; i++, offset += 4) + BLAKE512_W[i] = view.getUint32(offset, false); + this.get().forEach((v, i) => (BBUF[i] = v)); // First half from state. + BBUF.set(this.constants.subarray(0, 16), 16); + if (withLength) { + // Blake1-64 injects the 64-bit bit counter into `v12` and `v13`; the final all-padding + // block passes `withLength = false`, leaving the trailing constant lanes untouched. + const { h, l } = u64.fromBig(BigInt(this.length * 8)); + BBUF[24] = (BBUF[24] ^ h) >>> 0; + BBUF[25] = (BBUF[25] ^ l) >>> 0; + BBUF[26] = (BBUF[26] ^ h) >>> 0; + BBUF[27] = (BBUF[27] ^ l) >>> 0; + } + for (let i = 0, k = 0; i < 16; i++) { + G1b(0, 4, 8, 12, BLAKE512_W, k++); + G2b(0, 4, 8, 12, BLAKE512_W, k++); + G1b(1, 5, 9, 13, BLAKE512_W, k++); + G2b(1, 5, 9, 13, BLAKE512_W, k++); + G1b(2, 6, 10, 14, BLAKE512_W, k++); + G2b(2, 6, 10, 14, BLAKE512_W, k++); + G1b(3, 7, 11, 15, BLAKE512_W, k++); + G2b(3, 7, 11, 15, BLAKE512_W, k++); + G1b(0, 5, 10, 15, BLAKE512_W, k++); + G2b(0, 5, 10, 15, BLAKE512_W, k++); + G1b(1, 6, 11, 12, BLAKE512_W, k++); + G2b(1, 6, 11, 12, BLAKE512_W, k++); + G1b(2, 7, 8, 13, BLAKE512_W, k++); + G2b(2, 7, 8, 13, BLAKE512_W, k++); + G1b(3, 4, 9, 14, BLAKE512_W, k++); + G2b(3, 4, 9, 14, BLAKE512_W, k++); + } + this.v0l ^= BBUF[0] ^ BBUF[16] ^ this.salt[0]; + this.v0h ^= BBUF[1] ^ BBUF[17] ^ this.salt[1]; + this.v1l ^= BBUF[2] ^ BBUF[18] ^ this.salt[2]; + this.v1h ^= BBUF[3] ^ BBUF[19] ^ this.salt[3]; + this.v2l ^= BBUF[4] ^ BBUF[20] ^ this.salt[4]; + this.v2h ^= BBUF[5] ^ BBUF[21] ^ this.salt[5]; + this.v3l ^= BBUF[6] ^ BBUF[22] ^ this.salt[6]; + this.v3h ^= BBUF[7] ^ BBUF[23] ^ this.salt[7]; + this.v4l ^= BBUF[8] ^ BBUF[24] ^ this.salt[0]; + this.v4h ^= BBUF[9] ^ BBUF[25] ^ this.salt[1]; + this.v5l ^= BBUF[10] ^ BBUF[26] ^ this.salt[2]; + this.v5h ^= BBUF[11] ^ BBUF[27] ^ this.salt[3]; + this.v6l ^= BBUF[12] ^ BBUF[28] ^ this.salt[4]; + this.v6h ^= BBUF[13] ^ BBUF[29] ^ this.salt[5]; + this.v7l ^= BBUF[14] ^ BBUF[30] ^ this.salt[6]; + this.v7h ^= BBUF[15] ^ BBUF[31] ^ this.salt[7]; + clean(BBUF, BLAKE512_W); + } +} +/** Internal blake1-224 hash class. */ +export class _BLAKE224 extends BLAKE1_32B { + constructor(opts = {}) { + super(28, B224_IV, 0b0000_0000, opts); + } +} +/** Internal blake1-256 hash class. */ +export class _BLAKE256 extends BLAKE1_32B { + constructor(opts = {}) { + super(32, B256_IV, 0b0000_0001, opts); + } +} +/** Internal blake1-384 hash class. */ +export class _BLAKE384 extends BLAKE1_64B { + constructor(opts = {}) { + super(48, B384_IV, 0b0000_0000, opts); + } +} +/** Internal blake1-512 hash class. */ +export class _BLAKE512 extends BLAKE1_64B { + constructor(opts = {}) { + super(64, B512_IV, 0b0000_0001, opts); + } +} +/** + * Blake1-224 hash function. + * @param msg - message bytes to hash + * @param opts - Optional Blake1 settings. See {@link BlakeOpts}. If set, + * `opts.salt` must be exactly 16 bytes. + * @returns Digest bytes. + * @example + * Hash a message with Blake1-224. + * ```ts + * blake224(new Uint8Array([97, 98, 99])); + * ``` + */ +export const blake224 = /* @__PURE__ */ createHasher((opts) => new _BLAKE224(opts)); +/** + * Blake1-256 hash function. + * @param msg - message bytes to hash + * @param opts - Optional Blake1 settings. See {@link BlakeOpts}. If set, + * `opts.salt` must be exactly 16 bytes. + * @returns Digest bytes. + * @example + * Hash a message with Blake1-256. + * ```ts + * blake256(new Uint8Array([97, 98, 99])); + * ``` + */ +export const blake256 = /* @__PURE__ */ createHasher((opts) => new _BLAKE256(opts)); +/** + * Blake1-384 hash function. + * @param msg - message bytes to hash + * @param opts - Optional Blake1 settings. See {@link BlakeOpts}. If set, + * `opts.salt` must be exactly 32 bytes. + * @returns Digest bytes. + * @example + * Hash a message with Blake1-384. + * ```ts + * blake384(new Uint8Array([97, 98, 99])); + * ``` + */ +export const blake384 = /* @__PURE__ */ createHasher((opts) => new _BLAKE384(opts)); +/** + * Blake1-512 hash function. + * @param msg - message bytes to hash + * @param opts - Optional Blake1 settings. See {@link BlakeOpts}. If set, + * `opts.salt` must be exactly 32 bytes. + * @returns Digest bytes. + * @example + * Hash a message with Blake1-512. + * ```ts + * blake512(new Uint8Array([97, 98, 99])); + * ``` + */ +export const blake512 = /* @__PURE__ */ createHasher((opts) => new _BLAKE512(opts)); +//# sourceMappingURL=blake1.js.map \ No newline at end of file diff --git a/node_modules/@noble/hashes/blake1.js.map b/node_modules/@noble/hashes/blake1.js.map new file mode 100644 index 0000000..496638d --- /dev/null +++ b/node_modules/@noble/hashes/blake1.js.map @@ -0,0 +1 @@ +{"version":3,"file":"blake1.js","sourceRoot":"","sources":["src/blake1.ts"],"names":[],"mappings":"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,CAAC,GAAG,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACtG,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACtG,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACtG,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACtG,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACtG,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACtG,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACtG,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACtG,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACtG,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACtG,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC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AC9C,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC9C,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC9C,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC9C,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC9C,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC9C,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC/C,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC/C,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC/C,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC/C,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC/C,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC/C,KAAK,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IAC1B,CAAC;CACF;AAED,sCAAsC;AACtC,MAAM,OAAO,SAAU,SAAQ,UAAU;IACvC,YAAY,OAAkB,EAAE;QAC9B,KAAK,CAAC,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC;IACxC,CAAC;CACF;AACD,sCAAsC;AACtC,MAAM,OAAO,SAAU,SAAQ,UAAU;IACvC,YAAY,OAAkB,EAAE;QAC9B,KAAK,CAAC,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC;IACxC,CAAC;CACF;AACD,sCAAsC;AACtC,MAAM,OAAO,SAAU,SAAQ,UAAU;IACvC,YAAY,OAAkB,EAAE;QAC9B,KAAK,CAAC,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC;IACxC,CAAC;CACF;AACD,sCAAsC;AACtC,MAAM,OAAO,SAAU,SAAQ,UAAU;IACvC,YAAY,OAAkB,EAAE;QAC9B,KAAK,CAAC,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC;IACxC,CAAC;CACF;AACD;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAsC,eAAe,CAAC,YAAY,CACrF,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,SAAS,CAAC,IAAI,CAAC,CAC9B,CAAC;AACF;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAsC,eAAe,CAAC,YAAY,CACrF,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,SAAS,CAAC,IAAI,CAAC,CAC9B,CAAC;AACF;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAsC,eAAe,CAAC,YAAY,CACrF,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,SAAS,CAAC,IAAI,CAAC,CAC9B,CAAC;AACF;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAsC,eAAe,CAAC,YAAY,CACrF,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,SAAS,CAAC,IAAI,CAAC,CAC9B,CAAC"} \ No newline at end of file diff --git a/node_modules/@noble/hashes/blake2.d.ts b/node_modules/@noble/hashes/blake2.d.ts new file mode 100644 index 0000000..ff66cdb --- /dev/null +++ b/node_modules/@noble/hashes/blake2.d.ts @@ -0,0 +1,184 @@ +import { type CHash, type Hash, type TArg, type TRet } from './utils.ts'; +/** + * Blake hash options. + * `dkLen` is output length. `key` is used in MAC mode. `salt` is used in + * KDF mode. + */ +export type Blake2Opts = { + /** Desired digest length in bytes. RFC 7693 uses 1..64 for blake2b and 1..32 for blake2s. */ + dkLen?: number; + /** Optional MAC key. */ + key?: Uint8Array; + /** Optional salt mixed into initialization. */ + salt?: Uint8Array; + /** Optional personalization bytes. */ + personalization?: Uint8Array; +}; +/** Internal base class for BLAKE2. */ +export declare abstract class _BLAKE2> implements Hash { + protected abstract compress(msg: Uint32Array, offset: number, isLast: boolean): void; + protected abstract get(): number[]; + protected abstract set(...args: number[]): void; + abstract destroy(): void; + protected buffer: Uint8Array; + protected buffer32: Uint32Array; + protected finished: boolean; + protected destroyed: boolean; + protected length: number; + protected pos: number; + readonly blockLen: number; + readonly outputLen: number; + readonly canXOF: boolean; + constructor(blockLen: number, outputLen: number); + update(data: TArg): this; + digestInto(out: TArg): void; + digest(): TRet; + _cloneInto(to?: T): T; + clone(): T; +} +/** Internal blake2b hash class with state stored as LE u32 low/high halves. */ +export declare class _BLAKE2b extends _BLAKE2<_BLAKE2b> { + private v0l; + private v0h; + private v1l; + private v1h; + private v2l; + private v2h; + private v3l; + private v3h; + private v4l; + private v4h; + private v5l; + private v5h; + private v6l; + private v6h; + private v7l; + private v7h; + constructor(opts?: Blake2Opts); + protected get(): [ + number, + number, + number, + number, + number, + number, + number, + number, + number, + number, + number, + number, + number, + number, + number, + number + ]; + protected set(v0l: number, v0h: number, v1l: number, v1h: number, v2l: number, v2h: number, v3l: number, v3h: number, v4l: number, v4h: number, v5l: number, v5h: number, v6l: number, v6h: number, v7l: number, v7h: number): void; + protected compress(msg: Uint32Array, offset: number, isLast: boolean): void; + destroy(): void; +} +/** + * Blake2b hash function. 64-bit. 1.5x slower than blake2s in JS. + * @param msg - message that would be hashed + * @param opts - Optional output, MAC, salt, and personalization settings. + * `dkLen` must be 1..64 bytes; `salt` and `personalization`, if present, + * must be 16 bytes each. See {@link Blake2Opts}. + * @returns Digest bytes. + * @example + * Hash a message with Blake2b. + * ```ts + * blake2b(new Uint8Array([97, 98, 99])); + * ``` + */ +export declare const blake2b: TRet>; +/** Internal type, 16 numbers. */ +export type _Num16 = { + v0: number; + v1: number; + v2: number; + v3: number; + v4: number; + v5: number; + v6: number; + v7: number; + v8: number; + v9: number; + v10: number; + v11: number; + v12: number; + v13: number; + v14: number; + v15: number; +}; +/** + * BLAKE2-compress core method. + * Runs only the round function over a caller-supplied local vector; callers initialize `v0..v15` + * and apply the final `h[i] ^= v[i] ^ v[i + 8]` fold themselves. + * @param s - flattened sigma schedule bytes + * @param offset - starting word offset inside `msg`, not a byte offset + * @param msg - message words + * @param rounds - round count to execute + * @param v0 - state word 0 + * @param v1 - state word 1 + * @param v2 - state word 2 + * @param v3 - state word 3 + * @param v4 - state word 4 + * @param v5 - state word 5 + * @param v6 - state word 6 + * @param v7 - state word 7 + * @param v8 - state word 8 + * @param v9 - state word 9 + * @param v10 - state word 10 + * @param v11 - state word 11 + * @param v12 - state word 12 + * @param v13 - state word 13 + * @param v14 - state word 14 + * @param v15 - state word 15 + * @returns Updated compression state words. + * @example + * Run the BLAKE2 compression core on zeroed state and message words. + * ```ts + * import { compress } from '@noble/hashes/blake2.js'; + * const state = compress( + * new Uint8Array(16), + * 0, + * new Uint32Array(16), + * 1, + * 0, 0, 0, 0, 0, 0, 0, 0, + * 0, 0, 0, 0, 0, 0, 0, 0 + * ); + * state.v0; + * ``` + */ +export declare function compress(s: TArg, offset: number, msg: TArg, rounds: number, v0: number, v1: number, v2: number, v3: number, v4: number, v5: number, v6: number, v7: number, v8: number, v9: number, v10: number, v11: number, v12: number, v13: number, v14: number, v15: number): _Num16; +/** Internal blake2s hash class. */ +export declare class _BLAKE2s extends _BLAKE2<_BLAKE2s> { + private v0; + private v1; + private v2; + private v3; + private v4; + private v5; + private v6; + private v7; + constructor(opts?: Blake2Opts); + protected get(): [number, number, number, number, number, number, number, number]; + protected set(v0: number, v1: number, v2: number, v3: number, v4: number, v5: number, v6: number, v7: number): void; + protected compress(msg: Uint32Array, offset: number, isLast: boolean): void; + destroy(): void; +} +/** + * Blake2s hash function. Focuses on 8-bit to 32-bit platforms. 1.5x faster than blake2b in JS. + * @param msg - message that would be hashed + * @param opts - Optional output, MAC, salt, and personalization settings. + * `dkLen` must be 1..32 bytes; `salt` and `personalization`, if present, + * must be 8 bytes each. See {@link Blake2Opts}. + * @returns Digest bytes. + * @example + * Hash a message with Blake2s. + * ```ts + * blake2s(new Uint8Array([97, 98, 99])); + * ``` + */ +export declare const blake2s: TRet>; +//# sourceMappingURL=blake2.d.ts.map \ No newline at end of file diff --git a/node_modules/@noble/hashes/blake2.d.ts.map b/node_modules/@noble/hashes/blake2.d.ts.map new file mode 100644 index 0000000..947c111 --- /dev/null +++ b/node_modules/@noble/hashes/blake2.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"blake2.d.ts","sourceRoot":"","sources":["src/blake2.ts"],"names":[],"mappings":"AASA,OAAO,EAKL,KAAK,KAAK,EACV,KAAK,IAAI,EACT,KAAK,IAAI,EACT,KAAK,IAAI,EACV,MAAM,YAAY,CAAC;AAEpB;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB,6FAA6F;IAC7F,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wBAAwB;IACxB,GAAG,CAAC,EAAE,UAAU,CAAC;IACjB,+CAA+C;IAC/C,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,sCAAsC;IACtC,eAAe,CAAC,EAAE,UAAU,CAAC;CAC9B,CAAC;AAiFF,sCAAsC;AACtC,8BAAsB,OAAO,CAAC,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,CAAE,YAAW,IAAI,CAAC,CAAC,CAAC;IACpE,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI;IACpF,SAAS,CAAC,QAAQ,CAAC,GAAG,IAAI,MAAM,EAAE;IAClC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI;IAC/C,QAAQ,CAAC,OAAO,IAAI,IAAI;IACxB,SAAS,CAAC,MAAM,EAAE,UAAU,CAAC;IAC7B,SAAS,CAAC,QAAQ,EAAE,WAAW,CAAC;IAChC,SAAS,CAAC,QAAQ,UAAS;IAC3B,SAAS,CAAC,SAAS,UAAS;IAC5B,SAAS,CAAC,MAAM,EAAE,MAAM,CAAK;IAC7B,SAAS,CAAC,GAAG,EAAE,MAAM,CAAK;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAS;gBAErB,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;IAQ/C,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,GAAG,IAAI;IAuCpC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,GAAG,IAAI;IAyBvC,MAAM,IAAI,IAAI,CAAC,UAAU,CAAC;IAQ1B,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC;IAcrB,KAAK,IAAI,CAAC;CAGX;AAED,+EAA+E;AAC/E,qBAAa,QAAS,SAAQ,OAAO,CAAC,QAAQ,CAAC;IAE7C,OAAO,CAAC,GAAG,CAAiB;IAC5B,OAAO,CAAC,GAAG,CAAiB;IAC5B,OAAO,CAAC,GAAG,CAAiB;IAC5B,OAAO,CAAC,GAAG,CAAiB;IAC5B,OAAO,CAAC,GAAG,CAAiB;IAC5B,OAAO,CAAC,GAAG,CAAiB;IAC5B,OAAO,CAAC,GAAG,CAAiB;IAC5B,OAAO,CAAC,GAAG,CAAiB;IAC5B,OAAO,CAAC,GAAG,CAAiB;IAC5B,OAAO,CAAC,GAAG,CAAiB;IAC5B,OAAO,CAAC,GAAG,CAAkB;IAC7B,OAAO,CAAC,GAAG,CAAkB;IAC7B,OAAO,CAAC,GAAG,CAAkB;IAC7B,OAAO,CAAC,GAAG,CAAkB;IAC7B,OAAO,CAAC,GAAG,CAAkB;IAC7B,OAAO,CAAC,GAAG,CAAkB;gBAEjB,IAAI,GAAE,UAAe;IAqCjC,SAAS,CAAC,GAAG,IAAI;QACf,MAAM;QAAE,MAAM;QAAE,MAAM;QAAE,MAAM;QAAE,MAAM;QAAE,MAAM;QAAE,MAAM;QAAE,MAAM;QAC9D,MAAM;QAAE,MAAM;QAAE,MAAM;QAAE,MAAM;QAAE,MAAM;QAAE,MAAM;QAAE,MAAM;QAAE,MAAM;KAC/D;IAKD,SAAS,CAAC,GAAG,CACX,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAClD,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAClD,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAClD,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GACjD,IAAI;IAkBP,SAAS,CAAC,QAAQ,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI;IAoD3E,OAAO,IAAI,IAAI;CAKhB;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,UAAU,CAAC,CAErD,CAAC;AAMF,iCAAiC;AAEjC,MAAM,MAAM,MAAM,GAAG;IACnB,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAC/C,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAC/C,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IACjD,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;CACpD,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,MAAM,EAClG,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAC9F,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GACnG,MAAM,CAsBR;AAKD,mCAAmC;AACnC,qBAAa,QAAS,SAAQ,OAAO,CAAC,QAAQ,CAAC;IAE7C,OAAO,CAAC,EAAE,CAAiB;IAC3B,OAAO,CAAC,EAAE,CAAiB;IAC3B,OAAO,CAAC,EAAE,CAAiB;IAC3B,OAAO,CAAC,EAAE,CAAiB;IAC3B,OAAO,CAAC,EAAE,CAAiB;IAC3B,OAAO,CAAC,EAAE,CAAiB;IAC3B,OAAO,CAAC,EAAE,CAAiB;IAC3B,OAAO,CAAC,EAAE,CAAiB;gBAEf,IAAI,GAAE,UAAe;IAgCjC,SAAS,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;IAKjF,SAAS,CAAC,GAAG,CACX,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAC7F,IAAI;IAUP,SAAS,CAAC,QAAQ,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI;IAoB3E,OAAO,IAAI,IAAI;CAKhB;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,UAAU,CAAC,CAErD,CAAC"} \ No newline at end of file diff --git a/node_modules/@noble/hashes/blake2.js b/node_modules/@noble/hashes/blake2.js new file mode 100644 index 0000000..7c80cef --- /dev/null +++ b/node_modules/@noble/hashes/blake2.js @@ -0,0 +1,501 @@ +/** + * blake2b (64-bit) & blake2s (8 to 32-bit) hash functions. + * b could have been faster, but there is no fast u64 in js, so s is 1.5x faster. + * @module + */ +import { BSIGMA, G1s, G2s } from "./_blake.js"; +import { SHA256_IV } from "./_md.js"; +import * as u64 from "./_u64.js"; +// prettier-ignore +import { abytes, aexists, anumber, aoutput, clean, createHasher, swap32IfBE, swap8IfBE, u32 } from "./utils.js"; +// Same IV words as `SHA512_IV`, but endian-swapped into LE u32 low/high halves +// for the BLAKE2b u64 helpers below. +const B2B_IV = /* @__PURE__ */ Uint32Array.from([ + 0xf3bcc908, 0x6a09e667, 0x84caa73b, 0xbb67ae85, 0xfe94f82b, 0x3c6ef372, 0x5f1d36f1, 0xa54ff53a, + 0xade682d1, 0x510e527f, 0x2b3e6c1f, 0x9b05688c, 0xfb41bd6b, 0x1f83d9ab, 0x137e2179, 0x5be0cd19, +]); +// Shared synchronous BLAKE2b work vector as LE u32 low/high halves. +const BBUF = /* @__PURE__ */ new Uint32Array(32); +// BLAKE2b G mix split into two half-rounds over LE u32 low/high limbs. +function G1b(a, b, c, d, msg, x) { + // NOTE: V is LE here + const Xl = msg[x], Xh = msg[x + 1]; // prettier-ignore + let Al = BBUF[2 * a], Ah = BBUF[2 * a + 1]; // prettier-ignore + let Bl = BBUF[2 * b], Bh = BBUF[2 * b + 1]; // prettier-ignore + let Cl = BBUF[2 * c], Ch = BBUF[2 * c + 1]; // prettier-ignore + let Dl = BBUF[2 * d], Dh = BBUF[2 * d + 1]; // prettier-ignore + // v[a] = (v[a] + v[b] + x) | 0; + let ll = u64.add3L(Al, Bl, Xl); + Ah = u64.add3H(ll, Ah, Bh, Xh); + Al = ll | 0; + // v[d] = rotr(v[d] ^ v[a], 32) + ({ Dh, Dl } = { Dh: Dh ^ Ah, Dl: Dl ^ Al }); + ({ Dh, Dl } = { Dh: u64.rotr32H(Dh, Dl), Dl: u64.rotr32L(Dh, Dl) }); + // v[c] = (v[c] + v[d]) | 0; + ({ h: Ch, l: Cl } = u64.add(Ch, Cl, Dh, Dl)); + // v[b] = rotr(v[b] ^ v[c], 24) + ({ Bh, Bl } = { Bh: Bh ^ Ch, Bl: Bl ^ Cl }); + ({ Bh, Bl } = { Bh: u64.rotrSH(Bh, Bl, 24), Bl: u64.rotrSL(Bh, Bl, 24) }); + ((BBUF[2 * a] = Al), (BBUF[2 * a + 1] = Ah)); + ((BBUF[2 * b] = Bl), (BBUF[2 * b + 1] = Bh)); + ((BBUF[2 * c] = Cl), (BBUF[2 * c + 1] = Ch)); + ((BBUF[2 * d] = Dl), (BBUF[2 * d + 1] = Dh)); +} +// Second half-round of the same LE-limb BLAKE2b G mix; `x` is the message word offset. +function G2b(a, b, c, d, msg, x) { + // NOTE: V is LE here + const Xl = msg[x], Xh = msg[x + 1]; // prettier-ignore + let Al = BBUF[2 * a], Ah = BBUF[2 * a + 1]; // prettier-ignore + let Bl = BBUF[2 * b], Bh = BBUF[2 * b + 1]; // prettier-ignore + let Cl = BBUF[2 * c], Ch = BBUF[2 * c + 1]; // prettier-ignore + let Dl = BBUF[2 * d], Dh = BBUF[2 * d + 1]; // prettier-ignore + // v[a] = (v[a] + v[b] + x) | 0; + let ll = u64.add3L(Al, Bl, Xl); + Ah = u64.add3H(ll, Ah, Bh, Xh); + Al = ll | 0; + // v[d] = rotr(v[d] ^ v[a], 16) + ({ Dh, Dl } = { Dh: Dh ^ Ah, Dl: Dl ^ Al }); + ({ Dh, Dl } = { Dh: u64.rotrSH(Dh, Dl, 16), Dl: u64.rotrSL(Dh, Dl, 16) }); + // v[c] = (v[c] + v[d]) | 0; + ({ h: Ch, l: Cl } = u64.add(Ch, Cl, Dh, Dl)); + // v[b] = rotr(v[b] ^ v[c], 63) + ({ Bh, Bl } = { Bh: Bh ^ Ch, Bl: Bl ^ Cl }); + ({ Bh, Bl } = { Bh: u64.rotrBH(Bh, Bl, 63), Bl: u64.rotrBL(Bh, Bl, 63) }); + ((BBUF[2 * a] = Al), (BBUF[2 * a + 1] = Ah)); + ((BBUF[2 * b] = Bl), (BBUF[2 * b + 1] = Bh)); + ((BBUF[2 * c] = Cl), (BBUF[2 * c + 1] = Ch)); + ((BBUF[2 * d] = Dl), (BBUF[2 * d + 1] = Dh)); +} +function checkBlake2Opts(outputLen, opts = {}, keyLen, saltLen, persLen) { + anumber(keyLen); + // RFC 7693 §2.1 requires digest length nn in 1..keyLen. + if (outputLen <= 0 || outputLen > keyLen) + throw new Error('outputLen bigger than keyLen'); + const { key, salt, personalization } = opts; + // This API uses `undefined` for the RFC 7693 `kk = 0` case, so a provided key must be non-empty. + if (key !== undefined && (key.length < 1 || key.length > keyLen)) + throw new Error('"key" expected to be undefined or of length=1..' + keyLen); + if (salt !== undefined) + abytes(salt, saltLen, 'salt'); + if (personalization !== undefined) + abytes(personalization, persLen, 'personalization'); +} +/** Internal base class for BLAKE2. */ +export class _BLAKE2 { + buffer; + buffer32; + finished = false; + destroyed = false; + length = 0; + pos = 0; + blockLen; + outputLen; + canXOF = false; + constructor(blockLen, outputLen) { + anumber(blockLen); + anumber(outputLen); + this.blockLen = blockLen; + this.outputLen = outputLen; + this.buffer = new Uint8Array(blockLen); + this.buffer32 = u32(this.buffer); + } + update(data) { + aexists(this); + abytes(data); + // Main difference with other hashes: there is flag for last block, + // so we cannot process current block before we know that there + // is the next one. This significantly complicates logic and reduces ability + // to do zero-copy processing + const { blockLen, buffer, buffer32 } = this; + const len = data.length; + const offset = data.byteOffset; + const buf = data.buffer; + for (let pos = 0; pos < len;) { + // If buffer is full and we still have input (don't process last block, same as blake2s) + if (this.pos === blockLen) { + swap32IfBE(buffer32); + this.compress(buffer32, 0, false); + swap32IfBE(buffer32); + this.pos = 0; + } + const take = Math.min(blockLen - this.pos, len - pos); + const dataOffset = offset + pos; + // Zero-copy only for full, 4-byte-aligned, non-final blocks. + if (take === blockLen && !(dataOffset % 4) && pos + take < len) { + const data32 = new Uint32Array(buf, dataOffset, Math.floor((len - pos) / 4)); + swap32IfBE(data32); + for (let pos32 = 0; pos + blockLen < len; pos32 += buffer32.length, pos += blockLen) { + this.length += blockLen; + this.compress(data32, pos32, false); + } + swap32IfBE(data32); + continue; + } + buffer.set(data.subarray(pos, pos + take), this.pos); + this.pos += take; + this.length += take; + pos += take; + } + return this; + } + digestInto(out) { + aexists(this); + aoutput(out, this); + const { pos, buffer32 } = this; + this.finished = true; + // Padding + clean(this.buffer.subarray(pos)); + swap32IfBE(buffer32); + this.compress(buffer32, 0, true); + swap32IfBE(buffer32); + // Reject unaligned views explicitly instead of hiding them behind a full scratch copy. + if (out.byteOffset & 3) + throw new RangeError('"digestInto() output" expected 4-byte aligned byteOffset, got ' + out.byteOffset); + const state = this.get(); + const out32 = u32(out); + const full = Math.floor(this.outputLen / 4); + for (let i = 0; i < full; i++) + out32[i] = swap8IfBE(state[i]); + const tail = this.outputLen % 4; + if (!tail) + return; + const off = full * 4; + const word = state[full]; + for (let i = 0; i < tail; i++) + out[off + i] = word >>> (8 * i); + } + digest() { + const { buffer, outputLen } = this; + this.digestInto(buffer); + // Return a copy so callers do not alias the instance scratch buffer used during finalization. + const res = buffer.slice(0, outputLen); + this.destroy(); + return res; + } + _cloneInto(to) { + const { buffer, length, finished, destroyed, outputLen, pos } = this; + // Recreate only `dkLen`; key/salt/personalization are already absorbed into the copied state. + to ||= new this.constructor({ dkLen: outputLen }); + to.set(...this.get()); + to.buffer.set(buffer); + to.destroyed = destroyed; + to.finished = finished; + to.length = length; + to.pos = pos; + // @ts-ignore + to.outputLen = outputLen; + return to; + } + clone() { + return this._cloneInto(); + } +} +/** Internal blake2b hash class with state stored as LE u32 low/high halves. */ +export class _BLAKE2b extends _BLAKE2 { + // Same IV words as SHA-512 / BLAKE2b, encoded as LE u32 low/high halves. + v0l = B2B_IV[0] | 0; + v0h = B2B_IV[1] | 0; + v1l = B2B_IV[2] | 0; + v1h = B2B_IV[3] | 0; + v2l = B2B_IV[4] | 0; + v2h = B2B_IV[5] | 0; + v3l = B2B_IV[6] | 0; + v3h = B2B_IV[7] | 0; + v4l = B2B_IV[8] | 0; + v4h = B2B_IV[9] | 0; + v5l = B2B_IV[10] | 0; + v5h = B2B_IV[11] | 0; + v6l = B2B_IV[12] | 0; + v6h = B2B_IV[13] | 0; + v7l = B2B_IV[14] | 0; + v7h = B2B_IV[15] | 0; + constructor(opts = {}) { + const olen = opts.dkLen === undefined ? 64 : opts.dkLen; + super(128, olen); + checkBlake2Opts(olen, opts, 64, 16, 16); + let { key, personalization, salt } = opts; + let keyLength = 0; + if (key !== undefined) { + abytes(key, undefined, 'key'); + keyLength = key.length; + } + // RFC 7693 §2.5: xor `p[0] = 0x0101kknn` into the low 32 bits of `h[0]`; + // the high 32 bits stay at `IV[0]`. + this.v0l ^= this.outputLen | (keyLength << 8) | (0x01 << 16) | (0x01 << 24); + if (salt !== undefined) { + abytes(salt, undefined, 'salt'); + const slt = u32(salt); + this.v4l ^= swap8IfBE(slt[0]); + this.v4h ^= swap8IfBE(slt[1]); + this.v5l ^= swap8IfBE(slt[2]); + this.v5h ^= swap8IfBE(slt[3]); + } + if (personalization !== undefined) { + abytes(personalization, undefined, 'personalization'); + const pers = u32(personalization); + this.v6l ^= swap8IfBE(pers[0]); + this.v6h ^= swap8IfBE(pers[1]); + this.v7l ^= swap8IfBE(pers[2]); + this.v7h ^= swap8IfBE(pers[3]); + } + if (key !== undefined) { + // Pad to blockLen and update + const tmp = new Uint8Array(this.blockLen); + tmp.set(key); + this.update(tmp); + } + } + // prettier-ignore + get() { + let { v0l, v0h, v1l, v1h, v2l, v2h, v3l, v3h, v4l, v4h, v5l, v5h, v6l, v6h, v7l, v7h } = this; + return [v0l, v0h, v1l, v1h, v2l, v2h, v3l, v3h, v4l, v4h, v5l, v5h, v6l, v6h, v7l, v7h]; + } + // prettier-ignore + set(v0l, v0h, v1l, v1h, v2l, v2h, v3l, v3h, v4l, v4h, v5l, v5h, v6l, v6h, v7l, v7h) { + this.v0l = v0l | 0; + this.v0h = v0h | 0; + this.v1l = v1l | 0; + this.v1h = v1h | 0; + this.v2l = v2l | 0; + this.v2h = v2h | 0; + this.v3l = v3l | 0; + this.v3h = v3h | 0; + this.v4l = v4l | 0; + this.v4h = v4h | 0; + this.v5l = v5l | 0; + this.v5h = v5h | 0; + this.v6l = v6l | 0; + this.v6h = v6h | 0; + this.v7l = v7l | 0; + this.v7h = v7h | 0; + } + compress(msg, offset, isLast) { + this.get().forEach((v, i) => (BBUF[i] = v)); // First half from state. + BBUF.set(B2B_IV, 16); // Second half from IV. + let { h, l } = u64.fromBig(BigInt(this.length)); + BBUF[24] = B2B_IV[8] ^ l; // Low word of the offset. + BBUF[25] = B2B_IV[9] ^ h; // High word. + // Invert all bits for last block + if (isLast) { + BBUF[28] = ~BBUF[28]; + BBUF[29] = ~BBUF[29]; + } + let j = 0; + const s = BSIGMA; + // SIGMA selects 64-bit message words; multiply by 2 because `msg` stores + // each word as [low32, high32]. + for (let i = 0; i < 12; i++) { + G1b(0, 4, 8, 12, msg, offset + 2 * s[j++]); + G2b(0, 4, 8, 12, msg, offset + 2 * s[j++]); + G1b(1, 5, 9, 13, msg, offset + 2 * s[j++]); + G2b(1, 5, 9, 13, msg, offset + 2 * s[j++]); + G1b(2, 6, 10, 14, msg, offset + 2 * s[j++]); + G2b(2, 6, 10, 14, msg, offset + 2 * s[j++]); + G1b(3, 7, 11, 15, msg, offset + 2 * s[j++]); + G2b(3, 7, 11, 15, msg, offset + 2 * s[j++]); + G1b(0, 5, 10, 15, msg, offset + 2 * s[j++]); + G2b(0, 5, 10, 15, msg, offset + 2 * s[j++]); + G1b(1, 6, 11, 12, msg, offset + 2 * s[j++]); + G2b(1, 6, 11, 12, msg, offset + 2 * s[j++]); + G1b(2, 7, 8, 13, msg, offset + 2 * s[j++]); + G2b(2, 7, 8, 13, msg, offset + 2 * s[j++]); + G1b(3, 4, 9, 14, msg, offset + 2 * s[j++]); + G2b(3, 4, 9, 14, msg, offset + 2 * s[j++]); + } + this.v0l ^= BBUF[0] ^ BBUF[16]; + this.v0h ^= BBUF[1] ^ BBUF[17]; + this.v1l ^= BBUF[2] ^ BBUF[18]; + this.v1h ^= BBUF[3] ^ BBUF[19]; + this.v2l ^= BBUF[4] ^ BBUF[20]; + this.v2h ^= BBUF[5] ^ BBUF[21]; + this.v3l ^= BBUF[6] ^ BBUF[22]; + this.v3h ^= BBUF[7] ^ BBUF[23]; + this.v4l ^= BBUF[8] ^ BBUF[24]; + this.v4h ^= BBUF[9] ^ BBUF[25]; + this.v5l ^= BBUF[10] ^ BBUF[26]; + this.v5h ^= BBUF[11] ^ BBUF[27]; + this.v6l ^= BBUF[12] ^ BBUF[28]; + this.v6h ^= BBUF[13] ^ BBUF[29]; + this.v7l ^= BBUF[14] ^ BBUF[30]; + this.v7h ^= BBUF[15] ^ BBUF[31]; + clean(BBUF); + } + destroy() { + this.destroyed = true; + clean(this.buffer32); + this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + } +} +/** + * Blake2b hash function. 64-bit. 1.5x slower than blake2s in JS. + * @param msg - message that would be hashed + * @param opts - Optional output, MAC, salt, and personalization settings. + * `dkLen` must be 1..64 bytes; `salt` and `personalization`, if present, + * must be 16 bytes each. See {@link Blake2Opts}. + * @returns Digest bytes. + * @example + * Hash a message with Blake2b. + * ```ts + * blake2b(new Uint8Array([97, 98, 99])); + * ``` + */ +export const blake2b = /* @__PURE__ */ createHasher((opts) => new _BLAKE2b(opts)); +/** + * BLAKE2-compress core method. + * Runs only the round function over a caller-supplied local vector; callers initialize `v0..v15` + * and apply the final `h[i] ^= v[i] ^ v[i + 8]` fold themselves. + * @param s - flattened sigma schedule bytes + * @param offset - starting word offset inside `msg`, not a byte offset + * @param msg - message words + * @param rounds - round count to execute + * @param v0 - state word 0 + * @param v1 - state word 1 + * @param v2 - state word 2 + * @param v3 - state word 3 + * @param v4 - state word 4 + * @param v5 - state word 5 + * @param v6 - state word 6 + * @param v7 - state word 7 + * @param v8 - state word 8 + * @param v9 - state word 9 + * @param v10 - state word 10 + * @param v11 - state word 11 + * @param v12 - state word 12 + * @param v13 - state word 13 + * @param v14 - state word 14 + * @param v15 - state word 15 + * @returns Updated compression state words. + * @example + * Run the BLAKE2 compression core on zeroed state and message words. + * ```ts + * import { compress } from '@noble/hashes/blake2.js'; + * const state = compress( + * new Uint8Array(16), + * 0, + * new Uint32Array(16), + * 1, + * 0, 0, 0, 0, 0, 0, 0, 0, + * 0, 0, 0, 0, 0, 0, 0, 0 + * ); + * state.v0; + * ``` + */ +// prettier-ignore +export function compress(s, offset, msg, rounds, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) { + let j = 0; + for (let i = 0; i < rounds; i++) { + ({ a: v0, b: v4, c: v8, d: v12 } = G1s(v0, v4, v8, v12, msg[offset + s[j++]])); + ({ a: v0, b: v4, c: v8, d: v12 } = G2s(v0, v4, v8, v12, msg[offset + s[j++]])); + ({ a: v1, b: v5, c: v9, d: v13 } = G1s(v1, v5, v9, v13, msg[offset + s[j++]])); + ({ a: v1, b: v5, c: v9, d: v13 } = G2s(v1, v5, v9, v13, msg[offset + s[j++]])); + ({ a: v2, b: v6, c: v10, d: v14 } = G1s(v2, v6, v10, v14, msg[offset + s[j++]])); + ({ a: v2, b: v6, c: v10, d: v14 } = G2s(v2, v6, v10, v14, msg[offset + s[j++]])); + ({ a: v3, b: v7, c: v11, d: v15 } = G1s(v3, v7, v11, v15, msg[offset + s[j++]])); + ({ a: v3, b: v7, c: v11, d: v15 } = G2s(v3, v7, v11, v15, msg[offset + s[j++]])); + ({ a: v0, b: v5, c: v10, d: v15 } = G1s(v0, v5, v10, v15, msg[offset + s[j++]])); + ({ a: v0, b: v5, c: v10, d: v15 } = G2s(v0, v5, v10, v15, msg[offset + s[j++]])); + ({ a: v1, b: v6, c: v11, d: v12 } = G1s(v1, v6, v11, v12, msg[offset + s[j++]])); + ({ a: v1, b: v6, c: v11, d: v12 } = G2s(v1, v6, v11, v12, msg[offset + s[j++]])); + ({ a: v2, b: v7, c: v8, d: v13 } = G1s(v2, v7, v8, v13, msg[offset + s[j++]])); + ({ a: v2, b: v7, c: v8, d: v13 } = G2s(v2, v7, v8, v13, msg[offset + s[j++]])); + ({ a: v3, b: v4, c: v9, d: v14 } = G1s(v3, v4, v9, v14, msg[offset + s[j++]])); + ({ a: v3, b: v4, c: v9, d: v14 } = G2s(v3, v4, v9, v14, msg[offset + s[j++]])); + } + return { v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 }; +} +// Blake2s reuses the SHA-256 IV words as-is. +const B2S_IV = /* @__PURE__ */ SHA256_IV.slice(); +/** Internal blake2s hash class. */ +export class _BLAKE2s extends _BLAKE2 { + // Internal state, same as SHA-256 + v0 = B2S_IV[0] | 0; + v1 = B2S_IV[1] | 0; + v2 = B2S_IV[2] | 0; + v3 = B2S_IV[3] | 0; + v4 = B2S_IV[4] | 0; + v5 = B2S_IV[5] | 0; + v6 = B2S_IV[6] | 0; + v7 = B2S_IV[7] | 0; + constructor(opts = {}) { + const olen = opts.dkLen === undefined ? 32 : opts.dkLen; + super(64, olen); + checkBlake2Opts(olen, opts, 32, 8, 8); + let { key, personalization, salt } = opts; + let keyLength = 0; + if (key !== undefined) { + abytes(key, undefined, 'key'); + keyLength = key.length; + } + // RFC 7693 §2.5: xor `p[0] = 0x0101kknn` directly into `h[0]`, since + // BLAKE2s stores each state word as one `u32`. + this.v0 ^= this.outputLen | (keyLength << 8) | (0x01 << 16) | (0x01 << 24); + if (salt !== undefined) { + abytes(salt, undefined, 'salt'); + const slt = u32(salt); + this.v4 ^= swap8IfBE(slt[0]); + this.v5 ^= swap8IfBE(slt[1]); + } + if (personalization !== undefined) { + abytes(personalization, undefined, 'personalization'); + const pers = u32(personalization); + this.v6 ^= swap8IfBE(pers[0]); + this.v7 ^= swap8IfBE(pers[1]); + } + if (key !== undefined) { + // Pad to blockLen and update + const tmp = new Uint8Array(this.blockLen); + tmp.set(key); + this.update(tmp); + } + } + get() { + const { v0, v1, v2, v3, v4, v5, v6, v7 } = this; + return [v0, v1, v2, v3, v4, v5, v6, v7]; + } + // prettier-ignore + set(v0, v1, v2, v3, v4, v5, v6, v7) { + this.v0 = v0 | 0; + this.v1 = v1 | 0; + this.v2 = v2 | 0; + this.v3 = v3 | 0; + this.v4 = v4 | 0; + this.v5 = v5 | 0; + this.v6 = v6 | 0; + this.v7 = v7 | 0; + } + compress(msg, offset, isLast) { + const { h, l } = u64.fromBig(BigInt(this.length)); + // Seed v8..v15 from the IV, xor the low/high 32-bit byte counter into + // v12/v13, and invert v14 on the final block. + // prettier-ignore + const { v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 } = compress(BSIGMA, offset, msg, 10, this.v0, this.v1, this.v2, this.v3, this.v4, this.v5, this.v6, this.v7, B2S_IV[0], B2S_IV[1], B2S_IV[2], B2S_IV[3], l ^ B2S_IV[4], h ^ B2S_IV[5], isLast ? ~B2S_IV[6] : B2S_IV[6], B2S_IV[7]); + this.v0 ^= v0 ^ v8; + this.v1 ^= v1 ^ v9; + this.v2 ^= v2 ^ v10; + this.v3 ^= v3 ^ v11; + this.v4 ^= v4 ^ v12; + this.v5 ^= v5 ^ v13; + this.v6 ^= v6 ^ v14; + this.v7 ^= v7 ^ v15; + } + destroy() { + this.destroyed = true; + clean(this.buffer32); + this.set(0, 0, 0, 0, 0, 0, 0, 0); + } +} +/** + * Blake2s hash function. Focuses on 8-bit to 32-bit platforms. 1.5x faster than blake2b in JS. + * @param msg - message that would be hashed + * @param opts - Optional output, MAC, salt, and personalization settings. + * `dkLen` must be 1..32 bytes; `salt` and `personalization`, if present, + * must be 8 bytes each. See {@link Blake2Opts}. + * @returns Digest bytes. + * @example + * Hash a message with Blake2s. + * ```ts + * blake2s(new Uint8Array([97, 98, 99])); + * ``` + */ +export const blake2s = /* @__PURE__ */ createHasher((opts) => new _BLAKE2s(opts)); +//# sourceMappingURL=blake2.js.map \ No newline at end of file diff --git a/node_modules/@noble/hashes/blake2.js.map b/node_modules/@noble/hashes/blake2.js.map new file mode 100644 index 0000000..2f8733f --- /dev/null +++ b/node_modules/@noble/hashes/blake2.js.map @@ -0,0 +1 @@ +{"version":3,"file":"blake2.js","sourceRoot":"","sources":["src/blake2.ts"],"names":[],"mappings":"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,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC3C,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC3C,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC3C,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC3C,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC5C,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC5C,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC5C,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAE5C,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC5C,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC5C,GAAG,CAAC,CAAC,EAAE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,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/E,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACjF,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACjF,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACjF,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAEjF,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACjF,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACjF,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACjF,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACjF,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/E,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/E,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAA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"} \ No newline at end of file diff --git a/node_modules/@noble/hashes/blake3.d.ts b/node_modules/@noble/hashes/blake3.d.ts new file mode 100644 index 0000000..1fd4cc7 --- /dev/null +++ b/node_modules/@noble/hashes/blake3.d.ts @@ -0,0 +1,68 @@ +import { _BLAKE2 } from './blake2.ts'; +import { type CHashXOF, type HashXOF, type TArg, type TRet } from './utils.ts'; +/** + * Ensure to use EITHER `key` OR `context`, not both. + * + * * `key`: 32-byte MAC key. + * * `context`: caller-encoded KDF context bytes. If your protocol defines a + * string context, encode it before passing it here. + * A good default format for the original context string is + * "[application] [commit timestamp] [purpose]". + */ +export type Blake3Opts = { + /** Desired digest length in bytes. The BLAKE3 spec allows 0..2^64-1 bytes of output. */ + dkLen?: number; + /** Optional 32-byte MAC key. */ + key?: Uint8Array; + /** Optional KDF context bytes. */ + context?: Uint8Array; +}; +/** Blake3 hash. Can be used as MAC and KDF with caller-encoded context bytes. */ +export declare class _BLAKE3 extends _BLAKE2<_BLAKE3> implements HashXOF<_BLAKE3> { + readonly canXOF = true; + private chunkPos; + private chunksDone; + private flags; + private IV; + private state; + private stack; + private posOut; + private bufferOut32; + private bufferOut; + private chunkOut; + private enableXOF; + constructor(opts?: Blake3Opts, flags?: number); + protected get(): []; + protected set(): void; + private b2Compress; + protected compress(buf: Uint32Array, bufPos?: number, isLast?: boolean): void; + _cloneInto(to?: _BLAKE3): _BLAKE3; + destroy(): void; + private b2CompressOut; + protected finish(): void; + private writeInto; + xofInto(out: TArg): TRet; + xof(bytes: number): TRet; + digestInto(out: TArg): void; + digest(): TRet; +} +/** + * BLAKE3 hash function. Can be used as MAC and KDF. + * @param msg - message that would be hashed + * @param opts - Optional output, MAC, or KDF configuration. `key` must be + * exactly 32 bytes, `context` is caller-encoded bytes, and `dkLen` can be + * 0..2^64-1 via the XOF-backed output path. See {@link Blake3Opts}. + * @returns Digest bytes. + * @example + * Hash, MAC, or derive key material with BLAKE3. + * ```ts + * import { blake3 } from '@noble/hashes/blake3.js'; + * import { utf8ToBytes } from '@noble/hashes/utils.js'; + * const data = new Uint8Array(32); + * const hash = blake3(data); + * const mac = blake3(data, { key: new Uint8Array(32) }); + * const kdf = blake3(data, { context: utf8ToBytes('application name') }); + * ``` + */ +export declare const blake3: TRet>; +//# sourceMappingURL=blake3.d.ts.map \ No newline at end of file diff --git a/node_modules/@noble/hashes/blake3.d.ts.map b/node_modules/@noble/hashes/blake3.d.ts.map new file mode 100644 index 0000000..94e019e --- /dev/null +++ b/node_modules/@noble/hashes/blake3.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"blake3.d.ts","sourceRoot":"","sources":["src/blake3.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,OAAO,EAAY,MAAM,aAAa,CAAC;AAEhD,OAAO,EAML,KAAK,QAAQ,EACb,KAAK,OAAO,EACZ,KAAK,IAAI,EACT,KAAK,IAAI,EACV,MAAM,YAAY,CAAC;AA4BpB;;;;;;;;GAQG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB,wFAAwF;IACxF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gCAAgC;IAChC,GAAG,CAAC,EAAE,UAAU,CAAC;IACjB,kCAAkC;IAClC,OAAO,CAAC,EAAE,UAAU,CAAC;CACtB,CAAC;AAEF,iFAAiF;AACjF,qBAAa,OAAQ,SAAQ,OAAO,CAAC,OAAO,CAAE,YAAW,OAAO,CAAC,OAAO,CAAC;IACvE,QAAQ,CAAC,MAAM,QAAQ;IACvB,OAAO,CAAC,QAAQ,CAAK;IAGrB,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,EAAE,CAAc;IACxB,OAAO,CAAC,KAAK,CAAc;IAC3B,OAAO,CAAC,KAAK,CAAqB;IAElC,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,SAAS,CAAa;IAG9B,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,SAAS,CAAQ;gBAEb,IAAI,GAAE,UAAe,EAAE,KAAK,SAAI;IA6B5C,SAAS,CAAC,GAAG,IAAI,EAAE;IAGnB,SAAS,CAAC,GAAG,IAAI,IAAI;IAGrB,OAAO,CAAC,UAAU;IAmBlB,SAAS,CAAC,QAAQ,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,GAAE,MAAU,EAAE,MAAM,GAAE,OAAe,GAAG,IAAI;IAkCvF,UAAU,CAAC,EAAE,CAAC,EAAE,OAAO,GAAG,OAAO;IAiBjC,OAAO,IAAI,IAAI;IAQf,OAAO,CAAC,aAAa;IA+BrB,SAAS,CAAC,MAAM,IAAI,IAAI;IAsBxB,OAAO,CAAC,SAAS;IAcjB,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC;IAIhD,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC;IAIpC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,GAAG,IAAI;IAQvC,MAAM,IAAI,IAAI,CAAC,UAAU,CAAC;CAK3B;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC,CAEtD,CAAC"} \ No newline at end of file diff --git a/node_modules/@noble/hashes/blake3.js b/node_modules/@noble/hashes/blake3.js new file mode 100644 index 0000000..a5718c2 --- /dev/null +++ b/node_modules/@noble/hashes/blake3.js @@ -0,0 +1,284 @@ +/** + * Blake3 fast hash is Blake2 with reduced security (round count). Can also be used as MAC & KDF. + * + * It is advertised as "the fastest cryptographic hash". However, it isn't true in JS. + * Why is this so slow? While it must be 6x faster than blake2b, perf diff is only 20%: + * + * * There is only 30% reduction in number of rounds from blake2s + * * Speed-up comes from tree structure, which is parallelized using SIMD & threading. + * These features are not present in JS, so we only get overhead from trees. + * * Parallelization only happens on 1024-byte chunks: there is no benefit for small inputs. + * * It is still possible to make it faster using: a) loop unrolling b) web workers c) wasm + * @module + */ +import { SHA256_IV } from "./_md.js"; +import { fromBig } from "./_u64.js"; +import { _BLAKE2, compress } from "./blake2.js"; +// prettier-ignore +import { abytes, aexists, anumber, aoutput, clean, copyBytes, createHasher, swap32IfBE, u32, u8 } from "./utils.js"; +// Constructor-time mode flags (`KEYED_HASH`, `DERIVE_*`) plus per-node tree +// flags (`CHUNK_*`, `PARENT`, `ROOT`). +const B3_Flags = { + CHUNK_START: 0b1, + CHUNK_END: 0b10, + PARENT: 0b100, + ROOT: 0b1000, + KEYED_HASH: 0b10000, + DERIVE_KEY_CONTEXT: 0b100000, + DERIVE_KEY_MATERIAL: 0b1000000, +}; +// Default BLAKE3 IV, cloned from the shared BLAKE2s / SHA-256 IV basis. +const B3_IV = /* @__PURE__ */ SHA256_IV.slice(); +// Seven 16-word rounds of BLAKE3 message schedule, generated by repeatedly +// permuting the identity row. +const B3_SIGMA = /* @__PURE__ */ (() => { + const Id = Array.from({ length: 16 }, (_, i) => i); + const permute = (arr) => [2, 6, 3, 10, 7, 0, 4, 13, 1, 11, 12, 5, 9, 14, 15, 8].map((i) => arr[i]); + const res = []; + for (let i = 0, v = Id; i < 7; i++, v = permute(v)) + res.push(...v); + return Uint8Array.from(res); +})(); +/** Blake3 hash. Can be used as MAC and KDF with caller-encoded context bytes. */ +export class _BLAKE3 extends _BLAKE2 { + canXOF = true; + chunkPos = 0; // Position of current block in chunk + // How many chunks we already have; exact while this stays within + // JS's safe-integer range. + chunksDone = 0; + flags = 0 | 0; + IV; + state; + stack = []; + // Output + posOut = 0; + bufferOut32 = new Uint32Array(16); + bufferOut; + // Index of output chunk; exact while this stays within JS's + // safe-integer range. + chunkOut = 0; + enableXOF = true; + constructor(opts = {}, flags = 0) { + super(64, opts.dkLen === undefined ? 32 : opts.dkLen); + const { key, context } = opts; + const hasContext = context !== undefined; + if (key !== undefined) { + if (hasContext) + throw new Error('Only "key" or "context" can be specified at same time'); + abytes(key, 32, 'key'); + const k = copyBytes(key); + this.IV = u32(k); + swap32IfBE(this.IV); + this.flags = flags | B3_Flags.KEYED_HASH; + } + else if (hasContext) { + abytes(context, undefined, 'context'); + const ctx = context; + const contextKey = new _BLAKE3({ dkLen: 32 }, B3_Flags.DERIVE_KEY_CONTEXT) + .update(ctx) + .digest(); + this.IV = u32(contextKey); + swap32IfBE(this.IV); + this.flags = flags | B3_Flags.DERIVE_KEY_MATERIAL; + } + else { + this.IV = B3_IV.slice(); + this.flags = flags; + } + this.state = this.IV.slice(); + this.bufferOut = u8(this.bufferOut32); + } + // _BLAKE2's scalar-state hooks are unused here: BLAKE3 keeps its tree/XOF state in arrays and + // copies it directly in _cloneInto(). + get() { + return []; + } + set() { } + // Truncated chunk/parent compression: seed v8..v15 as IV[0..3], t0, t1, + // block length, and flags, then keep only the first 8 output words. + b2Compress(counter, flags, buf, bufPos = 0) { + const { state: s, pos } = this; + const { h, l } = fromBig(BigInt(counter), true); + // prettier-ignore + const { v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 } = compress(B3_SIGMA, bufPos, buf, 7, s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], B3_IV[0], B3_IV[1], B3_IV[2], B3_IV[3], h, l, pos, flags); + s[0] = v0 ^ v8; + s[1] = v1 ^ v9; + s[2] = v2 ^ v10; + s[3] = v3 ^ v11; + s[4] = v4 ^ v12; + s[5] = v5 ^ v13; + s[6] = v6 ^ v14; + s[7] = v7 ^ v15; + } + compress(buf, bufPos = 0, isLast = false) { + // Compress last block + let flags = this.flags; + if (!this.chunkPos) + flags |= B3_Flags.CHUNK_START; + if (this.chunkPos === 15 || isLast) + flags |= B3_Flags.CHUNK_END; + if (!isLast) + this.pos = this.blockLen; + this.b2Compress(this.chunksDone, flags, buf, bufPos); + this.chunkPos += 1; + // If current block is last in chunk (16 blocks), then compress chunks + if (this.chunkPos === 16 || isLast) { + let chunk = this.state; + this.state = this.IV.slice(); + // If not the last one, compress only when there are trailing zeros in chunk counter + // Chunks are used as a binary tree where the current stack is the path. + // Zero means the current leaf is finished and can be compressed. + // 1 (001) - leaf not finished (just push current chunk to stack) + // 2 (010) - leaf finished at depth=1 (merge with last elm on stack and push back) + // 3 (011) - last leaf not finished + // 4 (100) - leafs finished at depth=1 and depth=2 + for (let last, chunks = this.chunksDone + 1; isLast || !(chunks & 1); chunks >>= 1) { + if (!(last = this.stack.pop())) + break; + this.buffer32.set(last, 0); + this.buffer32.set(chunk, 8); + this.pos = this.blockLen; + this.b2Compress(0, this.flags | B3_Flags.PARENT, this.buffer32, 0); + chunk = this.state; + this.state = this.IV.slice(); + } + this.chunksDone++; + this.chunkPos = 0; + this.stack.push(chunk); + } + this.pos = 0; + } + _cloneInto(to) { + to = super._cloneInto(to); + const { IV, flags, state, chunkPos, posOut, chunkOut, stack, chunksDone } = this; + to.state.set(state.slice()); + // Clone each CV stack entry by value so extending or destroying the clone + // cannot alias the source tree state. + to.stack = stack.map((i) => Uint32Array.from(i)); + to.IV.set(IV); + to.flags = flags; + to.chunkPos = chunkPos; + to.chunksDone = chunksDone; + to.posOut = posOut; + to.chunkOut = chunkOut; + to.enableXOF = this.enableXOF; + to.bufferOut32.set(this.bufferOut32); + return to; + } + destroy() { + this.destroyed = true; + clean(this.state, this.buffer32, this.IV, this.bufferOut32); + clean(...this.stack); + } + // Root/XOF compression: rerun the same ROOT inputs with incrementing output + // counter `t` and materialize all 16 output words. + // Same as b2Compress, but doesn't modify state and returns 16 u32 array (instead of 8) + b2CompressOut() { + const { state: s, pos, flags, buffer32, bufferOut32: out32 } = this; + const { h, l } = fromBig(BigInt(this.chunkOut++)); + swap32IfBE(buffer32); + // prettier-ignore + const { v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 } = compress(B3_SIGMA, 0, buffer32, 7, s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], B3_IV[0], B3_IV[1], B3_IV[2], B3_IV[3], l, h, pos, flags); + out32[0] = v0 ^ v8; + out32[1] = v1 ^ v9; + out32[2] = v2 ^ v10; + out32[3] = v3 ^ v11; + out32[4] = v4 ^ v12; + out32[5] = v5 ^ v13; + out32[6] = v6 ^ v14; + out32[7] = v7 ^ v15; + out32[8] = s[0] ^ v8; + out32[9] = s[1] ^ v9; + out32[10] = s[2] ^ v10; + out32[11] = s[3] ^ v11; + out32[12] = s[4] ^ v12; + out32[13] = s[5] ^ v13; + out32[14] = s[6] ^ v14; + out32[15] = s[7] ^ v15; + swap32IfBE(buffer32); + swap32IfBE(out32); + this.posOut = 0; + } + finish() { + if (this.finished) + return; + this.finished = true; + // Padding + clean(this.buffer.subarray(this.pos)); + // Process last chunk + let flags = this.flags | B3_Flags.ROOT; + if (this.stack.length) { + // Finalize the current chunk first, then rerun the last parent + // compression as ROOT with t = 0 and b = 64. + flags |= B3_Flags.PARENT; + swap32IfBE(this.buffer32); + this.compress(this.buffer32, 0, true); + swap32IfBE(this.buffer32); + this.chunksDone = 0; + this.pos = this.blockLen; + } + else { + flags |= (!this.chunkPos ? B3_Flags.CHUNK_START : 0) | B3_Flags.CHUNK_END; + } + this.flags = flags; + this.b2CompressOut(); + } + writeInto(out) { + aexists(this, false); + abytes(out); + this.finish(); + const { blockLen, bufferOut } = this; + for (let pos = 0, len = out.length; pos < len;) { + if (this.posOut >= blockLen) + this.b2CompressOut(); + const take = Math.min(blockLen - this.posOut, len - pos); + out.set(bufferOut.subarray(this.posOut, this.posOut + take), pos); + this.posOut += take; + pos += take; + } + return out; + } + xofInto(out) { + if (!this.enableXOF) + throw new Error('XOF is not possible after digest call'); + return this.writeInto(out); + } + xof(bytes) { + anumber(bytes); + return this.xofInto(new Uint8Array(bytes)); + } + digestInto(out) { + aoutput(out, this); + if (this.finished) + throw new Error('digest() was already called'); + this.enableXOF = false; + // `aoutput(...)` allows oversized buffers; digestInto() must fill only the configured digest. + this.writeInto(out.subarray(0, this.outputLen)); + this.destroy(); + } + digest() { + const out = new Uint8Array(this.outputLen); + this.digestInto(out); + return out; + } +} +/** + * BLAKE3 hash function. Can be used as MAC and KDF. + * @param msg - message that would be hashed + * @param opts - Optional output, MAC, or KDF configuration. `key` must be + * exactly 32 bytes, `context` is caller-encoded bytes, and `dkLen` can be + * 0..2^64-1 via the XOF-backed output path. See {@link Blake3Opts}. + * @returns Digest bytes. + * @example + * Hash, MAC, or derive key material with BLAKE3. + * ```ts + * import { blake3 } from '@noble/hashes/blake3.js'; + * import { utf8ToBytes } from '@noble/hashes/utils.js'; + * const data = new Uint8Array(32); + * const hash = blake3(data); + * const mac = blake3(data, { key: new Uint8Array(32) }); + * const kdf = blake3(data, { context: utf8ToBytes('application name') }); + * ``` + */ +export const blake3 = /* @__PURE__ */ createHasher((opts = {}) => new _BLAKE3(opts)); +//# sourceMappingURL=blake3.js.map \ No newline at end of file diff --git a/node_modules/@noble/hashes/blake3.js.map b/node_modules/@noble/hashes/blake3.js.map new file mode 100644 index 0000000..40965f6 --- /dev/null +++ b/node_modules/@noble/hashes/blake3.js.map @@ -0,0 +1 @@ +{"version":3,"file":"blake3.js","sourceRoot":"","sources":["src/blake3.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@noble/hashes/eskdf.d.ts b/node_modules/@noble/hashes/eskdf.d.ts new file mode 100644 index 0000000..7ff4281 --- /dev/null +++ b/node_modules/@noble/hashes/eskdf.d.ts @@ -0,0 +1,92 @@ +import { type TRet } from './utils.ts'; +/** + * Scrypt KDF with the fixed ESKDF policy tuple `{ N: 2^19, r: 8, p: 1, dkLen: 32 }`. + * @param password - user password string, UTF-8 encoded before entering RFC 7914 + * @param salt - unique salt string, UTF-8 encoded before entering RFC 7914 + * @returns Derived 32-byte key. + * @example + * Derive the 32-byte scrypt key used by ESKDF. + * ```ts + * scrypt('password123', 'user@example.com'); + * ``` + */ +export declare function scrypt(password: string, salt: string): TRet; +/** + * PBKDF2-HMAC-SHA256 with the fixed ESKDF policy tuple `{ sha256, c: 2^17, dkLen: 32 }`. + * @param password - user password string, UTF-8 encoded before entering PBKDF2-HMAC-SHA-256 + * @param salt - unique salt string, UTF-8 encoded before entering PBKDF2-HMAC-SHA-256 + * @returns Derived 32-byte key. + * @example + * Derive the 32-byte PBKDF2 key used by ESKDF. + * ```ts + * pbkdf2('password123', 'user@example.com'); + * ``` + */ +export declare function pbkdf2(password: string, salt: string): TRet; +/** + * Derives main seed. Takes a lot of time; prefer the higher-level `eskdf(...)` + * flow unless you specifically need the raw main seed. + * Derives the main seed by xor'ing two branches: + * the scrypt branch uses a `0x01` separator byte on username/password, + * and the PBKDF2 branch uses `0x02`. + * Username and password strings are encoded by the underlying KDFs after the + * local separator bytes are appended. + * @param username - account identifier used as public salt + * @param password - user password string + * @returns Main 32-byte seed for the account. + * @throws If the username or password length is invalid. {@link Error} + * @example + * Derive the main ESKDF seed from username and password. + * ```ts + * deriveMainSeed('example-user', 'example-password'); + * ``` + */ +export declare function deriveMainSeed(username: string, password: string): TRet; +type AccountID = number | string; +type OptsLength = { + keyLength: number; +}; +type OptsMod = { + modulus: bigint; +}; +type KeyOpts = undefined | OptsLength | OptsMod; +/** Not using classes because constructor cannot be async. */ +export interface ESKDF { + /** + * Derives a child key. Child key will not be associated with any + * other child key because of properties of underlying KDF. + * + * @param protocol - 3-15 character protocol name + * @param accountId - numeric account identifier, or a string id for + * `password\d{0,3}`, `ssh`, `tor`, or `file` + * @param options - Optional child-key shaping parameters. See {@link KeyOpts}. + * @returns Derived child key bytes. + */ + deriveChildKey: (protocol: string, accountId: AccountID, options?: KeyOpts) => TRet; + /** Deletes the main seed from the ESKDF instance. */ + expire: () => void; + /** + * Human-readable fingerprint: first 6 bytes of + * `deriveChildKey('fingerprint', 0)`, formatted as uppercase + * colon-separated hex. + */ + fingerprint: string; +} +/** + * ESKDF + * @param username - username, email, or identifier, min: 8 characters, should have enough entropy + * @param password - password, min: 8 characters, should have enough entropy + * @returns Frozen API that derives child keys and exposes the account fingerprint. + * @throws If the username or password length is invalid. {@link Error} + * @example + * Derive account-specific child keys from the main ESKDF seed. + * ```ts + * const kdf = await eskdf('example-university', 'beginning-new-example'); + * const key = kdf.deriveChildKey('aes', 0); + * const fingerprint = kdf.fingerprint; + * kdf.expire(); + * ``` + */ +export declare function eskdf(username: string, password: string): Promise>; +export {}; +//# sourceMappingURL=eskdf.d.ts.map \ No newline at end of file diff --git a/node_modules/@noble/hashes/eskdf.d.ts.map b/node_modules/@noble/hashes/eskdf.d.ts.map new file mode 100644 index 0000000..d0a7953 --- /dev/null +++ b/node_modules/@noble/hashes/eskdf.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"eskdf.d.ts","sourceRoot":"","sources":["src/eskdf.ts"],"names":[],"mappings":"AAQA,OAAO,EAQL,KAAK,IAAI,EACV,MAAM,YAAY,CAAC;AAYpB;;;;;;;;;;GAUG;AACH,wBAAgB,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,CAEvE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,CAEvE;AAkBD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,CAanF;AAED,KAAK,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC;AAkCjC,KAAK,UAAU,GAAG;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC;AACxC,KAAK,OAAO,GAAG;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AACnC,KAAK,OAAO,GAAG,SAAS,GAAG,UAAU,GAAG,OAAO,CAAC;AA6ChD,6DAA6D;AAC7D,MAAM,WAAW,KAAK;IACpB;;;;;;;;;OASG;IACH,cAAc,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC,UAAU,CAAC,CAAC;IAChG,qDAAqD;IACrD,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB;;;;OAIG;IACH,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CA+BpF"} \ No newline at end of file diff --git a/node_modules/@noble/hashes/eskdf.js b/node_modules/@noble/hashes/eskdf.js new file mode 100644 index 0000000..5ea541d --- /dev/null +++ b/node_modules/@noble/hashes/eskdf.js @@ -0,0 +1,218 @@ +/** + * Experimental KDF for AES. + * @module + */ +import { hkdf } from "./hkdf.js"; +import { pbkdf2 as _pbkdf2 } from "./pbkdf2.js"; +import { scrypt as _scrypt } from "./scrypt.js"; +import { sha256 } from "./sha2.js"; +import { abytes, bytesToHex, clean, createView, hexToBytes, kdfInputToBytes, } from "./utils.js"; +// A tiny KDF for various applications like AES key-gen. +// Uses HKDF in a non-standard way, so it's not "KDF-secure", only "PRF-secure". +// Which is good enough: assume sha2-256 retained preimage resistance. +// Fixed ESKDF scrypt work factor: interactive-latency target with about 512 MiB RAM per derivation. +const SCRYPT_FACTOR = /* @__PURE__ */ (() => 2 ** 19)(); +// Fixed ESKDF PBKDF2 work factor: CPU-only companion branch in the same rough +// interactive-latency range. +const PBKDF2_FACTOR = /* @__PURE__ */ (() => 2 ** 17)(); +/** + * Scrypt KDF with the fixed ESKDF policy tuple `{ N: 2^19, r: 8, p: 1, dkLen: 32 }`. + * @param password - user password string, UTF-8 encoded before entering RFC 7914 + * @param salt - unique salt string, UTF-8 encoded before entering RFC 7914 + * @returns Derived 32-byte key. + * @example + * Derive the 32-byte scrypt key used by ESKDF. + * ```ts + * scrypt('password123', 'user@example.com'); + * ``` + */ +export function scrypt(password, salt) { + return _scrypt(password, salt, { N: SCRYPT_FACTOR, r: 8, p: 1, dkLen: 32 }); +} +/** + * PBKDF2-HMAC-SHA256 with the fixed ESKDF policy tuple `{ sha256, c: 2^17, dkLen: 32 }`. + * @param password - user password string, UTF-8 encoded before entering PBKDF2-HMAC-SHA-256 + * @param salt - unique salt string, UTF-8 encoded before entering PBKDF2-HMAC-SHA-256 + * @returns Derived 32-byte key. + * @example + * Derive the 32-byte PBKDF2 key used by ESKDF. + * ```ts + * pbkdf2('password123', 'user@example.com'); + * ``` + */ +export function pbkdf2(password, salt) { + return _pbkdf2(sha256, password, salt, { c: PBKDF2_FACTOR, dkLen: 32 }); +} +// Combines two 32-byte byte arrays into a fresh 32-byte result without aliasing either input. +function xor32(a, b) { + abytes(a, 32); + abytes(b, 32); + const arr = new Uint8Array(32); + for (let i = 0; i < 32; i++) { + arr[i] = a[i] ^ b[i]; + } + return arr; +} +// All local string length checks are in JS UTF-16 code units, not UTF-8 bytes. +function strHasLength(str, min, max) { + return typeof str === 'string' && str.length >= min && str.length <= max; +} +/** + * Derives main seed. Takes a lot of time; prefer the higher-level `eskdf(...)` + * flow unless you specifically need the raw main seed. + * Derives the main seed by xor'ing two branches: + * the scrypt branch uses a `0x01` separator byte on username/password, + * and the PBKDF2 branch uses `0x02`. + * Username and password strings are encoded by the underlying KDFs after the + * local separator bytes are appended. + * @param username - account identifier used as public salt + * @param password - user password string + * @returns Main 32-byte seed for the account. + * @throws If the username or password length is invalid. {@link Error} + * @example + * Derive the main ESKDF seed from username and password. + * ```ts + * deriveMainSeed('example-user', 'example-password'); + * ``` + */ +export function deriveMainSeed(username, password) { + if (!strHasLength(username, 8, 255)) + throw new Error('invalid username'); + if (!strHasLength(password, 8, 255)) + throw new Error('invalid password'); + // Keep the protocol separators as the literal bytes 0x01 / 0x02 even after minification. + // Embedding them as non-printable characters directly can be awkward across + // JS tooling and environments. + const codes = { _1: 1, _2: 2 }; + const sep = { s: String.fromCharCode(codes._1), p: String.fromCharCode(codes._2) }; + const scr = scrypt(password + sep.s, username + sep.s); + const pbk = pbkdf2(password + sep.p, username + sep.p); + const res = xor32(scr, pbk); + clean(scr, pbk); + return res; +} +/** + * Converts protocol & accountId pair to HKDF params: + * `info` is UTF-8 protocol bytes, numeric ids become 4-byte BE `salt`, + * and string ids become UTF-8 `salt` bytes. + */ +function getSaltInfo(protocol, accountId = 0) { + // Note that length here also repeats two lines below + // We do an additional length check here to reduce the scope of DoS attacks + if (!(strHasLength(protocol, 3, 15) && /^[a-z0-9]{3,15}$/.test(protocol))) { + throw new Error('invalid protocol'); + } + // Exact-match only: substring matches like `assh` / `mentor` must not widen the public whitelist. + const allowsStr = /^(password\d{0,3}|ssh|tor|file)$/.test(protocol); + let salt; // Assigned below: either 4-byte BE account bytes or UTF-8 account bytes. + if (typeof accountId === 'string') { + if (!allowsStr) + throw new Error('accountId must be a number'); + if (!strHasLength(accountId, 1, 255)) + throw new Error('accountId must be string of length 1..255'); + salt = kdfInputToBytes(accountId); + } + else if (Number.isSafeInteger(accountId)) { + if (accountId < 0 || accountId > Math.pow(2, 32) - 1) + throw new Error('invalid accountId'); + // Convert to Big Endian Uint32 + salt = new Uint8Array(4); + createView(salt).setUint32(0, accountId, false); + } + else { + throw new Error('accountId must be a number' + (allowsStr ? ' or string' : '')); + } + const info = kdfInputToBytes(protocol); + return { salt, info }; +} +// Local modulus-size helper, not a general bigint-byte-length primitive: +// `<= 128n` is rejected by ESKDF policy. +function countBytes(num) { + if (typeof num !== 'bigint' || num <= BigInt(128)) + throw new Error('invalid number'); + return Math.ceil(num.toString(2).length / 8); +} +/** + * Parses keyLength and modulus options to extract length of result key. + * If modulus is used, adds 64 bits to it per the FIPS 186-5 Appendix A.3.1 / + * A.4.1 extra-bits guidance. + */ +function getKeyLength(options) { + if (!options || typeof options !== 'object') + return 32; + const hasLen = 'keyLength' in options; + const hasMod = 'modulus' in options; + if (hasLen && hasMod) + throw new Error('cannot combine keyLength and modulus options'); + if (!hasLen && !hasMod) + throw new Error('must have either keyLength or modulus option'); + // FIPS 186-5 Appendix A.3.1 / A.4.1 calls for at least 64 extra bits. + const l = hasMod ? countBytes(options.modulus) + 8 : options.keyLength; + if (!(typeof l === 'number' && l >= 16 && l <= 8192)) + throw new Error('invalid keyLength'); + return l; +} +/** + * Converts key to bigint and divides it by modulus. Big Endian. + * Adapts FIPS 186-5 Appendix A.4.1: `getKeyLength()` already requested the + * extra 64-bit margin, and this step maps the result into `1..modulus-1`. + */ +function modReduceKey(key, modulus) { + const _1 = BigInt(1); + const num = BigInt('0x' + bytesToHex(key)); // check for ui8a, then bytesToNumber() + const res = (num % (modulus - _1)) + _1; // Remove 0 from output + if (res < _1) + throw new Error('expected positive number'); // Guard against bad values + // Strip the extra 64-bit margin that `getKeyLength()` requested + // for bias reduction. + const len = key.length - 8; + const hex = res.toString(16).padStart(len * 2, '0'); // numberToHex() + const bytes = hexToBytes(hex); + if (bytes.length !== len) + throw new Error('invalid length of result key'); + return bytes; +} +/** + * ESKDF + * @param username - username, email, or identifier, min: 8 characters, should have enough entropy + * @param password - password, min: 8 characters, should have enough entropy + * @returns Frozen API that derives child keys and exposes the account fingerprint. + * @throws If the username or password length is invalid. {@link Error} + * @example + * Derive account-specific child keys from the main ESKDF seed. + * ```ts + * const kdf = await eskdf('example-university', 'beginning-new-example'); + * const key = kdf.deriveChildKey('aes', 0); + * const fingerprint = kdf.fingerprint; + * kdf.expire(); + * ``` + */ +export async function eskdf(username, password) { + // We are using closure + object instead of class because + // we want to make `seed` non-accessible for any external function. + let seed = deriveMainSeed(username, password); + function deriveCK(protocol, accountId = 0, options) { + // Reject expired instances before deriving any HKDF inputs from the closure-held seed. + abytes(seed, 32); + const { salt, info } = getSaltInfo(protocol, accountId); // validate protocol & accountId + // Validate option shape and coarse length bounds; + // `hkdf()` still rejects non-integer lengths. + const keyLength = getKeyLength(options); + const key = hkdf(sha256, seed, salt, info, keyLength); + // Modulus has already been validated + return options && 'modulus' in options ? modReduceKey(key, options.modulus) : key; + } + function expire() { + // Overwrite the closure-held seed before dropping the reference. + if (seed) + seed.fill(1); + seed = undefined; + } + // prettier-ignore + const fingerprint = Array.from(deriveCK('fingerprint', 0)) + .slice(0, 6) + .map((char) => char.toString(16).padStart(2, '0').toUpperCase()) + .join(':'); + return Object.freeze({ deriveChildKey: deriveCK, expire, fingerprint }); +} +//# sourceMappingURL=eskdf.js.map \ No newline at end of file diff --git a/node_modules/@noble/hashes/eskdf.js.map b/node_modules/@noble/hashes/eskdf.js.map new file mode 100644 index 0000000..49209e5 --- /dev/null +++ b/node_modules/@noble/hashes/eskdf.js.map @@ -0,0 +1 @@ +{"version":3,"file":"eskdf.js","sourceRoot":"","sources":["src/eskdf.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@noble/hashes/hkdf.d.ts b/node_modules/@noble/hashes/hkdf.d.ts new file mode 100644 index 0000000..0ace1fe --- /dev/null +++ b/node_modules/@noble/hashes/hkdf.d.ts @@ -0,0 +1,64 @@ +import { type CHash, type TArg, type TRet } from './utils.ts'; +/** + * HKDF-extract from spec. Less important part. `HKDF-Extract(IKM, salt) -> PRK` + * Arguments position differs from spec (IKM is first one, since it is not optional) + * Local validation only checks `hash`; `ikm` / `salt` byte validation is delegated to `hmac()`. + * @param hash - hash function that would be used (e.g. sha256) + * @param ikm - input keying material, the initial key + * @param salt - optional salt value (a non-secret random value) + * @returns Pseudorandom key derived from input keying material. + * @example + * Run the HKDF extract step. + * ```ts + * import { extract } from '@noble/hashes/hkdf.js'; + * import { sha256 } from '@noble/hashes/sha2.js'; + * extract(sha256, new Uint8Array([1, 2, 3]), new Uint8Array([4, 5, 6])); + * ``` + */ +export declare function extract(hash: TArg, ikm: TArg, salt?: TArg): TRet; +/** + * HKDF-expand from the spec. The most important part. `HKDF-Expand(PRK, info, L) -> OKM` + * @param hash - hash function that would be used (e.g. sha256) + * @param prk - a pseudorandom key of at least HashLen octets + * (usually, the output from the extract step) + * @param info - optional context and application specific information (can be a zero-length string) + * @param length - length of output keying material in bytes. + * RFC 5869 §2.3 allows `0..255*HashLen`, so `0` returns an empty OKM. + * @returns Output keying material with the requested length. + * @throws If the requested output length exceeds the HKDF limit + * for the selected hash. {@link Error} + * @example + * Run the HKDF expand step. + * ```ts + * import { expand } from '@noble/hashes/hkdf.js'; + * import { sha256 } from '@noble/hashes/sha2.js'; + * expand(sha256, new Uint8Array(32), new Uint8Array([1, 2, 3]), 16); + * ``` + */ +export declare function expand(hash: TArg, prk: TArg, info?: TArg, length?: number): TRet; +/** + * HKDF (RFC 5869): derive keys from an initial input. + * Combines hkdf_extract + hkdf_expand in one step + * @param hash - hash function that would be used (e.g. sha256) + * @param ikm - input keying material, the initial key + * @param salt - optional salt value (a non-secret random value) + * @param info - optional context and application specific information bytes + * @param length - length of output keying material in bytes. + * RFC 5869 §2.3 allows `0..255*HashLen`, so `0` returns an empty OKM. + * @returns Output keying material derived from the input key. + * @throws If the requested output length exceeds the HKDF limit + * for the selected hash. {@link Error} + * @example + * HKDF (RFC 5869): derive keys from an initial input. + * ```ts + * import { hkdf } from '@noble/hashes/hkdf.js'; + * import { sha256 } from '@noble/hashes/sha2.js'; + * import { randomBytes, utf8ToBytes } from '@noble/hashes/utils.js'; + * const inputKey = randomBytes(32); + * const salt = randomBytes(32); + * const info = utf8ToBytes('application-key'); + * const okm = hkdf(sha256, inputKey, salt, info, 32); + * ``` + */ +export declare const hkdf: (hash: TArg, ikm: TArg, salt: TArg, info: TArg, length: number) => TRet; +//# sourceMappingURL=hkdf.d.ts.map \ No newline at end of file diff --git a/node_modules/@noble/hashes/hkdf.d.ts.map b/node_modules/@noble/hashes/hkdf.d.ts.map new file mode 100644 index 0000000..9b6a97f --- /dev/null +++ b/node_modules/@noble/hashes/hkdf.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"hkdf.d.ts","sourceRoot":"","sources":["src/hkdf.ts"],"names":[],"mappings":"AAMA,OAAO,EAA0B,KAAK,KAAK,EAAS,KAAK,IAAI,EAAE,KAAK,IAAI,EAAE,MAAM,YAAY,CAAC;AAE7F;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,OAAO,CACrB,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,EACjB,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,EACrB,IAAI,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,GACtB,IAAI,CAAC,UAAU,CAAC,CAOlB;AAQD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,MAAM,CACpB,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,EACjB,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,EACrB,IAAI,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,EACvB,MAAM,GAAE,MAAW,GAClB,IAAI,CAAC,UAAU,CAAC,CAiClB;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,IAAI,GACf,MAAM,IAAI,CAAC,KAAK,CAAC,EACjB,KAAK,IAAI,CAAC,UAAU,CAAC,EACrB,MAAM,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC,EAClC,MAAM,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC,EAClC,QAAQ,MAAM,KACb,IAAI,CAAC,UAAU,CAAyD,CAAC"} \ No newline at end of file diff --git a/node_modules/@noble/hashes/hkdf.js b/node_modules/@noble/hashes/hkdf.js new file mode 100644 index 0000000..ccb0130 --- /dev/null +++ b/node_modules/@noble/hashes/hkdf.js @@ -0,0 +1,120 @@ +/** + * HKDF (RFC 5869): extract + expand in one step. + * See {@link https://soatok.blog/2021/11/17/understanding-hkdf/}. + * @module + */ +import { hmac } from "./hmac.js"; +import { abytes, ahash, anumber, clean } from "./utils.js"; +/** + * HKDF-extract from spec. Less important part. `HKDF-Extract(IKM, salt) -> PRK` + * Arguments position differs from spec (IKM is first one, since it is not optional) + * Local validation only checks `hash`; `ikm` / `salt` byte validation is delegated to `hmac()`. + * @param hash - hash function that would be used (e.g. sha256) + * @param ikm - input keying material, the initial key + * @param salt - optional salt value (a non-secret random value) + * @returns Pseudorandom key derived from input keying material. + * @example + * Run the HKDF extract step. + * ```ts + * import { extract } from '@noble/hashes/hkdf.js'; + * import { sha256 } from '@noble/hashes/sha2.js'; + * extract(sha256, new Uint8Array([1, 2, 3]), new Uint8Array([4, 5, 6])); + * ``` + */ +export function extract(hash, ikm, salt) { + ahash(hash); + // NOTE: some libraries treat zero-length array as 'not provided'; + // we don't, since we have undefined as 'not provided' + // https://github.com/RustCrypto/KDFs/issues/15 + if (salt === undefined) + salt = new Uint8Array(hash.outputLen); + return hmac(hash, salt, ikm); +} +// Shared mutable scratch byte for the RFC 5869 block counter `N`. +// Safe to reuse because `expand()` is synchronous and resets it with `clean(...)` before returning. +const HKDF_COUNTER = /* @__PURE__ */ Uint8Array.of(0); +// Shared RFC 5869 empty string for both `info === undefined` and the first-block `T(0)` input. +const EMPTY_BUFFER = /* @__PURE__ */ Uint8Array.of(); +/** + * HKDF-expand from the spec. The most important part. `HKDF-Expand(PRK, info, L) -> OKM` + * @param hash - hash function that would be used (e.g. sha256) + * @param prk - a pseudorandom key of at least HashLen octets + * (usually, the output from the extract step) + * @param info - optional context and application specific information (can be a zero-length string) + * @param length - length of output keying material in bytes. + * RFC 5869 §2.3 allows `0..255*HashLen`, so `0` returns an empty OKM. + * @returns Output keying material with the requested length. + * @throws If the requested output length exceeds the HKDF limit + * for the selected hash. {@link Error} + * @example + * Run the HKDF expand step. + * ```ts + * import { expand } from '@noble/hashes/hkdf.js'; + * import { sha256 } from '@noble/hashes/sha2.js'; + * expand(sha256, new Uint8Array(32), new Uint8Array([1, 2, 3]), 16); + * ``` + */ +export function expand(hash, prk, info, length = 32) { + ahash(hash); + anumber(length, 'length'); + abytes(prk, undefined, 'prk'); + const olen = hash.outputLen; + // RFC 5869 §2.3: PRK is "a pseudorandom key of at least HashLen octets". + if (prk.length < olen) + throw new Error('"prk" must be at least HashLen octets'); + // RFC 5869 §2.3 only bounds `L` by `<= 255*HashLen`; `L=0` is valid and yields empty OKM. + if (length > 255 * olen) + throw new Error('Length must be <= 255*HashLen'); + const blocks = Math.ceil(length / olen); + if (info === undefined) + info = EMPTY_BUFFER; + else + abytes(info, undefined, 'info'); + // first L(ength) octets of T + const okm = new Uint8Array(blocks * olen); + // Re-use HMAC instance between blocks + const HMAC = hmac.create(hash, prk); + const HMACTmp = HMAC._cloneInto(); + const T = new Uint8Array(HMAC.outputLen); + for (let counter = 0; counter < blocks; counter++) { + HKDF_COUNTER[0] = counter + 1; + // T(0) = empty string (zero length) + // T(N) = HMAC-Hash(PRK, T(N-1) | info | N) + HMACTmp.update(counter === 0 ? EMPTY_BUFFER : T) + .update(info) + .update(HKDF_COUNTER) + .digestInto(T); + okm.set(T, olen * counter); + HMAC._cloneInto(HMACTmp); + } + HMAC.destroy(); + HMACTmp.destroy(); + clean(T, HKDF_COUNTER); + return okm.slice(0, length); +} +/** + * HKDF (RFC 5869): derive keys from an initial input. + * Combines hkdf_extract + hkdf_expand in one step + * @param hash - hash function that would be used (e.g. sha256) + * @param ikm - input keying material, the initial key + * @param salt - optional salt value (a non-secret random value) + * @param info - optional context and application specific information bytes + * @param length - length of output keying material in bytes. + * RFC 5869 §2.3 allows `0..255*HashLen`, so `0` returns an empty OKM. + * @returns Output keying material derived from the input key. + * @throws If the requested output length exceeds the HKDF limit + * for the selected hash. {@link Error} + * @example + * HKDF (RFC 5869): derive keys from an initial input. + * ```ts + * import { hkdf } from '@noble/hashes/hkdf.js'; + * import { sha256 } from '@noble/hashes/sha2.js'; + * import { randomBytes, utf8ToBytes } from '@noble/hashes/utils.js'; + * const inputKey = randomBytes(32); + * const salt = randomBytes(32); + * const info = utf8ToBytes('application-key'); + * const okm = hkdf(sha256, inputKey, salt, info, 32); + * ``` + */ +export const hkdf = (hash, ikm, salt, info, length) => expand(hash, extract(hash, ikm, salt), info, length); +//# sourceMappingURL=hkdf.js.map \ No newline at end of file diff --git a/node_modules/@noble/hashes/hkdf.js.map b/node_modules/@noble/hashes/hkdf.js.map new file mode 100644 index 0000000..1a783f4 --- /dev/null +++ b/node_modules/@noble/hashes/hkdf.js.map @@ -0,0 +1 @@ +{"version":3,"file":"hkdf.js","sourceRoot":"","sources":["src/hkdf.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@noble/hashes/hmac.d.ts b/node_modules/@noble/hashes/hmac.d.ts new file mode 100644 index 0000000..7ec669d --- /dev/null +++ b/node_modules/@noble/hashes/hmac.d.ts @@ -0,0 +1,47 @@ +/** + * HMAC: RFC2104 message authentication code. + * @module + */ +import { type CHash, type Hash, type TArg, type TRet } from './utils.ts'; +/** + * Internal class for HMAC. + * Accepts any byte key, although RFC 2104 §3 recommends keys at least + * `HashLen` bytes long. + */ +export declare class _HMAC> implements Hash<_HMAC> { + oHash: T; + iHash: T; + blockLen: number; + outputLen: number; + canXOF: boolean; + private finished; + private destroyed; + constructor(hash: TArg, key: TArg); + update(buf: TArg): this; + digestInto(out: TArg): void; + digest(): TRet; + _cloneInto(to?: _HMAC): _HMAC; + clone(): _HMAC; + destroy(): void; +} +/** + * HMAC: RFC2104 message authentication code. + * @param hash - function that would be used e.g. sha256 + * @param key - authentication key bytes + * @param message - message bytes to authenticate + * @returns Authentication tag bytes. + * @example + * Compute an RFC 2104 HMAC. + * ```ts + * import { hmac } from '@noble/hashes/hmac.js'; + * import { sha256 } from '@noble/hashes/sha2.js'; + * const mac = hmac(sha256, new Uint8Array([1, 2, 3]), new Uint8Array([4, 5, 6])); + * ``` + */ +type HmacFn = { + (hash: TArg, key: TArg, message: TArg): TRet; + create(hash: TArg, key: TArg): TRet<_HMAC>; +}; +export declare const hmac: TRet; +export {}; +//# sourceMappingURL=hmac.d.ts.map \ No newline at end of file diff --git a/node_modules/@noble/hashes/hmac.d.ts.map b/node_modules/@noble/hashes/hmac.d.ts.map new file mode 100644 index 0000000..07fe4ab --- /dev/null +++ b/node_modules/@noble/hashes/hmac.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"hmac.d.ts","sourceRoot":"","sources":["src/hmac.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAML,KAAK,KAAK,EACV,KAAK,IAAI,EACT,KAAK,IAAI,EACT,KAAK,IAAI,EACV,MAAM,YAAY,CAAC;AAEpB;;;;GAIG;AACH,qBAAa,KAAK,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,CAAE,YAAW,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC7D,KAAK,EAAE,CAAC,CAAC;IACT,KAAK,EAAE,CAAC,CAAC;IACT,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,UAAS;IACf,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,SAAS,CAAS;gBAEd,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC;IAsBpD,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,GAAG,IAAI;IAKnC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,GAAG,IAAI;IAYvC,MAAM,IAAI,IAAI,CAAC,UAAU,CAAC;IAK1B,UAAU,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC;IAcnC,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC;IAGjB,OAAO,IAAI,IAAI;CAKhB;AAED;;;;;;;;;;;;;GAaG;AACH,KAAK,MAAM,GAAG;IACZ,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC;IACxF,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;CACpE,CAAC;AACF,eAAO,MAAM,IAAI,EAAE,IAAI,CAAC,MAAM,CAS1B,CAAC"} \ No newline at end of file diff --git a/node_modules/@noble/hashes/hmac.js b/node_modules/@noble/hashes/hmac.js new file mode 100644 index 0000000..fd066ea --- /dev/null +++ b/node_modules/@noble/hashes/hmac.js @@ -0,0 +1,93 @@ +/** + * HMAC: RFC2104 message authentication code. + * @module + */ +import { abytes, aexists, ahash, aoutput, clean, } from "./utils.js"; +/** + * Internal class for HMAC. + * Accepts any byte key, although RFC 2104 §3 recommends keys at least + * `HashLen` bytes long. + */ +export class _HMAC { + oHash; + iHash; + blockLen; + outputLen; + canXOF = false; + finished = false; + destroyed = false; + constructor(hash, key) { + ahash(hash); + abytes(key, undefined, 'key'); + this.iHash = hash.create(); + if (typeof this.iHash.update !== 'function') + throw new Error('Expected instance of class which extends utils.Hash'); + this.blockLen = this.iHash.blockLen; + this.outputLen = this.iHash.outputLen; + const blockLen = this.blockLen; + const pad = new Uint8Array(blockLen); + // blockLen can be bigger than outputLen + pad.set(key.length > blockLen ? hash.create().update(key).digest() : key); + for (let i = 0; i < pad.length; i++) + pad[i] ^= 0x36; + this.iHash.update(pad); + // By doing update (processing of the first block) of the outer hash here, + // we can re-use it between multiple calls via clone. + this.oHash = hash.create(); + // Undo internal XOR && apply outer XOR + for (let i = 0; i < pad.length; i++) + pad[i] ^= 0x36 ^ 0x5c; + this.oHash.update(pad); + clean(pad); + } + update(buf) { + aexists(this); + this.iHash.update(buf); + return this; + } + digestInto(out) { + aexists(this); + aoutput(out, this); + this.finished = true; + const buf = out.subarray(0, this.outputLen); + // Reuse the first outputLen bytes for the inner digest; the outer hash consumes them before + // overwriting that same prefix with the final tag, leaving any oversized tail untouched. + this.iHash.digestInto(buf); + this.oHash.update(buf); + this.oHash.digestInto(buf); + this.destroy(); + } + digest() { + const out = new Uint8Array(this.oHash.outputLen); + this.digestInto(out); + return out; + } + _cloneInto(to) { + // Create new instance without calling constructor since the key + // is already in state and we don't know it. + to ||= Object.create(Object.getPrototypeOf(this), {}); + const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this; + to = to; + to.finished = finished; + to.destroyed = destroyed; + to.blockLen = blockLen; + to.outputLen = outputLen; + to.oHash = oHash._cloneInto(to.oHash); + to.iHash = iHash._cloneInto(to.iHash); + return to; + } + clone() { + return this._cloneInto(); + } + destroy() { + this.destroyed = true; + this.oHash.destroy(); + this.iHash.destroy(); + } +} +export const hmac = /* @__PURE__ */ (() => { + const hmac_ = ((hash, key, message) => new _HMAC(hash, key).update(message).digest()); + hmac_.create = (hash, key) => new _HMAC(hash, key); + return hmac_; +})(); +//# sourceMappingURL=hmac.js.map \ No newline at end of file diff --git a/node_modules/@noble/hashes/hmac.js.map b/node_modules/@noble/hashes/hmac.js.map new file mode 100644 index 0000000..4f3ed1a --- /dev/null +++ b/node_modules/@noble/hashes/hmac.js.map @@ -0,0 +1 @@ +{"version":3,"file":"hmac.js","sourceRoot":"","sources":["src/hmac.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@noble/hashes/index.d.ts b/node_modules/@noble/hashes/index.d.ts new file mode 100644 index 0000000..e26a57a --- /dev/null +++ b/node_modules/@noble/hashes/index.d.ts @@ -0,0 +1,2 @@ +export {}; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/node_modules/@noble/hashes/index.d.ts.map b/node_modules/@noble/hashes/index.d.ts.map new file mode 100644 index 0000000..4e8c581 --- /dev/null +++ b/node_modules/@noble/hashes/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["src/index.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/node_modules/@noble/hashes/index.js b/node_modules/@noble/hashes/index.js new file mode 100644 index 0000000..5bcf959 --- /dev/null +++ b/node_modules/@noble/hashes/index.js @@ -0,0 +1,35 @@ +/** + * Audited & minimal JS implementation of hash functions, MACs, and KDFs. + * Check out individual modules. + * @module + * @example +```js +import { + sha256, sha384, sha512, sha224, sha512_224, sha512_256 +} from '@noble/hashes/sha2.js'; +import { + sha3_224, sha3_256, sha3_384, sha3_512, + keccak_224, keccak_256, keccak_384, keccak_512, + shake128, shake256 +} from '@noble/hashes/sha3.js'; +import { + cshake128, cshake256, + turboshake128, turboshake256, + kt128, kt256, + kmac128, kmac256, + tuplehash256, parallelhash256, + keccakprg +} from '@noble/hashes/sha3-addons.js'; +import { blake3 } from '@noble/hashes/blake3.js'; +import { blake2b, blake2s } from '@noble/hashes/blake2.js'; +import { hmac } from '@noble/hashes/hmac.js'; +import { hkdf } from '@noble/hashes/hkdf.js'; +import { pbkdf2, pbkdf2Async } from '@noble/hashes/pbkdf2.js'; +import { scrypt, scryptAsync } from '@noble/hashes/scrypt.js'; +import { md5, ripemd160, sha1 } from '@noble/hashes/legacy.js'; +import * as utils from '@noble/hashes/utils.js'; +``` + */ +throw new Error('root module cannot be imported: import submodules instead. Check out README'); +export {}; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/@noble/hashes/index.js.map b/node_modules/@noble/hashes/index.js.map new file mode 100644 index 0000000..9ad47d2 --- /dev/null +++ b/node_modules/@noble/hashes/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,IAAI,KAAK,CAAC,6EAA6E,CAAC,CAAC"} \ No newline at end of file diff --git a/node_modules/@noble/hashes/legacy.d.ts b/node_modules/@noble/hashes/legacy.d.ts new file mode 100644 index 0000000..1f9fd43 --- /dev/null +++ b/node_modules/@noble/hashes/legacy.d.ts @@ -0,0 +1,102 @@ +/** + +SHA1 (RFC 3174), MD5 (RFC 1321), and RIPEMD160 legacy, weak hash functions. +RFC 2286 only covers HMAC-RIPEMD160 wrapper material and test vectors, +not the base RIPEMD-160 compression spec. +Don't use them in a new protocol. What "weak" means: + +- Collisions can be made with 2^18 effort in MD5, 2^60 in SHA1, 2^80 in RIPEMD160. +- No practical pre-image attacks (only theoretical, 2^123.4) +- HMAC seems kinda ok: https://www.rfc-editor.org/rfc/rfc6151 + * @module + */ +import { HashMD } from './_md.ts'; +import { type CHash, type TRet } from './utils.ts'; +/** Internal SHA1 legacy hash class. */ +export declare class _SHA1 extends HashMD<_SHA1> { + private A; + private B; + private C; + private D; + private E; + constructor(); + protected get(): [number, number, number, number, number]; + protected set(A: number, B: number, C: number, D: number, E: number): void; + protected process(view: DataView, offset: number): void; + protected roundClean(): void; + destroy(): void; +} +/** + * SHA1 (RFC 3174) legacy hash function. It was cryptographically broken. + * @param msg - message bytes to hash + * @returns Digest bytes. + * @example + * Hash a message with SHA1. + * ```ts + * sha1(new Uint8Array([97, 98, 99])); + * ``` + */ +export declare const sha1: TRet; +/** Internal MD5 legacy hash class. */ +export declare class _MD5 extends HashMD<_MD5> { + private A; + private B; + private C; + private D; + constructor(); + protected get(): [number, number, number, number]; + protected set(A: number, B: number, C: number, D: number): void; + protected process(view: DataView, offset: number): void; + protected roundClean(): void; + destroy(): void; +} +/** + * MD5 (RFC 1321) legacy hash function. It was cryptographically broken. + * MD5 architecture is similar to SHA1, with some differences: + * - Reduced output length: 16 bytes (128 bit) instead of 20 + * - 64 rounds, instead of 80 + * - Little-endian: could be faster, but will require more code + * - Non-linear index selection: huge speed-up for unroll + * - Per round constants: more memory accesses, additional speed-up for unroll + * @param msg - message bytes to hash + * @returns Digest bytes. + * @example + * Hash a message with MD5. + * ```ts + * md5(new Uint8Array([97, 98, 99])); + * ``` + */ +export declare const md5: TRet; +/** + * Internal RIPEMD-160 legacy hash class. + * RFC 2286 only adds HMAC-RIPEMD160 material, not the core hash specification. + */ +export declare class _RIPEMD160 extends HashMD<_RIPEMD160> { + private h0; + private h1; + private h2; + private h3; + private h4; + constructor(); + protected get(): [number, number, number, number, number]; + protected set(h0: number, h1: number, h2: number, h3: number, h4: number): void; + protected process(view: DataView, offset: number): void; + protected roundClean(): void; + destroy(): void; +} +/** + * RIPEMD-160 - a legacy hash function from 1990s. + * RFC 2286 only covers HMAC-RIPEMD160 test material; the links below point + * at the base RIPEMD-160 references. + * * {@link https://homes.esat.kuleuven.be/~bosselae/ripemd160.html} + * * {@link https://homes.esat.kuleuven.be/~bosselae/ripemd160/pdf/AB-9601/AB-9601.pdf} + * @param msg - message bytes to hash + * @returns Digest bytes. + * @example + * Hash a message with RIPEMD-160. + * ```ts + * ripemd160(new Uint8Array([97, 98, 99])); + * ``` + */ +export declare const ripemd160: TRet; +//# sourceMappingURL=legacy.d.ts.map \ No newline at end of file diff --git a/node_modules/@noble/hashes/legacy.d.ts.map b/node_modules/@noble/hashes/legacy.d.ts.map new file mode 100644 index 0000000..538ff86 --- /dev/null +++ b/node_modules/@noble/hashes/legacy.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"legacy.d.ts","sourceRoot":"","sources":["src/legacy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAO,MAAM,EAAO,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,KAAK,KAAK,EAA6B,KAAK,IAAI,EAAE,MAAM,YAAY,CAAC;AAU9E,uCAAuC;AACvC,qBAAa,KAAM,SAAQ,MAAM,CAAC,KAAK,CAAC;IACtC,OAAO,CAAC,CAAC,CAAkB;IAC3B,OAAO,CAAC,CAAC,CAAkB;IAC3B,OAAO,CAAC,CAAC,CAAkB;IAC3B,OAAO,CAAC,CAAC,CAAkB;IAC3B,OAAO,CAAC,CAAC,CAAkB;;IAK3B,SAAS,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;IAIzD,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI;IAO1E,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAoCvD,SAAS,CAAC,UAAU,IAAI,IAAI;IAG5B,OAAO,IAAI,IAAI;CAOhB;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,IAAI,EAAE,IAAI,CAAC,KAAK,CAAmD,CAAC;AAcjF,sCAAsC;AACtC,qBAAa,IAAK,SAAQ,MAAM,CAAC,IAAI,CAAC;IACpC,OAAO,CAAC,CAAC,CAAiB;IAC1B,OAAO,CAAC,CAAC,CAAiB;IAC1B,OAAO,CAAC,CAAC,CAAiB;IAC1B,OAAO,CAAC,CAAC,CAAiB;;IAK1B,SAAS,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;IAIjD,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI;IAM/D,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAqCvD,SAAS,CAAC,UAAU,IAAI,IAAI;IAG5B,OAAO,IAAI,IAAI;CAOhB;AAED;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,GAAG,EAAE,IAAI,CAAC,KAAK,CAAkD,CAAC;AAmD/E;;;GAGG;AACH,qBAAa,UAAW,SAAQ,MAAM,CAAC,UAAU,CAAC;IAChD,OAAO,CAAC,EAAE,CAAkB;IAC5B,OAAO,CAAC,EAAE,CAAkB;IAC5B,OAAO,CAAC,EAAE,CAAkB;IAC5B,OAAO,CAAC,EAAE,CAAkB;IAC5B,OAAO,CAAC,EAAE,CAAkB;;IAK5B,SAAS,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;IAIzD,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI;IAO/E,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAoCvD,SAAS,CAAC,UAAU,IAAI,IAAI;IAG5B,OAAO,IAAI,IAAI;CAKhB;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,SAAS,EAAE,IAAI,CAAC,KAAK,CAAwD,CAAC"} \ No newline at end of file diff --git a/node_modules/@noble/hashes/legacy.js b/node_modules/@noble/hashes/legacy.js new file mode 100644 index 0000000..20c3b99 --- /dev/null +++ b/node_modules/@noble/hashes/legacy.js @@ -0,0 +1,327 @@ +/** + +SHA1 (RFC 3174), MD5 (RFC 1321), and RIPEMD160 legacy, weak hash functions. +RFC 2286 only covers HMAC-RIPEMD160 wrapper material and test vectors, +not the base RIPEMD-160 compression spec. +Don't use them in a new protocol. What "weak" means: + +- Collisions can be made with 2^18 effort in MD5, 2^60 in SHA1, 2^80 in RIPEMD160. +- No practical pre-image attacks (only theoretical, 2^123.4) +- HMAC seems kinda ok: https://www.rfc-editor.org/rfc/rfc6151 + * @module + */ +import { Chi, HashMD, Maj } from "./_md.js"; +import { clean, createHasher, rotl } from "./utils.js"; +/** Initial SHA-1 state from RFC 3174 §6.1. */ +const SHA1_IV = /* @__PURE__ */ Uint32Array.from([ + 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0, +]); +// Reusable 80-word SHA-1 message schedule buffer. +const SHA1_W = /* @__PURE__ */ new Uint32Array(80); +/** Internal SHA1 legacy hash class. */ +export class _SHA1 extends HashMD { + A = SHA1_IV[0] | 0; + B = SHA1_IV[1] | 0; + C = SHA1_IV[2] | 0; + D = SHA1_IV[3] | 0; + E = SHA1_IV[4] | 0; + constructor() { + super(64, 20, 8, false); + } + get() { + const { A, B, C, D, E } = this; + return [A, B, C, D, E]; + } + set(A, B, C, D, E) { + this.A = A | 0; + this.B = B | 0; + this.C = C | 0; + this.D = D | 0; + this.E = E | 0; + } + process(view, offset) { + for (let i = 0; i < 16; i++, offset += 4) + SHA1_W[i] = view.getUint32(offset, false); + for (let i = 16; i < 80; i++) + SHA1_W[i] = rotl(SHA1_W[i - 3] ^ SHA1_W[i - 8] ^ SHA1_W[i - 14] ^ SHA1_W[i - 16], 1); + // Compression function main loop, 80 rounds + let { A, B, C, D, E } = this; + for (let i = 0; i < 80; i++) { + let F, K; + if (i < 20) { + F = Chi(B, C, D); + K = 0x5a827999; + } + else if (i < 40) { + F = B ^ C ^ D; + K = 0x6ed9eba1; + } + else if (i < 60) { + F = Maj(B, C, D); + K = 0x8f1bbcdc; + } + else { + F = B ^ C ^ D; + K = 0xca62c1d6; + } + const T = (rotl(A, 5) + F + E + K + SHA1_W[i]) | 0; + E = D; + D = C; + C = rotl(B, 30); + B = A; + A = T; + } + // Add the compressed chunk to the current hash value + A = (A + this.A) | 0; + B = (B + this.B) | 0; + C = (C + this.C) | 0; + D = (D + this.D) | 0; + E = (E + this.E) | 0; + this.set(A, B, C, D, E); + } + roundClean() { + clean(SHA1_W); + } + destroy() { + // HashMD callers route post-destroy usability through `destroyed`; zeroizing alone still leaves + // update()/digest() callable on reused instances. + this.destroyed = true; + this.set(0, 0, 0, 0, 0); + clean(this.buffer); + } +} +/** + * SHA1 (RFC 3174) legacy hash function. It was cryptographically broken. + * @param msg - message bytes to hash + * @returns Digest bytes. + * @example + * Hash a message with SHA1. + * ```ts + * sha1(new Uint8Array([97, 98, 99])); + * ``` + */ +export const sha1 = /* @__PURE__ */ createHasher(() => new _SHA1()); +/** RFC 1321 `T[i]` uses `floor(2^32 * abs(sin(i)))`; this is the shared `2^32` scale factor. */ +const p32 = /* @__PURE__ */ Math.pow(2, 32); +/** RFC 1321 `T[1..64]` table. */ +const K = /* @__PURE__ */ Array.from({ length: 64 }, (_, i) => Math.floor(p32 * Math.abs(Math.sin(i + 1)))); +/** MD5 initial state from RFC 1321, stored as 4 u32 words. */ +const MD5_IV = /* @__PURE__ */ SHA1_IV.slice(0, 4); +// Reusable 16-word MD5 message block buffer. +const MD5_W = /* @__PURE__ */ new Uint32Array(16); +/** Internal MD5 legacy hash class. */ +export class _MD5 extends HashMD { + A = MD5_IV[0] | 0; + B = MD5_IV[1] | 0; + C = MD5_IV[2] | 0; + D = MD5_IV[3] | 0; + constructor() { + super(64, 16, 8, true); + } + get() { + const { A, B, C, D } = this; + return [A, B, C, D]; + } + set(A, B, C, D) { + this.A = A | 0; + this.B = B | 0; + this.C = C | 0; + this.D = D | 0; + } + process(view, offset) { + for (let i = 0; i < 16; i++, offset += 4) + MD5_W[i] = view.getUint32(offset, true); + // Compression function main loop, 64 rounds + let { A, B, C, D } = this; + for (let i = 0; i < 64; i++) { + let F, g, s; + if (i < 16) { + F = Chi(B, C, D); + g = i; + s = [7, 12, 17, 22]; + } + else if (i < 32) { + // RFC 1321 round 2 uses G(B,C,D) = (B & D) | (C & ~D), which is `Chi(D, B, C)`. + F = Chi(D, B, C); + g = (5 * i + 1) % 16; + s = [5, 9, 14, 20]; + } + else if (i < 48) { + F = B ^ C ^ D; + g = (3 * i + 5) % 16; + s = [4, 11, 16, 23]; + } + else { + F = C ^ (B | ~D); + g = (7 * i) % 16; + s = [6, 10, 15, 21]; + } + F = F + A + K[i] + MD5_W[g]; + A = D; + D = C; + C = B; + B = B + rotl(F, s[i % 4]); + } + // Add the compressed chunk to the current hash value + A = (A + this.A) | 0; + B = (B + this.B) | 0; + C = (C + this.C) | 0; + D = (D + this.D) | 0; + this.set(A, B, C, D); + } + roundClean() { + clean(MD5_W); + } + destroy() { + // HashMD callers route post-destroy usability through `destroyed`; zeroizing alone still leaves + // update()/digest() callable on reused instances. + this.destroyed = true; + this.set(0, 0, 0, 0); + clean(this.buffer); + } +} +/** + * MD5 (RFC 1321) legacy hash function. It was cryptographically broken. + * MD5 architecture is similar to SHA1, with some differences: + * - Reduced output length: 16 bytes (128 bit) instead of 20 + * - 64 rounds, instead of 80 + * - Little-endian: could be faster, but will require more code + * - Non-linear index selection: huge speed-up for unroll + * - Per round constants: more memory accesses, additional speed-up for unroll + * @param msg - message bytes to hash + * @returns Digest bytes. + * @example + * Hash a message with MD5. + * ```ts + * md5(new Uint8Array([97, 98, 99])); + * ``` + */ +export const md5 = /* @__PURE__ */ createHasher(() => new _MD5()); +// RIPEMD-160 +// Permutation repeatedly applied to derive the later RIPEMD-160 message-order tables. +const Rho160 = /* @__PURE__ */ Uint8Array.from([ + 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, +]); +const Id160 = /* @__PURE__ */ (() => Uint8Array.from(new Array(16).fill(0).map((_, i) => i)))(); +const Pi160 = /* @__PURE__ */ (() => Id160.map((i) => (9 * i + 5) % 16))(); +// Five left/right message-word orderings for the RIPEMD-160 dual-lane rounds. +const idxLR = /* @__PURE__ */ (() => { + const L = [Id160]; + const R = [Pi160]; + const res = [L, R]; + for (let i = 0; i < 4; i++) + for (let j of res) + j.push(j[i].map((k) => Rho160[k])); + return res; +})(); +const idxL = /* @__PURE__ */ (() => idxLR[0])(); +const idxR = /* @__PURE__ */ (() => idxLR[1])(); +// const [idxL, idxR] = idxLR; +// Base per-group shift table before the left/right message-order permutations are applied. +const shifts160 = /* @__PURE__ */ [ + [11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8], + [12, 13, 11, 15, 6, 9, 9, 7, 12, 15, 11, 13, 7, 8, 7, 7], + [13, 15, 14, 11, 7, 7, 6, 8, 13, 14, 13, 12, 5, 5, 6, 9], + [14, 11, 12, 14, 8, 6, 5, 5, 15, 12, 15, 14, 9, 9, 8, 6], + [15, 12, 13, 13, 9, 5, 8, 6, 14, 11, 12, 11, 8, 6, 5, 5], +].map((i) => Uint8Array.from(i)); +const shiftsL160 = /* @__PURE__ */ idxL.map((idx, i) => idx.map((j) => shifts160[i][j])); +const shiftsR160 = /* @__PURE__ */ idxR.map((idx, i) => idx.map((j) => shifts160[i][j])); +// Five left-lane additive constants for RIPEMD-160. +const Kl160 = /* @__PURE__ */ Uint32Array.from([ + 0x00000000, 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xa953fd4e, +]); +// Five right-lane additive constants for RIPEMD-160. +const Kr160 = /* @__PURE__ */ Uint32Array.from([ + 0x50a28be6, 0x5c4dd124, 0x6d703ef3, 0x7a6d76e9, 0x00000000, +]); +// Called `f()` in the spec; valid `group` values are 0..4, and out-of-range +// inputs currently fall through to the group-4 branch. +function ripemd_f(group, x, y, z) { + if (group === 0) + return x ^ y ^ z; + if (group === 1) + return (x & y) | (~x & z); + if (group === 2) + return (x | ~y) ^ z; + if (group === 3) + return (x & z) | (y & ~z); + return x ^ (y | ~z); +} +// Reusable 16-word RIPEMD-160 message block buffer. +const BUF_160 = /* @__PURE__ */ new Uint32Array(16); +/** + * Internal RIPEMD-160 legacy hash class. + * RFC 2286 only adds HMAC-RIPEMD160 material, not the core hash specification. + */ +export class _RIPEMD160 extends HashMD { + h0 = 0x67452301 | 0; + h1 = 0xefcdab89 | 0; + h2 = 0x98badcfe | 0; + h3 = 0x10325476 | 0; + h4 = 0xc3d2e1f0 | 0; + constructor() { + super(64, 20, 8, true); + } + get() { + const { h0, h1, h2, h3, h4 } = this; + return [h0, h1, h2, h3, h4]; + } + set(h0, h1, h2, h3, h4) { + this.h0 = h0 | 0; + this.h1 = h1 | 0; + this.h2 = h2 | 0; + this.h3 = h3 | 0; + this.h4 = h4 | 0; + } + process(view, offset) { + for (let i = 0; i < 16; i++, offset += 4) + BUF_160[i] = view.getUint32(offset, true); + // prettier-ignore + let al = this.h0 | 0, ar = al, bl = this.h1 | 0, br = bl, cl = this.h2 | 0, cr = cl, dl = this.h3 | 0, dr = dl, el = this.h4 | 0, er = el; + // Instead of iterating 0 to 80, we split it into 5 groups + // And use the groups in constants, functions, etc. Much simpler + for (let group = 0; group < 5; group++) { + const rGroup = 4 - group; + const hbl = Kl160[group], hbr = Kr160[group]; // prettier-ignore + const rl = idxL[group], rr = idxR[group]; // prettier-ignore + const sl = shiftsL160[group], sr = shiftsR160[group]; // prettier-ignore + for (let i = 0; i < 16; i++) { + const tl = (rotl(al + ripemd_f(group, bl, cl, dl) + BUF_160[rl[i]] + hbl, sl[i]) + el) | 0; + al = el, el = dl, dl = rotl(cl, 10) | 0, cl = bl, bl = tl; // prettier-ignore + } + // 2 loops are 10% faster + for (let i = 0; i < 16; i++) { + const tr = (rotl(ar + ripemd_f(rGroup, br, cr, dr) + BUF_160[rr[i]] + hbr, sr[i]) + er) | 0; + ar = er, er = dr, dr = rotl(cr, 10) | 0, cr = br, br = tr; // prettier-ignore + } + } + // Add the compressed chunk to the current hash value + // Final recombination cross-adds the left/right lane accumulators into the next h0..h4 order. + this.set((this.h1 + cl + dr) | 0, (this.h2 + dl + er) | 0, (this.h3 + el + ar) | 0, (this.h4 + al + br) | 0, (this.h0 + bl + cr) | 0); + } + roundClean() { + clean(BUF_160); + } + destroy() { + this.destroyed = true; + clean(this.buffer); + this.set(0, 0, 0, 0, 0); + } +} +/** + * RIPEMD-160 - a legacy hash function from 1990s. + * RFC 2286 only covers HMAC-RIPEMD160 test material; the links below point + * at the base RIPEMD-160 references. + * * {@link https://homes.esat.kuleuven.be/~bosselae/ripemd160.html} + * * {@link https://homes.esat.kuleuven.be/~bosselae/ripemd160/pdf/AB-9601/AB-9601.pdf} + * @param msg - message bytes to hash + * @returns Digest bytes. + * @example + * Hash a message with RIPEMD-160. + * ```ts + * ripemd160(new Uint8Array([97, 98, 99])); + * ``` + */ +export const ripemd160 = /* @__PURE__ */ createHasher(() => new _RIPEMD160()); +//# sourceMappingURL=legacy.js.map \ No newline at end of file diff --git a/node_modules/@noble/hashes/legacy.js.map b/node_modules/@noble/hashes/legacy.js.map new file mode 100644 index 0000000..c36f29e --- /dev/null +++ b/node_modules/@noble/hashes/legacy.js.map @@ -0,0 +1 @@ +{"version":3,"file":"legacy.js","sourceRoot":"","sources":["src/legacy.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@noble/hashes/package.json b/node_modules/@noble/hashes/package.json new file mode 100644 index 0000000..0ace74d --- /dev/null +++ b/node_modules/@noble/hashes/package.json @@ -0,0 +1,97 @@ +{ + "name": "@noble/hashes", + "version": "2.2.0", + "description": "Audited & minimal 0-dependency JS implementation of SHA, RIPEMD, BLAKE, HMAC, HKDF, PBKDF & Scrypt", + "files": [ + "*.js", + "*.js.map", + "*.d.ts", + "*.d.ts.map", + "src" + ], + "devDependencies": { + "@paulmillr/jsbt": "0.5.0", + "@types/node": "25.3.0", + "fast-check": "4.2.0", + "prettier": "3.6.2", + "typescript": "6.0.2" + }, + "scripts": { + "bench": "node test/benchmark/noble.ts", + "bench:compare": "MBENCH_DIMS='algorithm,buffer,library' node test/benchmark/hashes.ts", + "bench:compare-scrypt": "MBENCH_DIMS='iters,library' MBENCH_FILTER='async' node test/benchmark/scrypt.ts", + "bench:install": "cd test/benchmark; npm install", + "build": "tsc", + "build:release": "npx --no @paulmillr/jsbt esbuild test/build", + "check": "npm run check:readme && npm run check:treeshake && npm run check:jsdoc", + "check:readme": "npx --no @paulmillr/jsbt readme package.json", + "check:treeshake": "npx --no @paulmillr/jsbt treeshake package.json test/build/out-treeshake", + "check:jsdoc": "npx --no @paulmillr/jsbt tsdoc package.json", + "build:clean": "rm *.{js,js.map,d.ts,d.ts.map} 2> /dev/null", + "format": "prettier --write 'src/**/*.{js,ts}' 'test/**/*.{js,ts}'", + "test": "node test/index.ts", + "test:bun": "bun test/index.ts", + "test:deno": "deno --allow-env --allow-read test/index.ts", + "test:node20": "cd test; npx tsc; node compiled/test/index.js", + "test:dos": "node test/slow-dos.test.ts", + "test:slow": "node test/slow-big.test.ts", + "test:acvp": "node test/slow-acvp.test.ts", + "test:kdf": "node test/slow-kdf.test.ts" + }, + "exports": { + ".": "./index.js", + "./_md.js": "./_md.js", + "./argon2.js": "./argon2.js", + "./blake1.js": "./blake1.js", + "./blake2.js": "./blake2.js", + "./blake3.js": "./blake3.js", + "./eskdf.js": "./eskdf.js", + "./hkdf.js": "./hkdf.js", + "./hmac.js": "./hmac.js", + "./legacy.js": "./legacy.js", + "./pbkdf2.js": "./pbkdf2.js", + "./scrypt.js": "./scrypt.js", + "./sha2.js": "./sha2.js", + "./sha3-addons.js": "./sha3-addons.js", + "./sha3.js": "./sha3.js", + "./webcrypto.js": "./webcrypto.js", + "./utils.js": "./utils.js" + }, + "engines": { + "node": ">= 20.19.0" + }, + "keywords": [ + "sha1", + "sha2", + "sha3", + "blake", + "blake2", + "blake3", + "hmac", + "hkdf", + "pbkdf2", + "scrypt", + "sha256", + "sha512", + "keccak", + "ripemd160", + "kdf", + "hash", + "cryptography", + "security", + "noble" + ], + "homepage": "https://paulmillr.com/noble/", + "funding": "https://paulmillr.com/funding/", + "repository": { + "type": "git", + "url": "git+https://github.com/paulmillr/noble-hashes.git" + }, + "type": "module", + "main": "index.js", + "module": "index.js", + "types": "index.d.ts", + "sideEffects": false, + "author": "Paul Miller (https://paulmillr.com)", + "license": "MIT" +} diff --git a/node_modules/@noble/hashes/pbkdf2.d.ts b/node_modules/@noble/hashes/pbkdf2.d.ts new file mode 100644 index 0000000..cf4a659 --- /dev/null +++ b/node_modules/@noble/hashes/pbkdf2.d.ts @@ -0,0 +1,56 @@ +import { type CHash, type KDFInput, type TArg, type TRet } from './utils.ts'; +/** + * PBKDF2 options: + * * c: iterations, should probably be higher than 100_000 + * * dkLen: desired length of derived key in bytes, must be `>= 1` per RFC 8018 §5.2 + * * asyncTick: max time in ms for which async function can block execution + */ +export type Pbkdf2Opt = { + /** Iteration count. Higher values increase CPU cost. */ + c: number; + /** Desired derived key length in bytes, must be `>= 1` per RFC 8018 §5.2. */ + dkLen?: number; + /** Max scheduler block time in milliseconds for the async variant. */ + asyncTick?: number; +}; +/** + * PBKDF2-HMAC: RFC 8018 key derivation function. + * @param hash - hash function that would be used e.g. sha256 + * @param password - password from which a derived key is generated; + * JS string inputs are UTF-8 encoded first + * @param salt - cryptographic salt; JS string inputs are UTF-8 encoded first + * @param opts - PBKDF2 work factor and output settings. `dkLen`, if provided, + * must be `>= 1` per RFC 8018 §5.2. See {@link Pbkdf2Opt}. + * @returns Derived key bytes. + * @throws If the PBKDF2 iteration count or derived-key settings are invalid. {@link Error} + * @example + * PBKDF2-HMAC: RFC 2898 key derivation function. + * ```ts + * import { pbkdf2 } from '@noble/hashes/pbkdf2.js'; + * import { sha256 } from '@noble/hashes/sha2.js'; + * const key = pbkdf2(sha256, 'password', 'salt', { dkLen: 32, c: Math.pow(2, 18) }); + * ``` + */ +export declare function pbkdf2(hash: TArg, password: TArg, salt: TArg, opts: TArg): TRet; +/** + * PBKDF2-HMAC: RFC 8018 key derivation function. Async version. + * @param hash - hash function that would be used e.g. sha256 + * @param password - password from which a derived key is generated; + * JS string inputs are UTF-8 encoded first + * @param salt - cryptographic salt; JS string inputs are UTF-8 encoded first + * @param opts - PBKDF2 work factor and output settings. `dkLen`, if provided, + * must be `>= 1` per RFC 8018 §5.2. `asyncTick` is only a local + * scheduler-yield knob for this JS wrapper, not part of RFC 8018. + * See {@link Pbkdf2Opt}. + * @returns Promise resolving to derived key bytes. + * @throws If the PBKDF2 iteration count or derived-key settings are invalid. {@link Error} + * @example + * PBKDF2-HMAC: RFC 2898 key derivation function. + * ```ts + * import { pbkdf2Async } from '@noble/hashes/pbkdf2.js'; + * import { sha256 } from '@noble/hashes/sha2.js'; + * const key = await pbkdf2Async(sha256, 'password', 'salt', { dkLen: 32, c: 500_000 }); + * ``` + */ +export declare function pbkdf2Async(hash: TArg, password: TArg, salt: TArg, opts: TArg): Promise>; +//# sourceMappingURL=pbkdf2.d.ts.map \ No newline at end of file diff --git a/node_modules/@noble/hashes/pbkdf2.d.ts.map b/node_modules/@noble/hashes/pbkdf2.d.ts.map new file mode 100644 index 0000000..2f7dc08 --- /dev/null +++ b/node_modules/@noble/hashes/pbkdf2.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"pbkdf2.d.ts","sourceRoot":"","sources":["src/pbkdf2.ts"],"names":[],"mappings":"AAMA,OAAO,EAGL,KAAK,KAAK,EAEV,KAAK,QAAQ,EACb,KAAK,IAAI,EACT,KAAK,IAAI,EACV,MAAM,YAAY,CAAC;AAEpB;;;;;GAKG;AACH,MAAM,MAAM,SAAS,GAAG;IACtB,wDAAwD;IACxD,CAAC,EAAE,MAAM,CAAC;IACV,6EAA6E;IAC7E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sEAAsE;IACtE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AA+CF;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,MAAM,CACpB,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,EACjB,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,EACxB,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,EACpB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,GACpB,IAAI,CAAC,UAAU,CAAC,CAwBlB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,WAAW,CAC/B,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,EACjB,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,EACxB,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,EACpB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,GACpB,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAwB3B"} \ No newline at end of file diff --git a/node_modules/@noble/hashes/pbkdf2.js b/node_modules/@noble/hashes/pbkdf2.js new file mode 100644 index 0000000..50ee4db --- /dev/null +++ b/node_modules/@noble/hashes/pbkdf2.js @@ -0,0 +1,135 @@ +/** + * PBKDF (RFC 2898). Can be used to create a key from password and salt. + * @module + */ +import { hmac } from "./hmac.js"; +// prettier-ignore +import { ahash, anumber, asyncLoop, checkOpts, clean, createView, kdfInputToBytes } from "./utils.js"; +// Common start and end for sync/async functions +function pbkdf2Init(hash, _password, _salt, _opts) { + ahash(hash); + const opts = checkOpts({ dkLen: 32, asyncTick: 10 }, _opts); + const { c, dkLen, asyncTick } = opts; + anumber(c, 'c'); + anumber(dkLen, 'dkLen'); + anumber(asyncTick, 'asyncTick'); + if (c < 1) + throw new Error('iterations (c) must be >= 1'); + // RFC 8018 §5.2 defines `dkLen` as "a positive integer". + if (dkLen < 1) + throw new Error('"dkLen" must be >= 1'); + // RFC 8018 §5.2 step 1 requires rejecting oversize `dkLen` + // before allocating the destination buffer. + if (dkLen > (2 ** 32 - 1) * hash.outputLen) + throw new Error('derived key too long'); + const password = kdfInputToBytes(_password, 'password'); + const salt = kdfInputToBytes(_salt, 'salt'); + // DK = PBKDF2(PRF, Password, Salt, c, dkLen); + const DK = new Uint8Array(dkLen); + // U1 = PRF(Password, Salt + INT_32_BE(i)) + const PRF = hmac.create(hash, password); + // Cache PRF(P, S || ...) prefix state so each block only appends INT_32_BE(i). + const PRFSalt = PRF._cloneInto().update(salt); + return { c, dkLen, asyncTick, DK, PRF, PRFSalt }; +} +function pbkdf2Output(PRF, PRFSalt, DK, prfW, u) { + // Shared sync/async cleanup point: wipe transient PRF state + // while preserving the derived key buffer. + PRF.destroy(); + PRFSalt.destroy(); + if (prfW) + prfW.destroy(); + clean(u); + return DK; +} +/** + * PBKDF2-HMAC: RFC 8018 key derivation function. + * @param hash - hash function that would be used e.g. sha256 + * @param password - password from which a derived key is generated; + * JS string inputs are UTF-8 encoded first + * @param salt - cryptographic salt; JS string inputs are UTF-8 encoded first + * @param opts - PBKDF2 work factor and output settings. `dkLen`, if provided, + * must be `>= 1` per RFC 8018 §5.2. See {@link Pbkdf2Opt}. + * @returns Derived key bytes. + * @throws If the PBKDF2 iteration count or derived-key settings are invalid. {@link Error} + * @example + * PBKDF2-HMAC: RFC 2898 key derivation function. + * ```ts + * import { pbkdf2 } from '@noble/hashes/pbkdf2.js'; + * import { sha256 } from '@noble/hashes/sha2.js'; + * const key = pbkdf2(sha256, 'password', 'salt', { dkLen: 32, c: Math.pow(2, 18) }); + * ``` + */ +export function pbkdf2(hash, password, salt, opts) { + const { c, dkLen, DK, PRF, PRFSalt } = pbkdf2Init(hash, password, salt, opts); + let prfW; // Working copy + const arr = new Uint8Array(4); + const view = createView(arr); + const u = new Uint8Array(PRF.outputLen); + // DK = T1 + T2 + ⋯ + Tdklen/hlen + for (let ti = 1, pos = 0; pos < dkLen; ti++, pos += PRF.outputLen) { + // Ti = F(Password, Salt, c, i) + // The last Ti view can be shorter than hLen, which applies + // RFC 8018 §5.2 step 4's T_l<0..r-1> truncation without extra copies. + const Ti = DK.subarray(pos, pos + PRF.outputLen); + view.setInt32(0, ti, false); + // F(Password, Salt, c, i) = U1 ^ U2 ^ ⋯ ^ Uc + // U1 = PRF(Password, Salt + INT_32_BE(i)) + (prfW = PRFSalt._cloneInto(prfW)).update(arr).digestInto(u); + Ti.set(u.subarray(0, Ti.length)); + for (let ui = 1; ui < c; ui++) { + // Uc = PRF(Password, Uc−1) + PRF._cloneInto(prfW).update(u).digestInto(u); + for (let i = 0; i < Ti.length; i++) + Ti[i] ^= u[i]; + } + } + return pbkdf2Output(PRF, PRFSalt, DK, prfW, u); +} +/** + * PBKDF2-HMAC: RFC 8018 key derivation function. Async version. + * @param hash - hash function that would be used e.g. sha256 + * @param password - password from which a derived key is generated; + * JS string inputs are UTF-8 encoded first + * @param salt - cryptographic salt; JS string inputs are UTF-8 encoded first + * @param opts - PBKDF2 work factor and output settings. `dkLen`, if provided, + * must be `>= 1` per RFC 8018 §5.2. `asyncTick` is only a local + * scheduler-yield knob for this JS wrapper, not part of RFC 8018. + * See {@link Pbkdf2Opt}. + * @returns Promise resolving to derived key bytes. + * @throws If the PBKDF2 iteration count or derived-key settings are invalid. {@link Error} + * @example + * PBKDF2-HMAC: RFC 2898 key derivation function. + * ```ts + * import { pbkdf2Async } from '@noble/hashes/pbkdf2.js'; + * import { sha256 } from '@noble/hashes/sha2.js'; + * const key = await pbkdf2Async(sha256, 'password', 'salt', { dkLen: 32, c: 500_000 }); + * ``` + */ +export async function pbkdf2Async(hash, password, salt, opts) { + const { c, dkLen, asyncTick, DK, PRF, PRFSalt } = pbkdf2Init(hash, password, salt, opts); + let prfW; // Working copy + const arr = new Uint8Array(4); + const view = createView(arr); + const u = new Uint8Array(PRF.outputLen); + // DK = T1 + T2 + ⋯ + Tdklen/hlen + for (let ti = 1, pos = 0; pos < dkLen; ti++, pos += PRF.outputLen) { + // Ti = F(Password, Salt, c, i) + // The last Ti view can be shorter than hLen, which applies + // RFC 8018 §5.2 step 4's T_l<0..r-1> truncation without extra copies. + const Ti = DK.subarray(pos, pos + PRF.outputLen); + view.setInt32(0, ti, false); + // F(Password, Salt, c, i) = U1 ^ U2 ^ ⋯ ^ Uc + // U1 = PRF(Password, Salt + INT_32_BE(i)) + (prfW = PRFSalt._cloneInto(prfW)).update(arr).digestInto(u); + Ti.set(u.subarray(0, Ti.length)); + await asyncLoop(c - 1, asyncTick, () => { + // Uc = PRF(Password, Uc−1) + PRF._cloneInto(prfW).update(u).digestInto(u); + for (let i = 0; i < Ti.length; i++) + Ti[i] ^= u[i]; + }); + } + return pbkdf2Output(PRF, PRFSalt, DK, prfW, u); +} +//# sourceMappingURL=pbkdf2.js.map \ No newline at end of file diff --git a/node_modules/@noble/hashes/pbkdf2.js.map b/node_modules/@noble/hashes/pbkdf2.js.map new file mode 100644 index 0000000..291eca4 --- /dev/null +++ b/node_modules/@noble/hashes/pbkdf2.js.map @@ -0,0 +1 @@ +{"version":3,"file":"pbkdf2.js","sourceRoot":"","sources":["src/pbkdf2.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@noble/hashes/scrypt.d.ts b/node_modules/@noble/hashes/scrypt.d.ts new file mode 100644 index 0000000..b23a26e --- /dev/null +++ b/node_modules/@noble/hashes/scrypt.d.ts @@ -0,0 +1,65 @@ +import { type KDFInput, type TArg, type TRet } from './utils.ts'; +/** + * Scrypt options: + * - `N` is cpu/mem work factor (power of 2 e.g. `2**18`) + * - `r` is block size (8 is common), fine-tunes sequential memory read size and performance + * - `p` is parallelization factor (1 is common) + * - `dkLen` is output key length in bytes e.g. 32, and must be `>= 1` per RFC 7914 §2. + * - `asyncTick` - (default: 10) max time in ms for which async function can block execution + * - `maxmem` - (default: `1024 ** 3 + 1024` aka 1GB+1KB). A limit that the app could use for scrypt + * - `onProgress` - callback function that would be executed for progress report + */ +export type ScryptOpts = { + /** CPU and memory work factor. Must be a power of two. */ + N: number; + /** Block size parameter. */ + r: number; + /** Parallelization factor. */ + p: number; + /** Desired derived key length in bytes, must be `>= 1` per RFC 7914 §2. */ + dkLen?: number; + /** Max scheduler block time in milliseconds for the async variant. */ + asyncTick?: number; + /** Maximum temporary memory budget in bytes. */ + maxmem?: number; + /** + * Optional progress callback invoked during long-running derivations. + * param progress - completion fraction in the `0..1` range + */ + onProgress?: (progress: number) => void; +}; +/** + * Scrypt KDF from RFC 7914. See {@link ScryptOpts}. + * @param password - password or key material to derive from; + * JS string inputs are UTF-8 encoded first + * @param salt - unique salt bytes or string; JS string inputs are UTF-8 encoded first + * @param opts - Scrypt cost and memory parameters. `dkLen`, if provided, + * must be `>= 1` per RFC 7914 §2. See {@link ScryptOpts}. + * @returns Derived key bytes. + * @throws If the Scrypt cost, memory, or callback options are invalid. {@link Error} + * @example + * Derive a key with scrypt. + * ```ts + * scrypt('password', 'salt', { N: 2**18, r: 8, p: 1, dkLen: 32 }); + * ``` + */ +export declare function scrypt(password: TArg, salt: TArg, opts: TArg): TRet; +/** + * Scrypt KDF from RFC 7914. Async version. See {@link ScryptOpts}. + * @param password - password or key material to derive from; + * JS string inputs are UTF-8 encoded first + * @param salt - unique salt bytes or string; JS string inputs are UTF-8 encoded first + * @param opts - Scrypt cost and memory parameters. `dkLen`, if provided, + * must be `>= 1` per RFC 7914 §2. `asyncTick` is only a local + * scheduler-yield control for this JS wrapper, not part of RFC 7914. + * See {@link ScryptOpts}. + * @returns Promise resolving to derived key bytes. + * @throws If the Scrypt cost, memory, or callback options are invalid. {@link Error} + * @example + * Derive a key with scrypt asynchronously. + * ```ts + * await scryptAsync('password', 'salt', { N: 2**18, r: 8, p: 1, dkLen: 32 }); + * ``` + */ +export declare function scryptAsync(password: TArg, salt: TArg, opts: TArg): Promise>; +//# sourceMappingURL=scrypt.d.ts.map \ No newline at end of file diff --git a/node_modules/@noble/hashes/scrypt.d.ts.map b/node_modules/@noble/hashes/scrypt.d.ts.map new file mode 100644 index 0000000..4b642af --- /dev/null +++ b/node_modules/@noble/hashes/scrypt.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"scrypt.d.ts","sourceRoot":"","sources":["src/scrypt.ts"],"names":[],"mappings":"AAOA,OAAO,EAML,KAAK,QAAQ,EACb,KAAK,IAAI,EACT,KAAK,IAAI,EACV,MAAM,YAAY,CAAC;AAkFpB;;;;;;;;;GASG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB,0DAA0D;IAC1D,CAAC,EAAE,MAAM,CAAC;IACV,4BAA4B;IAC5B,CAAC,EAAE,MAAM,CAAC;IACV,8BAA8B;IAC9B,CAAC,EAAE,MAAM,CAAC;IACV,2EAA2E;IAC3E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sEAAsE;IACtE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gDAAgD;IAChD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CACzC,CAAC;AAiFF;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,MAAM,CACpB,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,EACxB,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,EACpB,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,GACrB,IAAI,CAAC,UAAU,CAAC,CAgClB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,EACxB,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,EACpB,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,GACrB,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAiC3B"} \ No newline at end of file diff --git a/node_modules/@noble/hashes/scrypt.js b/node_modules/@noble/hashes/scrypt.js new file mode 100644 index 0000000..29ff883 --- /dev/null +++ b/node_modules/@noble/hashes/scrypt.js @@ -0,0 +1,257 @@ +/** + * RFC 7914 Scrypt KDF. Can be used to create a key from password and salt. + * @module + */ +import { pbkdf2 } from "./pbkdf2.js"; +import { sha256 } from "./sha2.js"; +// prettier-ignore +import { anumber, asyncLoop, checkOpts, clean, rotl, swap32IfBE, u32 } from "./utils.js"; +// The main Scrypt loop: uses Salsa extensively. +// Six versions of the function were tried, this is the fastest one. +// RFC 7914 §3 / §4 step 2 applies Salsa20/8 to one 16-word (64-byte) block +// after xor'ing two such blocks. +// The local `y*` snapshot keeps the xor input stable even when `out` aliases `prev` or `input`. +// prettier-ignore +function XorAndSalsa(prev, pi, input, ii, out, oi) { + // Based on https://cr.yp.to/salsa20.html and RFC 7914's Salsa20/8 core. + // Xor blocks + let y00 = prev[pi++] ^ input[ii++], y01 = prev[pi++] ^ input[ii++]; + let y02 = prev[pi++] ^ input[ii++], y03 = prev[pi++] ^ input[ii++]; + let y04 = prev[pi++] ^ input[ii++], y05 = prev[pi++] ^ input[ii++]; + let y06 = prev[pi++] ^ input[ii++], y07 = prev[pi++] ^ input[ii++]; + let y08 = prev[pi++] ^ input[ii++], y09 = prev[pi++] ^ input[ii++]; + let y10 = prev[pi++] ^ input[ii++], y11 = prev[pi++] ^ input[ii++]; + let y12 = prev[pi++] ^ input[ii++], y13 = prev[pi++] ^ input[ii++]; + let y14 = prev[pi++] ^ input[ii++], y15 = prev[pi++] ^ input[ii++]; + // Save state to temporary variables (salsa) + let x00 = y00, x01 = y01, x02 = y02, x03 = y03, x04 = y04, x05 = y05, x06 = y06, x07 = y07, x08 = y08, x09 = y09, x10 = y10, x11 = y11, x12 = y12, x13 = y13, x14 = y14, x15 = y15; + // Main loop (salsa) + for (let i = 0; i < 8; i += 2) { + x04 ^= rotl(x00 + x12 | 0, 7); + x08 ^= rotl(x04 + x00 | 0, 9); + x12 ^= rotl(x08 + x04 | 0, 13); + x00 ^= rotl(x12 + x08 | 0, 18); + x09 ^= rotl(x05 + x01 | 0, 7); + x13 ^= rotl(x09 + x05 | 0, 9); + x01 ^= rotl(x13 + x09 | 0, 13); + x05 ^= rotl(x01 + x13 | 0, 18); + x14 ^= rotl(x10 + x06 | 0, 7); + x02 ^= rotl(x14 + x10 | 0, 9); + x06 ^= rotl(x02 + x14 | 0, 13); + x10 ^= rotl(x06 + x02 | 0, 18); + x03 ^= rotl(x15 + x11 | 0, 7); + x07 ^= rotl(x03 + x15 | 0, 9); + x11 ^= rotl(x07 + x03 | 0, 13); + x15 ^= rotl(x11 + x07 | 0, 18); + x01 ^= rotl(x00 + x03 | 0, 7); + x02 ^= rotl(x01 + x00 | 0, 9); + x03 ^= rotl(x02 + x01 | 0, 13); + x00 ^= rotl(x03 + x02 | 0, 18); + x06 ^= rotl(x05 + x04 | 0, 7); + x07 ^= rotl(x06 + x05 | 0, 9); + x04 ^= rotl(x07 + x06 | 0, 13); + x05 ^= rotl(x04 + x07 | 0, 18); + x11 ^= rotl(x10 + x09 | 0, 7); + x08 ^= rotl(x11 + x10 | 0, 9); + x09 ^= rotl(x08 + x11 | 0, 13); + x10 ^= rotl(x09 + x08 | 0, 18); + x12 ^= rotl(x15 + x14 | 0, 7); + x13 ^= rotl(x12 + x15 | 0, 9); + x14 ^= rotl(x13 + x12 | 0, 13); + x15 ^= rotl(x14 + x13 | 0, 18); + } + // Write output (salsa) + out[oi++] = (y00 + x00) | 0; + out[oi++] = (y01 + x01) | 0; + out[oi++] = (y02 + x02) | 0; + out[oi++] = (y03 + x03) | 0; + out[oi++] = (y04 + x04) | 0; + out[oi++] = (y05 + x05) | 0; + out[oi++] = (y06 + x06) | 0; + out[oi++] = (y07 + x07) | 0; + out[oi++] = (y08 + x08) | 0; + out[oi++] = (y09 + x09) | 0; + out[oi++] = (y10 + x10) | 0; + out[oi++] = (y11 + x11) | 0; + out[oi++] = (y12 + x12) | 0; + out[oi++] = (y13 + x13) | 0; + out[oi++] = (y14 + x14) | 0; + out[oi++] = (y15 + x15) | 0; +} +function BlockMix(input, ii, out, oi, r) { + // The block B is `r` 128-byte chunks, i.e. `2r` 16-word (64-byte) Salsa blocks. + let head = oi + 0; + let tail = oi + 16 * r; + for (let i = 0; i < 16; i++) + out[tail + i] = input[ii + (2 * r - 1) * 16 + i]; // X ← B[2r−1] + for (let i = 0; i < r; i++, head += 16, ii += 16) { + // RFC 7914 §4 step 3 outputs `Y[0], Y[2], ...` first, then `Y[1], Y[3], ...`; + // `head` and `tail` lay out those even/odd halves in place. + XorAndSalsa(out, tail, input, ii, out, head); // head[i] = Salsa(blockIn[2*i] ^ tail[i-1]) + if (i > 0) + tail += 16; // First iteration overwrites tmp value in tail + // tail[i] = Salsa(blockIn[2*i+1] ^ head[i]) + XorAndSalsa(out, head, input, (ii += 16), out, tail); + } +} +// Common prologue and epilogue for sync/async functions +function scryptInit(password, salt, _opts) { + // Maxmem - 1GB+1KB by default + const opts = checkOpts({ + dkLen: 32, + asyncTick: 10, + maxmem: 1024 ** 3 + 1024, + }, _opts); + const { N, r, p, dkLen, asyncTick, maxmem, onProgress } = opts; + anumber(N, 'N'); + anumber(r, 'r'); + anumber(p, 'p'); + anumber(dkLen, 'dkLen'); + anumber(asyncTick, 'asyncTick'); + anumber(maxmem, 'maxmem'); + if (onProgress !== undefined && typeof onProgress !== 'function') + throw new Error('progressCb must be a function'); + const blockSize = 128 * r; + const blockSize32 = blockSize / 4; + // Max N is 2^32 (Integrify is 32-bit). + // Real limit can be 2^22: some JS engines limit Uint8Array to 4GB. + // Spec check `N >= 2^(blockSize / 8)` is not done for compat with popular libs, + // which used incorrect r: 1, p: 8. Also, the check seems to be a spec error: + // https://www.rfc-editor.org/errata_search.php?rfc=7914 + const pow32 = Math.pow(2, 32); + if (N <= 1 || (N & (N - 1)) !== 0 || N > pow32) + throw new Error('"N" expected a power of 2, and 2^1 <= N <= 2^32'); + if (p < 1 || p > ((pow32 - 1) * 32) / blockSize) + throw new Error('"p" expected integer 1..((2^32 - 1) * 32) / (128 * r)'); + // RFC 7914 §2 defines `dkLen` as a positive integer. + if (dkLen < 1 || dkLen > (pow32 - 1) * 32) + throw new Error('"dkLen" expected integer 1..(2^32 - 1) * 32'); + // Include the shared `tmp` scratch block so `maxmem` matches noble's actual temporary allocation. + // Node requires more headroom here, so this accounting is intentionally noble-specific. + const memUsed = blockSize * (N + p + 1); + if (memUsed > maxmem) + throw new Error('"maxmem" limit was hit: memUsed(128*r*(N+p+1))=' + memUsed + ', maxmem=' + maxmem); + // [B0...Bp−1] ← PBKDF2HMAC-SHA256(Passphrase, Salt, 1, blockSize*ParallelizationFactor) + // Since it has only one iteration there is no reason to use async variant + const B = pbkdf2(sha256, password, salt, { c: 1, dkLen: blockSize * p }); + const B32 = u32(B); + // Re-used between parallel iterations. Array(iterations) of B + const V = u32(new Uint8Array(blockSize * N)); + const tmp = u32(new Uint8Array(blockSize)); + let blockMixCb = () => { }; + if (onProgress) { + const totalBlockMix = 2 * N * p; + // Invoke callback if progress changes from 10.01 to 10.02 + // Allows to draw smooth progress bar on up to 8K screen + const callbackPer = Math.max(Math.floor(totalBlockMix / 10000), 1); + let blockMixCnt = 0; + blockMixCb = () => { + blockMixCnt++; + if (onProgress && (!(blockMixCnt % callbackPer) || blockMixCnt === totalBlockMix)) + onProgress(blockMixCnt / totalBlockMix); + }; + } + return { N, r, p, dkLen, blockSize32, V, B32, B, tmp, blockMixCb, asyncTick }; +} +function scryptOutput(password, dkLen, B, V, tmp) { + // Shared final PBKDF2-and-cleanup step: keep the derived key, wipe the scrypt workspace. + const res = pbkdf2(sha256, password, B, { c: 1, dkLen }); + clean(B, V, tmp); + return res; +} +/** + * Scrypt KDF from RFC 7914. See {@link ScryptOpts}. + * @param password - password or key material to derive from; + * JS string inputs are UTF-8 encoded first + * @param salt - unique salt bytes or string; JS string inputs are UTF-8 encoded first + * @param opts - Scrypt cost and memory parameters. `dkLen`, if provided, + * must be `>= 1` per RFC 7914 §2. See {@link ScryptOpts}. + * @returns Derived key bytes. + * @throws If the Scrypt cost, memory, or callback options are invalid. {@link Error} + * @example + * Derive a key with scrypt. + * ```ts + * scrypt('password', 'salt', { N: 2**18, r: 8, p: 1, dkLen: 32 }); + * ``` + */ +export function scrypt(password, salt, opts) { + const { N, r, p, dkLen, blockSize32, V, B32, B, tmp, blockMixCb } = scryptInit(password, salt, opts); + swap32IfBE(B32); + for (let pi = 0; pi < p; pi++) { + const Pi = blockSize32 * pi; + for (let i = 0; i < blockSize32; i++) + V[i] = B32[Pi + i]; // V[0] = B[i] + for (let i = 0, pos = 0; i < N - 1; i++) { + BlockMix(V, pos, V, (pos += blockSize32), r); // V[i] = BlockMix(V[i-1]); + blockMixCb(); + } + BlockMix(V, (N - 1) * blockSize32, B32, Pi, r); // Process last element + blockMixCb(); + for (let i = 0; i < N; i++) { + // First u32 of the last 64-byte block (u32 is LE) + // RFC 7914 Integerify(X) uses the whole last 64-byte block, but mod N + // only depends on the low word here because N is a power of two and + // this implementation caps N at 2^32. + // & (N - 1) is % N as N is a power of 2, N & (N - 1) = 0 is checked + // above; >>> 0 for unsigned, input fits in u32. + const j = (B32[Pi + blockSize32 - 16] & (N - 1)) >>> 0; // j = Integrify(X) % iterations + // tmp = B ^ V[j] + for (let k = 0; k < blockSize32; k++) + tmp[k] = B32[Pi + k] ^ V[j * blockSize32 + k]; + BlockMix(tmp, 0, B32, Pi, r); // B = BlockMix(B ^ V[j]) + blockMixCb(); + } + } + swap32IfBE(B32); + return scryptOutput(password, dkLen, B, V, tmp); +} +/** + * Scrypt KDF from RFC 7914. Async version. See {@link ScryptOpts}. + * @param password - password or key material to derive from; + * JS string inputs are UTF-8 encoded first + * @param salt - unique salt bytes or string; JS string inputs are UTF-8 encoded first + * @param opts - Scrypt cost and memory parameters. `dkLen`, if provided, + * must be `>= 1` per RFC 7914 §2. `asyncTick` is only a local + * scheduler-yield control for this JS wrapper, not part of RFC 7914. + * See {@link ScryptOpts}. + * @returns Promise resolving to derived key bytes. + * @throws If the Scrypt cost, memory, or callback options are invalid. {@link Error} + * @example + * Derive a key with scrypt asynchronously. + * ```ts + * await scryptAsync('password', 'salt', { N: 2**18, r: 8, p: 1, dkLen: 32 }); + * ``` + */ +export async function scryptAsync(password, salt, opts) { + const { N, r, p, dkLen, blockSize32, V, B32, B, tmp, blockMixCb, asyncTick } = scryptInit(password, salt, opts); + swap32IfBE(B32); + for (let pi = 0; pi < p; pi++) { + const Pi = blockSize32 * pi; + for (let i = 0; i < blockSize32; i++) + V[i] = B32[Pi + i]; // V[0] = B[i] + let pos = 0; + await asyncLoop(N - 1, asyncTick, () => { + BlockMix(V, pos, V, (pos += blockSize32), r); // V[i] = BlockMix(V[i-1]); + blockMixCb(); + }); + BlockMix(V, (N - 1) * blockSize32, B32, Pi, r); // Process last element + blockMixCb(); + await asyncLoop(N, asyncTick, () => { + // First u32 of the last 64-byte block (u32 is LE) + // RFC 7914 Integerify(X) uses the whole last 64-byte block, but mod N + // only depends on the low word here because N is a power of two and + // this implementation caps N at 2^32. + // & (N - 1) is % N as N is a power of 2, N & (N - 1) = 0 is checked + // above; >>> 0 for unsigned, input fits in u32. + const j = (B32[Pi + blockSize32 - 16] & (N - 1)) >>> 0; // j = Integrify(X) % iterations + // tmp = B ^ V[j] + for (let k = 0; k < blockSize32; k++) + tmp[k] = B32[Pi + k] ^ V[j * blockSize32 + k]; + BlockMix(tmp, 0, B32, Pi, r); // B = BlockMix(B ^ V[j]) + blockMixCb(); + }); + } + swap32IfBE(B32); + return scryptOutput(password, dkLen, B, V, tmp); +} +//# sourceMappingURL=scrypt.js.map \ No newline at end of file diff --git a/node_modules/@noble/hashes/scrypt.js.map b/node_modules/@noble/hashes/scrypt.js.map new file mode 100644 index 0000000..7daddda --- /dev/null +++ b/node_modules/@noble/hashes/scrypt.js.map @@ -0,0 +1 @@ +{"version":3,"file":"scrypt.js","sourceRoot":"","sources":["src/scrypt.ts"],"names":[],"mappings":"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AAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAG,CAAC,CAAC,CAAC;QAC/D,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;QAAC,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;QAC/D,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAG,CAAC,CAAC,CAAC;QAAC,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAG,CAAC,CAAC,CAAC;QAC/D,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;QAAC,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;QAC/D,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAG,CAAC,CAAC,CAAC;QAAC,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAG,CAAC,CAAC,CAAC;QAC/D,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;QAAC,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;QAC/D,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAG,CAAC,CAAC,CAAC;QAAC,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAG,CAAC,CAAC,CAAC;QAC/D,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;QAAC,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;QAC/D,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAG,CAAC,CAAC,CAAC;QAAC,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAG,CAAC,CAAC,CAAC;QAC/D,GA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"} \ No newline at end of file diff --git a/node_modules/@noble/hashes/sha2.d.ts b/node_modules/@noble/hashes/sha2.d.ts new file mode 100644 index 0000000..b7a1d54 --- /dev/null +++ b/node_modules/@noble/hashes/sha2.d.ts @@ -0,0 +1,249 @@ +/** + * SHA2 hash function. A.k.a. sha256, sha384, sha512, sha512_224, sha512_256. + * SHA256 is the fastest hash implementable in JS, even faster than Blake3. + * Check out {@link https://www.rfc-editor.org/rfc/rfc4634 | RFC 4634} and + * {@link https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf | FIPS 180-4}. + * @module + */ +import { HashMD } from './_md.ts'; +import { type CHash, type TRet } from './utils.ts'; +/** Internal SHA-224 / SHA-256 compression engine from RFC 6234 §6.2. */ +declare abstract class SHA2_32B> extends HashMD { + protected abstract A: number; + protected abstract B: number; + protected abstract C: number; + protected abstract D: number; + protected abstract E: number; + protected abstract F: number; + protected abstract G: number; + protected abstract H: number; + constructor(outputLen: number); + protected get(): [number, number, number, number, number, number, number, number]; + protected set(A: number, B: number, C: number, D: number, E: number, F: number, G: number, H: number): void; + protected process(view: DataView, offset: number): void; + protected roundClean(): void; + destroy(): void; +} +/** Internal SHA-256 hash class grounded in RFC 6234 §6.2. */ +export declare class _SHA256 extends SHA2_32B<_SHA256> { + protected A: number; + protected B: number; + protected C: number; + protected D: number; + protected E: number; + protected F: number; + protected G: number; + protected H: number; + constructor(); +} +/** Internal SHA-224 hash class grounded in RFC 6234 §6.2 and §8.5. */ +export declare class _SHA224 extends SHA2_32B<_SHA224> { + protected A: number; + protected B: number; + protected C: number; + protected D: number; + protected E: number; + protected F: number; + protected G: number; + protected H: number; + constructor(); +} +/** Internal SHA-384 / SHA-512 compression engine from RFC 6234 §6.4. */ +declare abstract class SHA2_64B> extends HashMD { + protected abstract Ah: number; + protected abstract Al: number; + protected abstract Bh: number; + protected abstract Bl: number; + protected abstract Ch: number; + protected abstract Cl: number; + protected abstract Dh: number; + protected abstract Dl: number; + protected abstract Eh: number; + protected abstract El: number; + protected abstract Fh: number; + protected abstract Fl: number; + protected abstract Gh: number; + protected abstract Gl: number; + protected abstract Hh: number; + protected abstract Hl: number; + constructor(outputLen: number); + protected get(): [ + number, + number, + number, + number, + number, + number, + number, + number, + number, + number, + number, + number, + number, + number, + number, + number + ]; + protected set(Ah: number, Al: number, Bh: number, Bl: number, Ch: number, Cl: number, Dh: number, Dl: number, Eh: number, El: number, Fh: number, Fl: number, Gh: number, Gl: number, Hh: number, Hl: number): void; + protected process(view: DataView, offset: number): void; + protected roundClean(): void; + destroy(): void; +} +/** Internal SHA-512 hash class grounded in RFC 6234 §6.3 and §6.4. */ +export declare class _SHA512 extends SHA2_64B<_SHA512> { + protected Ah: number; + protected Al: number; + protected Bh: number; + protected Bl: number; + protected Ch: number; + protected Cl: number; + protected Dh: number; + protected Dl: number; + protected Eh: number; + protected El: number; + protected Fh: number; + protected Fl: number; + protected Gh: number; + protected Gl: number; + protected Hh: number; + protected Hl: number; + constructor(); +} +/** Internal SHA-384 hash class grounded in RFC 6234 §6.3 and §6.4. */ +export declare class _SHA384 extends SHA2_64B<_SHA384> { + protected Ah: number; + protected Al: number; + protected Bh: number; + protected Bl: number; + protected Ch: number; + protected Cl: number; + protected Dh: number; + protected Dl: number; + protected Eh: number; + protected El: number; + protected Fh: number; + protected Fl: number; + protected Gh: number; + protected Gl: number; + protected Hh: number; + protected Hl: number; + constructor(); +} +/** Internal SHA-512/224 hash class using the derived `T224_IV` and the shared + * RFC 6234 §6.4 compression engine. */ +export declare class _SHA512_224 extends SHA2_64B<_SHA512_224> { + protected Ah: number; + protected Al: number; + protected Bh: number; + protected Bl: number; + protected Ch: number; + protected Cl: number; + protected Dh: number; + protected Dl: number; + protected Eh: number; + protected El: number; + protected Fh: number; + protected Fl: number; + protected Gh: number; + protected Gl: number; + protected Hh: number; + protected Hl: number; + constructor(); +} +/** Internal SHA-512/256 hash class using the derived `T256_IV` and the shared + * RFC 6234 §6.4 compression engine. */ +export declare class _SHA512_256 extends SHA2_64B<_SHA512_256> { + protected Ah: number; + protected Al: number; + protected Bh: number; + protected Bl: number; + protected Ch: number; + protected Cl: number; + protected Dh: number; + protected Dl: number; + protected Eh: number; + protected El: number; + protected Fh: number; + protected Fl: number; + protected Gh: number; + protected Gl: number; + protected Hh: number; + protected Hl: number; + constructor(); +} +/** + * SHA2-256 hash function from RFC 4634. In JS it's the fastest: even faster than Blake3. Some info: + * + * - Trying 2^128 hashes would get 50% chance of collision, using birthday attack. + * - BTC network is doing 2^70 hashes/sec (2^95 hashes/year) as per 2025. + * - Each sha256 hash is executing 2^18 bit operations. + * - Good 2024 ASICs can do 200Th/sec with 3500 watts of power, corresponding to 2^36 hashes/joule. + * @param msg - message bytes to hash + * @returns Digest bytes. + * @example + * Hash a message with SHA2-256. + * ```ts + * sha256(new Uint8Array([97, 98, 99])); + * ``` + */ +export declare const sha256: TRet>; +/** + * SHA2-224 hash function from RFC 4634. + * @param msg - message bytes to hash + * @returns Digest bytes. + * @example + * Hash a message with SHA2-224. + * ```ts + * sha224(new Uint8Array([97, 98, 99])); + * ``` + */ +export declare const sha224: TRet>; +/** + * SHA2-512 hash function from RFC 4634. + * @param msg - message bytes to hash + * @returns Digest bytes. + * @example + * Hash a message with SHA2-512. + * ```ts + * sha512(new Uint8Array([97, 98, 99])); + * ``` + */ +export declare const sha512: TRet>; +/** + * SHA2-384 hash function from RFC 4634. + * @param msg - message bytes to hash + * @returns Digest bytes. + * @example + * Hash a message with SHA2-384. + * ```ts + * sha384(new Uint8Array([97, 98, 99])); + * ``` + */ +export declare const sha384: TRet>; +/** + * SHA2-512/256 "truncated" hash function, with improved resistance to length extension attacks. + * See the paper on {@link https://eprint.iacr.org/2010/548.pdf | truncated SHA512}. + * @param msg - message bytes to hash + * @returns Digest bytes. + * @example + * Hash a message with SHA2-512/256. + * ```ts + * sha512_256(new Uint8Array([97, 98, 99])); + * ``` + */ +export declare const sha512_256: TRet>; +/** + * SHA2-512/224 "truncated" hash function, with improved resistance to length extension attacks. + * See the paper on {@link https://eprint.iacr.org/2010/548.pdf | truncated SHA512}. + * @param msg - message bytes to hash + * @returns Digest bytes. + * @example + * Hash a message with SHA2-512/224. + * ```ts + * sha512_224(new Uint8Array([97, 98, 99])); + * ``` + */ +export declare const sha512_224: TRet>; +export {}; +//# sourceMappingURL=sha2.d.ts.map \ No newline at end of file diff --git a/node_modules/@noble/hashes/sha2.d.ts.map b/node_modules/@noble/hashes/sha2.d.ts.map new file mode 100644 index 0000000..717e788 --- /dev/null +++ b/node_modules/@noble/hashes/sha2.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"sha2.d.ts","sourceRoot":"","sources":["src/sha2.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@noble/hashes/sha2.js b/node_modules/@noble/hashes/sha2.js new file mode 100644 index 0000000..be20232 --- /dev/null +++ b/node_modules/@noble/hashes/sha2.js @@ -0,0 +1,458 @@ +/** + * SHA2 hash function. A.k.a. sha256, sha384, sha512, sha512_224, sha512_256. + * SHA256 is the fastest hash implementable in JS, even faster than Blake3. + * Check out {@link https://www.rfc-editor.org/rfc/rfc4634 | RFC 4634} and + * {@link https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf | FIPS 180-4}. + * @module + */ +import { Chi, HashMD, Maj, SHA224_IV, SHA256_IV, SHA384_IV, SHA512_IV } from "./_md.js"; +import * as u64 from "./_u64.js"; +import { clean, createHasher, oidNist, rotr } from "./utils.js"; +/** + * SHA-224 / SHA-256 round constants from RFC 6234 §5.1: the first 32 bits + * of the cube roots of the first 64 primes (2..311). + */ +// prettier-ignore +const SHA256_K = /* @__PURE__ */ Uint32Array.from([ + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 +]); +/** Reusable SHA-224 / SHA-256 message schedule buffer `W_t` from RFC 6234 §6.2 step 1. */ +const SHA256_W = /* @__PURE__ */ new Uint32Array(64); +/** Internal SHA-224 / SHA-256 compression engine from RFC 6234 §6.2. */ +class SHA2_32B extends HashMD { + constructor(outputLen) { + super(64, outputLen, 8, false); + } + get() { + const { A, B, C, D, E, F, G, H } = this; + return [A, B, C, D, E, F, G, H]; + } + // prettier-ignore + set(A, B, C, D, E, F, G, H) { + this.A = A | 0; + this.B = B | 0; + this.C = C | 0; + this.D = D | 0; + this.E = E | 0; + this.F = F | 0; + this.G = G | 0; + this.H = H | 0; + } + process(view, offset) { + // Extend the first 16 words into the remaining 48 words w[16..63] of the message schedule array + for (let i = 0; i < 16; i++, offset += 4) + SHA256_W[i] = view.getUint32(offset, false); + for (let i = 16; i < 64; i++) { + const W15 = SHA256_W[i - 15]; + const W2 = SHA256_W[i - 2]; + const s0 = rotr(W15, 7) ^ rotr(W15, 18) ^ (W15 >>> 3); + const s1 = rotr(W2, 17) ^ rotr(W2, 19) ^ (W2 >>> 10); + SHA256_W[i] = (s1 + SHA256_W[i - 7] + s0 + SHA256_W[i - 16]) | 0; + } + // Compression function main loop, 64 rounds + let { A, B, C, D, E, F, G, H } = this; + for (let i = 0; i < 64; i++) { + const sigma1 = rotr(E, 6) ^ rotr(E, 11) ^ rotr(E, 25); + const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0; + const sigma0 = rotr(A, 2) ^ rotr(A, 13) ^ rotr(A, 22); + const T2 = (sigma0 + Maj(A, B, C)) | 0; + H = G; + G = F; + F = E; + E = (D + T1) | 0; + D = C; + C = B; + B = A; + A = (T1 + T2) | 0; + } + // Add the compressed chunk to the current hash value + A = (A + this.A) | 0; + B = (B + this.B) | 0; + C = (C + this.C) | 0; + D = (D + this.D) | 0; + E = (E + this.E) | 0; + F = (F + this.F) | 0; + G = (G + this.G) | 0; + H = (H + this.H) | 0; + this.set(A, B, C, D, E, F, G, H); + } + roundClean() { + clean(SHA256_W); + } + destroy() { + // HashMD callers route post-destroy usability through `destroyed`; zeroizing alone still leaves + // update()/digest() callable on reused instances. + this.destroyed = true; + this.set(0, 0, 0, 0, 0, 0, 0, 0); + clean(this.buffer); + } +} +/** Internal SHA-256 hash class grounded in RFC 6234 §6.2. */ +export class _SHA256 extends SHA2_32B { + // We cannot use array here since array allows indexing by variable + // which means optimizer/compiler cannot use registers. + A = SHA256_IV[0] | 0; + B = SHA256_IV[1] | 0; + C = SHA256_IV[2] | 0; + D = SHA256_IV[3] | 0; + E = SHA256_IV[4] | 0; + F = SHA256_IV[5] | 0; + G = SHA256_IV[6] | 0; + H = SHA256_IV[7] | 0; + constructor() { + super(32); + } +} +/** Internal SHA-224 hash class grounded in RFC 6234 §6.2 and §8.5. */ +export class _SHA224 extends SHA2_32B { + A = SHA224_IV[0] | 0; + B = SHA224_IV[1] | 0; + C = SHA224_IV[2] | 0; + D = SHA224_IV[3] | 0; + E = SHA224_IV[4] | 0; + F = SHA224_IV[5] | 0; + G = SHA224_IV[6] | 0; + H = SHA224_IV[7] | 0; + constructor() { + super(28); + } +} +// SHA2-512 is slower than sha256 in js because u64 operations are slow. +// SHA-384 / SHA-512 round constants from RFC 6234 §5.2: +// 80 full 64-bit words split into high/low halves. +// prettier-ignore +const K512 = /* @__PURE__ */ (() => u64.split([ + '0x428a2f98d728ae22', '0x7137449123ef65cd', '0xb5c0fbcfec4d3b2f', '0xe9b5dba58189dbbc', + '0x3956c25bf348b538', '0x59f111f1b605d019', '0x923f82a4af194f9b', '0xab1c5ed5da6d8118', + '0xd807aa98a3030242', '0x12835b0145706fbe', '0x243185be4ee4b28c', '0x550c7dc3d5ffb4e2', + '0x72be5d74f27b896f', '0x80deb1fe3b1696b1', '0x9bdc06a725c71235', '0xc19bf174cf692694', + '0xe49b69c19ef14ad2', '0xefbe4786384f25e3', '0x0fc19dc68b8cd5b5', '0x240ca1cc77ac9c65', + '0x2de92c6f592b0275', '0x4a7484aa6ea6e483', '0x5cb0a9dcbd41fbd4', '0x76f988da831153b5', + '0x983e5152ee66dfab', '0xa831c66d2db43210', '0xb00327c898fb213f', '0xbf597fc7beef0ee4', + '0xc6e00bf33da88fc2', '0xd5a79147930aa725', '0x06ca6351e003826f', '0x142929670a0e6e70', + '0x27b70a8546d22ffc', '0x2e1b21385c26c926', '0x4d2c6dfc5ac42aed', '0x53380d139d95b3df', + '0x650a73548baf63de', '0x766a0abb3c77b2a8', '0x81c2c92e47edaee6', '0x92722c851482353b', + '0xa2bfe8a14cf10364', '0xa81a664bbc423001', '0xc24b8b70d0f89791', '0xc76c51a30654be30', + '0xd192e819d6ef5218', '0xd69906245565a910', '0xf40e35855771202a', '0x106aa07032bbd1b8', + '0x19a4c116b8d2d0c8', '0x1e376c085141ab53', '0x2748774cdf8eeb99', '0x34b0bcb5e19b48a8', + '0x391c0cb3c5c95a63', '0x4ed8aa4ae3418acb', '0x5b9cca4f7763e373', '0x682e6ff3d6b2b8a3', + '0x748f82ee5defb2fc', '0x78a5636f43172f60', '0x84c87814a1f0ab72', '0x8cc702081a6439ec', + '0x90befffa23631e28', '0xa4506cebde82bde9', '0xbef9a3f7b2c67915', '0xc67178f2e372532b', + '0xca273eceea26619c', '0xd186b8c721c0c207', '0xeada7dd6cde0eb1e', '0xf57d4f7fee6ed178', + '0x06f067aa72176fba', '0x0a637dc5a2c898a6', '0x113f9804bef90dae', '0x1b710b35131c471b', + '0x28db77f523047d84', '0x32caab7b40c72493', '0x3c9ebe0a15c9bebc', '0x431d67c49c100d4c', + '0x4cc5d4becb3e42b6', '0x597f299cfc657e2a', '0x5fcb6fab3ad6faec', '0x6c44198c4a475817' +].map(n => BigInt(n))))(); +const SHA512_Kh = /* @__PURE__ */ (() => K512[0])(); +const SHA512_Kl = /* @__PURE__ */ (() => K512[1])(); +// Reusable high-half schedule buffer for the RFC 6234 §6.4 64-bit `W_t` words. +const SHA512_W_H = /* @__PURE__ */ new Uint32Array(80); +// Reusable low-half schedule buffer for the RFC 6234 §6.4 64-bit `W_t` words. +const SHA512_W_L = /* @__PURE__ */ new Uint32Array(80); +/** Internal SHA-384 / SHA-512 compression engine from RFC 6234 §6.4. */ +class SHA2_64B extends HashMD { + constructor(outputLen) { + super(128, outputLen, 16, false); + } + // prettier-ignore + get() { + const { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this; + return [Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl]; + } + // prettier-ignore + set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl) { + this.Ah = Ah | 0; + this.Al = Al | 0; + this.Bh = Bh | 0; + this.Bl = Bl | 0; + this.Ch = Ch | 0; + this.Cl = Cl | 0; + this.Dh = Dh | 0; + this.Dl = Dl | 0; + this.Eh = Eh | 0; + this.El = El | 0; + this.Fh = Fh | 0; + this.Fl = Fl | 0; + this.Gh = Gh | 0; + this.Gl = Gl | 0; + this.Hh = Hh | 0; + this.Hl = Hl | 0; + } + process(view, offset) { + // Extend the first 16 words into the remaining 64 words w[16..79] of the message schedule array + for (let i = 0; i < 16; i++, offset += 4) { + SHA512_W_H[i] = view.getUint32(offset); + SHA512_W_L[i] = view.getUint32((offset += 4)); + } + for (let i = 16; i < 80; i++) { + // s0 := (w[i-15] rightrotate 1) xor (w[i-15] rightrotate 8) xor (w[i-15] rightshift 7) + const W15h = SHA512_W_H[i - 15] | 0; + const W15l = SHA512_W_L[i - 15] | 0; + const s0h = u64.rotrSH(W15h, W15l, 1) ^ u64.rotrSH(W15h, W15l, 8) ^ u64.shrSH(W15h, W15l, 7); + const s0l = u64.rotrSL(W15h, W15l, 1) ^ u64.rotrSL(W15h, W15l, 8) ^ u64.shrSL(W15h, W15l, 7); + // s1 := (w[i-2] rightrotate 19) xor (w[i-2] rightrotate 61) xor (w[i-2] rightshift 6) + const W2h = SHA512_W_H[i - 2] | 0; + const W2l = SHA512_W_L[i - 2] | 0; + const s1h = u64.rotrSH(W2h, W2l, 19) ^ u64.rotrBH(W2h, W2l, 61) ^ u64.shrSH(W2h, W2l, 6); + const s1l = u64.rotrSL(W2h, W2l, 19) ^ u64.rotrBL(W2h, W2l, 61) ^ u64.shrSL(W2h, W2l, 6); + // SHA512_W[i] = s0 + s1 + SHA512_W[i - 7] + SHA512_W[i - 16]; + const SUMl = u64.add4L(s0l, s1l, SHA512_W_L[i - 7], SHA512_W_L[i - 16]); + const SUMh = u64.add4H(SUMl, s0h, s1h, SHA512_W_H[i - 7], SHA512_W_H[i - 16]); + SHA512_W_H[i] = SUMh | 0; + SHA512_W_L[i] = SUMl | 0; + } + let { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this; + // Compression function main loop, 80 rounds + for (let i = 0; i < 80; i++) { + // S1 := (e rightrotate 14) xor (e rightrotate 18) xor (e rightrotate 41) + const sigma1h = u64.rotrSH(Eh, El, 14) ^ u64.rotrSH(Eh, El, 18) ^ u64.rotrBH(Eh, El, 41); + const sigma1l = u64.rotrSL(Eh, El, 14) ^ u64.rotrSL(Eh, El, 18) ^ u64.rotrBL(Eh, El, 41); + //const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0; + const CHIh = (Eh & Fh) ^ (~Eh & Gh); + const CHIl = (El & Fl) ^ (~El & Gl); + // T1 = H + sigma1 + Chi(E, F, G) + SHA512_K[i] + SHA512_W[i] + // prettier-ignore + const T1ll = u64.add5L(Hl, sigma1l, CHIl, SHA512_Kl[i], SHA512_W_L[i]); + const T1h = u64.add5H(T1ll, Hh, sigma1h, CHIh, SHA512_Kh[i], SHA512_W_H[i]); + const T1l = T1ll | 0; + // S0 := (a rightrotate 28) xor (a rightrotate 34) xor (a rightrotate 39) + const sigma0h = u64.rotrSH(Ah, Al, 28) ^ u64.rotrBH(Ah, Al, 34) ^ u64.rotrBH(Ah, Al, 39); + const sigma0l = u64.rotrSL(Ah, Al, 28) ^ u64.rotrBL(Ah, Al, 34) ^ u64.rotrBL(Ah, Al, 39); + const MAJh = (Ah & Bh) ^ (Ah & Ch) ^ (Bh & Ch); + const MAJl = (Al & Bl) ^ (Al & Cl) ^ (Bl & Cl); + Hh = Gh | 0; + Hl = Gl | 0; + Gh = Fh | 0; + Gl = Fl | 0; + Fh = Eh | 0; + Fl = El | 0; + ({ h: Eh, l: El } = u64.add(Dh | 0, Dl | 0, T1h | 0, T1l | 0)); + Dh = Ch | 0; + Dl = Cl | 0; + Ch = Bh | 0; + Cl = Bl | 0; + Bh = Ah | 0; + Bl = Al | 0; + const All = u64.add3L(T1l, sigma0l, MAJl); + Ah = u64.add3H(All, T1h, sigma0h, MAJh); + Al = All | 0; + } + // Add the compressed chunk to the current hash value + ({ h: Ah, l: Al } = u64.add(this.Ah | 0, this.Al | 0, Ah | 0, Al | 0)); + ({ h: Bh, l: Bl } = u64.add(this.Bh | 0, this.Bl | 0, Bh | 0, Bl | 0)); + ({ h: Ch, l: Cl } = u64.add(this.Ch | 0, this.Cl | 0, Ch | 0, Cl | 0)); + ({ h: Dh, l: Dl } = u64.add(this.Dh | 0, this.Dl | 0, Dh | 0, Dl | 0)); + ({ h: Eh, l: El } = u64.add(this.Eh | 0, this.El | 0, Eh | 0, El | 0)); + ({ h: Fh, l: Fl } = u64.add(this.Fh | 0, this.Fl | 0, Fh | 0, Fl | 0)); + ({ h: Gh, l: Gl } = u64.add(this.Gh | 0, this.Gl | 0, Gh | 0, Gl | 0)); + ({ h: Hh, l: Hl } = u64.add(this.Hh | 0, this.Hl | 0, Hh | 0, Hl | 0)); + this.set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl); + } + roundClean() { + clean(SHA512_W_H, SHA512_W_L); + } + destroy() { + // HashMD callers route post-destroy usability through `destroyed`; zeroizing alone still leaves + // update()/digest() callable on reused instances. + this.destroyed = true; + clean(this.buffer); + this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + } +} +/** Internal SHA-512 hash class grounded in RFC 6234 §6.3 and §6.4. */ +export class _SHA512 extends SHA2_64B { + Ah = SHA512_IV[0] | 0; + Al = SHA512_IV[1] | 0; + Bh = SHA512_IV[2] | 0; + Bl = SHA512_IV[3] | 0; + Ch = SHA512_IV[4] | 0; + Cl = SHA512_IV[5] | 0; + Dh = SHA512_IV[6] | 0; + Dl = SHA512_IV[7] | 0; + Eh = SHA512_IV[8] | 0; + El = SHA512_IV[9] | 0; + Fh = SHA512_IV[10] | 0; + Fl = SHA512_IV[11] | 0; + Gh = SHA512_IV[12] | 0; + Gl = SHA512_IV[13] | 0; + Hh = SHA512_IV[14] | 0; + Hl = SHA512_IV[15] | 0; + constructor() { + super(64); + } +} +/** Internal SHA-384 hash class grounded in RFC 6234 §6.3 and §6.4. */ +export class _SHA384 extends SHA2_64B { + Ah = SHA384_IV[0] | 0; + Al = SHA384_IV[1] | 0; + Bh = SHA384_IV[2] | 0; + Bl = SHA384_IV[3] | 0; + Ch = SHA384_IV[4] | 0; + Cl = SHA384_IV[5] | 0; + Dh = SHA384_IV[6] | 0; + Dl = SHA384_IV[7] | 0; + Eh = SHA384_IV[8] | 0; + El = SHA384_IV[9] | 0; + Fh = SHA384_IV[10] | 0; + Fl = SHA384_IV[11] | 0; + Gh = SHA384_IV[12] | 0; + Gl = SHA384_IV[13] | 0; + Hh = SHA384_IV[14] | 0; + Hl = SHA384_IV[15] | 0; + constructor() { + super(48); + } +} +/** + * Truncated SHA512/256 and SHA512/224. + * SHA512_IV is XORed with 0xa5a5a5a5a5a5a5a5, then used as "intermediary" IV of SHA512/t. + * Then t hashes string to produce result IV. + * See the repo-side derivation recipe in `test/misc/sha2-gen-iv.js`. + * These IV literals are checked against that script rather than a dedicated + * local RFC section. + */ +/** SHA-512/224 IV derived by the SHA-512/t recipe in `test/misc/sha2-gen-iv.js` and + * stored as sixteen big-endian 32-bit halves. */ +const T224_IV = /* @__PURE__ */ Uint32Array.from([ + 0x8c3d37c8, 0x19544da2, 0x73e19966, 0x89dcd4d6, 0x1dfab7ae, 0x32ff9c82, 0x679dd514, 0x582f9fcf, + 0x0f6d2b69, 0x7bd44da8, 0x77e36f73, 0x04c48942, 0x3f9d85a8, 0x6a1d36c8, 0x1112e6ad, 0x91d692a1, +]); +/** SHA-512/256 IV derived by the SHA-512/t recipe in `test/misc/sha2-gen-iv.js` and + * stored as sixteen big-endian 32-bit halves. */ +const T256_IV = /* @__PURE__ */ Uint32Array.from([ + 0x22312194, 0xfc2bf72c, 0x9f555fa3, 0xc84c64c2, 0x2393b86b, 0x6f53b151, 0x96387719, 0x5940eabd, + 0x96283ee2, 0xa88effe3, 0xbe5e1e25, 0x53863992, 0x2b0199fc, 0x2c85b8aa, 0x0eb72ddc, 0x81c52ca2, +]); +/** Internal SHA-512/224 hash class using the derived `T224_IV` and the shared + * RFC 6234 §6.4 compression engine. */ +export class _SHA512_224 extends SHA2_64B { + Ah = T224_IV[0] | 0; + Al = T224_IV[1] | 0; + Bh = T224_IV[2] | 0; + Bl = T224_IV[3] | 0; + Ch = T224_IV[4] | 0; + Cl = T224_IV[5] | 0; + Dh = T224_IV[6] | 0; + Dl = T224_IV[7] | 0; + Eh = T224_IV[8] | 0; + El = T224_IV[9] | 0; + Fh = T224_IV[10] | 0; + Fl = T224_IV[11] | 0; + Gh = T224_IV[12] | 0; + Gl = T224_IV[13] | 0; + Hh = T224_IV[14] | 0; + Hl = T224_IV[15] | 0; + constructor() { + super(28); + } +} +/** Internal SHA-512/256 hash class using the derived `T256_IV` and the shared + * RFC 6234 §6.4 compression engine. */ +export class _SHA512_256 extends SHA2_64B { + Ah = T256_IV[0] | 0; + Al = T256_IV[1] | 0; + Bh = T256_IV[2] | 0; + Bl = T256_IV[3] | 0; + Ch = T256_IV[4] | 0; + Cl = T256_IV[5] | 0; + Dh = T256_IV[6] | 0; + Dl = T256_IV[7] | 0; + Eh = T256_IV[8] | 0; + El = T256_IV[9] | 0; + Fh = T256_IV[10] | 0; + Fl = T256_IV[11] | 0; + Gh = T256_IV[12] | 0; + Gl = T256_IV[13] | 0; + Hh = T256_IV[14] | 0; + Hl = T256_IV[15] | 0; + constructor() { + super(32); + } +} +/** + * SHA2-256 hash function from RFC 4634. In JS it's the fastest: even faster than Blake3. Some info: + * + * - Trying 2^128 hashes would get 50% chance of collision, using birthday attack. + * - BTC network is doing 2^70 hashes/sec (2^95 hashes/year) as per 2025. + * - Each sha256 hash is executing 2^18 bit operations. + * - Good 2024 ASICs can do 200Th/sec with 3500 watts of power, corresponding to 2^36 hashes/joule. + * @param msg - message bytes to hash + * @returns Digest bytes. + * @example + * Hash a message with SHA2-256. + * ```ts + * sha256(new Uint8Array([97, 98, 99])); + * ``` + */ +export const sha256 = /* @__PURE__ */ createHasher(() => new _SHA256(), +/* @__PURE__ */ oidNist(0x01)); +/** + * SHA2-224 hash function from RFC 4634. + * @param msg - message bytes to hash + * @returns Digest bytes. + * @example + * Hash a message with SHA2-224. + * ```ts + * sha224(new Uint8Array([97, 98, 99])); + * ``` + */ +export const sha224 = /* @__PURE__ */ createHasher(() => new _SHA224(), +/* @__PURE__ */ oidNist(0x04)); +/** + * SHA2-512 hash function from RFC 4634. + * @param msg - message bytes to hash + * @returns Digest bytes. + * @example + * Hash a message with SHA2-512. + * ```ts + * sha512(new Uint8Array([97, 98, 99])); + * ``` + */ +export const sha512 = /* @__PURE__ */ createHasher(() => new _SHA512(), +/* @__PURE__ */ oidNist(0x03)); +/** + * SHA2-384 hash function from RFC 4634. + * @param msg - message bytes to hash + * @returns Digest bytes. + * @example + * Hash a message with SHA2-384. + * ```ts + * sha384(new Uint8Array([97, 98, 99])); + * ``` + */ +export const sha384 = /* @__PURE__ */ createHasher(() => new _SHA384(), +/* @__PURE__ */ oidNist(0x02)); +/** + * SHA2-512/256 "truncated" hash function, with improved resistance to length extension attacks. + * See the paper on {@link https://eprint.iacr.org/2010/548.pdf | truncated SHA512}. + * @param msg - message bytes to hash + * @returns Digest bytes. + * @example + * Hash a message with SHA2-512/256. + * ```ts + * sha512_256(new Uint8Array([97, 98, 99])); + * ``` + */ +export const sha512_256 = /* @__PURE__ */ createHasher(() => new _SHA512_256(), +/* @__PURE__ */ oidNist(0x06)); +/** + * SHA2-512/224 "truncated" hash function, with improved resistance to length extension attacks. + * See the paper on {@link https://eprint.iacr.org/2010/548.pdf | truncated SHA512}. + * @param msg - message bytes to hash + * @returns Digest bytes. + * @example + * Hash a message with SHA2-512/224. + * ```ts + * sha512_224(new Uint8Array([97, 98, 99])); + * ``` + */ +export const sha512_224 = /* @__PURE__ */ createHasher(() => new _SHA512_224(), +/* @__PURE__ */ oidNist(0x05)); +//# sourceMappingURL=sha2.js.map \ No newline at end of file diff --git a/node_modules/@noble/hashes/sha2.js.map b/node_modules/@noble/hashes/sha2.js.map new file mode 100644 index 0000000..9c8bb3d --- /dev/null +++ b/node_modules/@noble/hashes/sha2.js.map @@ -0,0 +1 @@ +{"version":3,"file":"sha2.js","sourceRoot":"","sources":["src/sha2.ts"],"names":[],"mappings":"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,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;QACvE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;QACvE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;QACvE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;QACvE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;QACvE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;QACvE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,GAA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"} \ No newline at end of file diff --git a/node_modules/@noble/hashes/sha3-addons.d.ts b/node_modules/@noble/hashes/sha3-addons.d.ts new file mode 100644 index 0000000..762b044 --- /dev/null +++ b/node_modules/@noble/hashes/sha3-addons.d.ts @@ -0,0 +1,461 @@ +/** + * SHA3 (keccak) addons. + * + * * cSHAKE, KMAC, TupleHash, ParallelHash + XOF variants from + * {@link https://csrc.nist.gov/pubs/sp/800/185/final | NIST SP 800-185} + * * KangarooTwelve 🦘 and TurboSHAKE - reduced-round keccak from + * {@link https://datatracker.ietf.org/doc/rfc9861/ | RFC 9861} + * * KeccakPRG: Pseudo-random generator based on Keccak + * ({@link https://keccak.team/files/CSF-0.1.pdf | pdf}) + * @module + */ +import { Keccak, type ShakeOpts } from './sha3.ts'; +import { type CHash, type CHashXOF, type Hash, type HashXOF, type KDFInput, type PRG, type TArg, type TRet } from './utils.ts'; +/** Options for cSHAKE and related SP 800-185 functions. */ +export type cShakeOpts = ShakeOpts & { + /** Optional personalization string mixed into domain separation. */ + personalization?: Uint8Array; + /** + * Optional NIST function-name string used for domain separation. + * SP 800-185 reserves this for standardized function names; applications + * should generally stick to `personalization`. + */ + NISTfn?: KDFInput; +}; +/** TupleHash callable interface. */ +export type ITupleHash = { + /** + * Hashes an ordered tuple of byte arrays. + * @param messages - Ordered byte-array tuple to hash. + * @param opts - TupleHash output and personalization options. See {@link cShakeOpts}. + * @returns Digest bytes. + */ + (messages: TArg, opts?: TArg): TRet; + /** + * Creates an incremental TupleHash state. + * @param opts - TupleHash output and personalization options. See {@link cShakeOpts}. + * @returns Stateful TupleHash instance. + */ + create(opts?: cShakeOpts): _TupleHash; +}; +/** + * 128-bit NIST cSHAKE XOF. + * @param msg - message bytes to hash + * @param opts - Optional output, personalization, and NIST function-name + * settings. When both `NISTfn` and `personalization` are empty, + * SP 800-185 defines this as plain SHAKE128. Defaults to 16 output bytes + * when `dkLen` is omitted. See {@link cShakeOpts}. + * @returns Digest bytes. + * @example + * Hash a message with cSHAKE128. + * ```ts + * cshake128(new Uint8Array([1, 2, 3]), { dkLen: 32 }); + * ``` + */ +export declare const cshake128: TRet>; +/** + * 256-bit NIST cSHAKE XOF. + * @param msg - message bytes to hash + * @param opts - Optional output, personalization, and NIST function-name + * settings. When both `NISTfn` and `personalization` are empty, + * SP 800-185 defines this as plain SHAKE256. Defaults to 32 output bytes + * when `dkLen` is omitted. See {@link cShakeOpts}. + * @returns Digest bytes. + * @example + * Hash a message with cSHAKE256. + * ```ts + * cshake256(new Uint8Array([1, 2, 3]), { dkLen: 64 }); + * ``` + */ +export declare const cshake256: TRet>; +/** + * Internal KMAC class. + * SP 800-185 §8.4.1 still recommends keys at least as long as the target + * security strength. + */ +export declare class _KMAC extends Keccak implements HashXOF<_KMAC> { + constructor(blockLen: number, outputLen: number, enableXOF: boolean, key: TArg, opts?: TArg); + protected finish(): void; + _cloneInto(to?: _KMAC): _KMAC; + clone(): _KMAC; +} +/** KMAC callable interface. */ +export type IKMAC = { + /** + * Computes a keyed KMAC digest for one message. + * @param key - Secret key bytes. + * @param message - Message bytes to authenticate. + * @param opts - KMAC output and personalization options. See {@link KangarooOpts}. + * @returns Authentication tag bytes. + */ + (key: TArg, message: TArg, opts?: TArg): TRet; + /** + * Creates an incremental KMAC state. + * @param key - Secret key bytes. + * @param opts - KMAC output and personalization options. See {@link cShakeOpts}. + * @returns Stateful KMAC instance. + */ + create(key: TArg, opts?: TArg): _KMAC; +}; +/** + * 128-bit Keccak MAC. + * @param key - MAC key bytes + * @param message - message bytes to authenticate + * @param opts - Optional output and personalization settings. Defaults to + * 16 output bytes when `dkLen` is omitted. See {@link cShakeOpts}. + * @returns Authentication tag bytes. + * @example + * Authenticate a message with KMAC128. + * ```ts + * kmac128(new Uint8Array([1, 2, 3]), new Uint8Array([4, 5, 6])); + * ``` + */ +export declare const kmac128: TRet; +/** + * 256-bit Keccak MAC. + * @param key - MAC key bytes + * @param message - message bytes to authenticate + * @param opts - Optional output and personalization settings. Defaults to + * 32 output bytes when `dkLen` is omitted. See {@link cShakeOpts}. + * @returns Authentication tag bytes. + * @example + * Authenticate a message with KMAC256. + * ```ts + * kmac256(new Uint8Array([1, 2, 3]), new Uint8Array([4, 5, 6])); + * ``` + */ +export declare const kmac256: TRet; +/** + * 128-bit Keccak-MAC XOF. + * @param key - MAC key bytes + * @param message - message bytes to authenticate + * @param opts - Optional output and personalization settings. Defaults to + * 16 output bytes when `dkLen` is omitted. See {@link cShakeOpts}. + * @returns Authentication tag bytes. + * @example + * Authenticate a message with KMAC128 XOF output. + * ```ts + * kmac128xof(new Uint8Array([1, 2, 3]), new Uint8Array([4, 5, 6]), { dkLen: 32 }); + * ``` + */ +export declare const kmac128xof: TRet; +/** + * 256-bit Keccak-MAC XOF. + * @param key - MAC key bytes + * @param message - message bytes to authenticate + * @param opts - Optional output and personalization settings. Defaults to + * 32 output bytes when `dkLen` is omitted. See {@link cShakeOpts}. + * @returns Authentication tag bytes. + * @example + * Authenticate a message with KMAC256 XOF output. + * ```ts + * kmac256xof(new Uint8Array([1, 2, 3]), new Uint8Array([4, 5, 6]), { dkLen: 64 }); + * ``` + */ +export declare const kmac256xof: TRet; +/** + * Internal TupleHash class for byte-array tuple elements. + * This implementation relies on SP 800-185's byte-oriented encoding form + * rather than arbitrary bit strings. + */ +export declare class _TupleHash extends Keccak implements HashXOF<_TupleHash> { + constructor(blockLen: number, outputLen: number, enableXOF: boolean, opts?: TArg); + protected finish(): void; + _cloneInto(to?: _TupleHash): _TupleHash; + clone(): _TupleHash; +} +/** + * 128-bit TupleHASH. `tuple(['ab', 'cd']) != tuple(['a', 'bcd'])`. + * @param messages - ordered byte-array tuple + * @param opts - Optional output and personalization settings. Defaults to + * 16 output bytes when `dkLen` is omitted. See {@link cShakeOpts}. + * @returns Digest bytes. + * @example + * Hash a tuple of byte arrays with TupleHash128. + * ```ts + * tuplehash128([new Uint8Array([1]), new Uint8Array([2])]); + * ``` + */ +export declare const tuplehash128: TRet; +/** + * 256-bit TupleHASH. `tuple(['ab', 'cd']) != tuple(['a', 'bcd'])`. + * @param messages - ordered byte-array tuple + * @param opts - Optional output and personalization settings. Defaults to + * 32 output bytes when `dkLen` is omitted. See {@link cShakeOpts}. + * @returns Digest bytes. + * @example + * Hash a tuple of byte arrays with TupleHash256. + * ```ts + * tuplehash256([new Uint8Array([1]), new Uint8Array([2])]); + * ``` + */ +export declare const tuplehash256: TRet; +/** + * 128-bit TupleHASH XOF. + * @param messages - ordered byte-array tuple + * @param opts - Optional output and personalization settings. Defaults to + * 16 output bytes when `dkLen` is omitted. See {@link cShakeOpts}. + * @returns Digest bytes. + * @example + * Hash a tuple of byte arrays with TupleHash128 XOF output. + * ```ts + * tuplehash128xof([new Uint8Array([1]), new Uint8Array([2])], { dkLen: 32 }); + * ``` + */ +export declare const tuplehash128xof: TRet; +/** + * 256-bit TupleHASH XOF. + * @param messages - ordered byte-array tuple + * @param opts - Optional output and personalization settings. Defaults to + * 32 output bytes when `dkLen` is omitted. See {@link cShakeOpts}. + * @returns Digest bytes. + * @example + * Hash a tuple of byte arrays with TupleHash256 XOF output. + * ```ts + * tuplehash256xof([new Uint8Array([1]), new Uint8Array([2])], { dkLen: 64 }); + * ``` + */ +export declare const tuplehash256xof: TRet; +type ParallelOpts = KangarooOpts & { + blockLen?: number; +}; +/** Internal Parallel Keccak Hash class. */ +export declare class _ParallelHash extends Keccak implements HashXOF<_ParallelHash> { + private leafHash?; + protected leafCons: () => Hash; + private chunkPos; + private chunksDone; + private chunkLen; + constructor(blockLen: number, outputLen: number, leafCons: () => Hash, enableXOF: boolean, opts?: TArg); + protected finish(): void; + _cloneInto(to?: _ParallelHash): _ParallelHash; + destroy(): void; + clone(): _ParallelHash; +} +/** + * 128-bit ParallelHash. In JS, it is not parallel. + * @param msg - message bytes to hash + * @param opts - Optional output, personalization, and chunking settings. + * Defaults to 16 output bytes when `dkLen` is omitted. + * See {@link ParallelOpts}. + * @returns Digest bytes. + * @example + * Hash a message with ParallelHash128. + * ```ts + * parallelhash128(new Uint8Array([1, 2, 3])); + * ``` + */ +export declare const parallelhash128: TRet>; +/** + * 256-bit ParallelHash. In JS, it is not parallel. + * @param msg - message bytes to hash + * @param opts - Optional output, personalization, and chunking settings. + * Defaults to 32 output bytes when `dkLen` is omitted. + * See {@link ParallelOpts}. + * @returns Digest bytes. + * @example + * Hash a message with ParallelHash256. + * ```ts + * parallelhash256(new Uint8Array([1, 2, 3])); + * ``` + */ +export declare const parallelhash256: TRet>; +/** + * 128-bit ParallelHash XOF. In JS, it is not parallel. + * @param msg - message bytes to hash + * @param opts - Optional output, personalization, and chunking settings. + * Defaults to 16 output bytes when `dkLen` is omitted. + * See {@link ParallelOpts}. + * @returns Digest bytes. + * @example + * Hash a message with ParallelHash128 XOF output. + * ```ts + * parallelhash128xof(new Uint8Array([1, 2, 3]), { dkLen: 32 }); + * ``` + */ +export declare const parallelhash128xof: TRet>; +/** + * 256-bit ParallelHash XOF. In JS, it is not parallel. + * @param msg - message bytes to hash + * @param opts - Optional output, personalization, and chunking settings. + * Defaults to 32 output bytes when `dkLen` is omitted. + * See {@link ParallelOpts}. + * @returns Digest bytes. + * @example + * Hash a message with ParallelHash256 XOF output. + * ```ts + * parallelhash256xof(new Uint8Array([1, 2, 3]), { dkLen: 64 }); + * ``` + */ +export declare const parallelhash256xof: TRet>; +/** + * TurboSHAKE options. + * `D` is the domain separation byte; RFC 9861 defines output length `L` + * as a positive integer. + */ +export type TurboshakeOpts = ShakeOpts & { + /** Optional domain separation byte in the `0x01..0x7f` range. */ + D?: number; +}; +/** + * TurboSHAKE 128-bit: reduced 12-round keccak. + * Should've been a simple "shake with 12 rounds", but we got a whole new + * spec about Turbo SHAKE Pro MAX. + * @param msg - message bytes to hash + * @param opts - Optional output-length and domain-separation settings. + * RFC 9861 §2.1 defaults `D` to `0x1f`. Defaults to 32 output bytes when + * `dkLen` is omitted. See {@link TurboshakeOpts}. + * @returns Digest bytes. + * @example + * Hash a message with TurboSHAKE128. + * ```ts + * turboshake128(new Uint8Array([1, 2, 3]), { dkLen: 32 }); + * ``` + */ +export declare const turboshake128: TRet>; +/** + * TurboSHAKE 256-bit: reduced 12-round keccak. + * @param msg - message bytes to hash + * @param opts - Optional output-length and domain-separation settings. + * RFC 9861 §2.1 defaults `D` to `0x1f`. Defaults to 64 output bytes when + * `dkLen` is omitted. See {@link TurboshakeOpts}. + * @returns Digest bytes. + * @example + * Hash a message with TurboSHAKE256. + * ```ts + * turboshake256(new Uint8Array([1, 2, 3]), { dkLen: 64 }); + * ``` + */ +export declare const turboshake256: TRet>; +/** K12 options. */ +export type KangarooOpts = { + /** + * Desired digest length in bytes. + * RFC 9861 §3 defines output length `L` as a positive integer. + */ + dkLen?: number; + /** + * Optional personalization string mixed into the sponge state. + * Stateful K12 instances keep an internal copy so caller buffers can be + * wiped independently. + */ + personalization?: Uint8Array; +}; +/** Internal K12 hash class. */ +export declare class _KangarooTwelve extends Keccak implements HashXOF<_KangarooTwelve> { + readonly chunkLen = 8192; + private leafHash?; + protected leafLen: number; + private personalization; + private chunkPos; + private chunksDone; + constructor(blockLen: number, leafLen: number, outputLen: number, rounds: number, opts: TArg); + update(data: TArg): this; + protected finish(): void; + destroy(): void; + _cloneInto(to?: _KangarooTwelve): _KangarooTwelve; + clone(): _KangarooTwelve; +} +/** + * 128-bit KangarooTwelve (k12): reduced 12-round keccak. + * @param msg - message bytes to hash + * @param opts - Optional output and personalization settings. Defaults to + * 32 output bytes when `dkLen` is omitted. See {@link KangarooOpts}. + * @returns Digest bytes. + * @example + * Hash a message with KangarooTwelve-128. + * ```ts + * kt128(new Uint8Array([1, 2, 3])); + * ``` + */ +export declare const kt128: TRet>; +/** + * 256-bit KangarooTwelve (k12): reduced 12-round keccak. + * @param msg - message bytes to hash + * @param opts - Optional output and personalization settings. Defaults to + * 64 output bytes when `dkLen` is omitted. See {@link KangarooOpts}. + * @returns Digest bytes. + * @example + * Hash a message with KangarooTwelve-256. + * ```ts + * kt256(new Uint8Array([1, 2, 3])); + * ``` + */ +export declare const kt256: TRet>; +/** KangarooTwelve-based MAC function type. */ +export type HopMAC = (key: TArg, message: TArg, personalization: TArg, dkLen?: number) => TRet; +/** + * 128-bit KangarooTwelve-based MAC. + * + * These untested (there is no test vectors or implementation available). Use at your own risk. + * HopMAC128(Key, M, C, L) = KT128(Key, KT128(M, C, 32), L) + * HopMAC256(Key, M, C, L) = KT256(Key, KT256(M, C, 64), L) + * The inner KangarooTwelve call always uses a fixed 32-byte digest here, + * regardless of the outer `dkLen`. + * @param key - MAC key bytes + * @param message - message bytes to authenticate + * @param personalization - personalization bytes mixed into the inner hash + * @param dkLen - optional output length in bytes + * @returns Authentication tag bytes. + * @example + * Authenticate a message with HopMAC128. + * ```ts + * HopMAC128(new Uint8Array([1]), new Uint8Array([2]), new Uint8Array([3]), 32); + * ``` + */ +export declare const HopMAC128: TRet; +/** + * 256-bit KangarooTwelve-based MAC. + * Like `HopMAC128`, there are no test vectors or known independent + * implementations available for cross-checking. + * @param key - MAC key bytes + * @param message - message bytes to authenticate + * @param personalization - personalization bytes mixed into the inner hash + * @param dkLen - optional output length in bytes. The inner KangarooTwelve + * call still uses a fixed 64-byte digest here, regardless of the outer + * `dkLen`. + * @returns Authentication tag bytes. + * @example + * Authenticate a message with HopMAC256. + * ```ts + * HopMAC256(new Uint8Array([1]), new Uint8Array([2]), new Uint8Array([3]), 64); + * ``` + */ +export declare const HopMAC256: TRet; +/** + * More at + * {@link https://github.com/XKCP/XKCP/tree/master/lib/high/Keccak/PRG}. + * Accepted capacities must keep `rho = 1598 - capacity` byte-aligned, and + * `.clean()` later also requires `rate > 801`. + */ +export declare class _KeccakPRG extends Keccak implements PRG { + protected rate: number; + constructor(capacity: number); + protected keccak(): void; + update(data: TArg): this; + protected finish(): void; + digestInto(_out: TArg): void; + addEntropy(seed: TArg): void; + randomBytes(length: number): TRet; + clean(): void; + _cloneInto(to?: _KeccakPRG): _KeccakPRG; + clone(): _KeccakPRG; +} +/** + * KeccakPRG: pseudo-random generator based on Keccak. + * See {@link https://keccak.team/files/CSF-0.1.pdf}. + * @param capacity - sponge capacity in bits. Accepted values are those that + * keep `rho = 1598 - capacity` byte-aligned; the default `254` is chosen + * because it satisfies that duplex layout while leaving a wide byte-aligned + * rate. + * @returns PRG instance backed by a Keccak sponge. + * @example + * Create a Keccak-based pseudorandom generator and read bytes from it. + * ```ts + * const prg = keccakprg(254); + * prg.randomBytes(8); + * ``` + */ +export declare const keccakprg: (capacity?: number) => TRet<_KeccakPRG>; +export {}; +//# sourceMappingURL=sha3-addons.d.ts.map \ No newline at end of file diff --git a/node_modules/@noble/hashes/sha3-addons.d.ts.map b/node_modules/@noble/hashes/sha3-addons.d.ts.map new file mode 100644 index 0000000..e43e1e3 --- /dev/null +++ b/node_modules/@noble/hashes/sha3-addons.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"sha3-addons.d.ts","sourceRoot":"","sources":["src/sha3-addons.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@noble/hashes/sha3-addons.js b/node_modules/@noble/hashes/sha3-addons.js new file mode 100644 index 0000000..21229ed --- /dev/null +++ b/node_modules/@noble/hashes/sha3-addons.js @@ -0,0 +1,783 @@ +/** + * SHA3 (keccak) addons. + * + * * cSHAKE, KMAC, TupleHash, ParallelHash + XOF variants from + * {@link https://csrc.nist.gov/pubs/sp/800/185/final | NIST SP 800-185} + * * KangarooTwelve 🦘 and TurboSHAKE - reduced-round keccak from + * {@link https://datatracker.ietf.org/doc/rfc9861/ | RFC 9861} + * * KeccakPRG: Pseudo-random generator based on Keccak + * ({@link https://keccak.team/files/CSF-0.1.pdf | pdf}) + * @module + */ +import { Keccak } from "./sha3.js"; +import { abytes, aexists, anumber, clean, copyBytes, createHasher, kdfInputToBytes, u32, } from "./utils.js"; +// cSHAKE && KMAC (NIST SP800-185) +const _8n = /* @__PURE__ */ BigInt(8); +const _ffn = /* @__PURE__ */ BigInt(0xff); +// It is safe to use bigints here, since they used only for length encoding (not actual data). +// We use bigints in sha256 for lengths too. +// Callers are still expected to supply SP 800-185-valid lengths +// (`0 <= x < 2^2040`); this helper does not enforce that bound. +function leftEncode(n) { + n = BigInt(n); + const res = [Number(n & _ffn)]; + n >>= _8n; + for (; n > 0; n >>= _8n) + res.unshift(Number(n & _ffn)); + res.unshift(res.length); + return new Uint8Array(res); +} +// Same caller contract as `leftEncode(...)`: lengths must already satisfy SP 800-185 §2.3.1. +function rightEncode(n) { + n = BigInt(n); + const res = [Number(n & _ffn)]; + n >>= _8n; + for (; n > 0; n >>= _8n) + res.unshift(Number(n & _ffn)); + res.push(res.length); + return new Uint8Array(res); +} +// `dkLen` validation is deferred to the downstream Keccak constructor. +function chooseLen(opts, outputLen) { + return opts.dkLen === undefined ? outputLen : opts.dkLen; +} +const abytesOrZero = (buf, title = '') => { + if (buf === undefined) + return EMPTY_BUFFER; + abytes(buf, undefined, title); + return buf; +}; +// NOTE: second modulo is necessary since we don't need to add padding if the +// current element takes a whole block. +// Callers only pass the fixed positive Keccak rates here (`168` or `136`); +// `block <= 0` is not validated locally. +const getPadding = (len, block) => new Uint8Array((block - (len % block)) % block); +// Personalization +function cshakePers(hash, opts = {}) { + const h = hash; + if (!opts || (opts.personalization === undefined && opts.NISTfn === undefined)) + return h; + // Encode and pad inplace to avoid unneccesary memory copies/slices so we + // don't need to zero them later. + // bytepad(encode_string(N) || encode_string(S), rate), where `rate` is the + // current cSHAKE/KMAC/TupleHash/ParallelHash block length. + const blockLenBytes = leftEncode(h.blockLen); + const fn = opts.NISTfn === undefined ? EMPTY_BUFFER : kdfInputToBytes(opts.NISTfn); + const fnLen = leftEncode(_8n * BigInt(fn.length)); // length in bits + const pers = abytesOrZero(opts.personalization, 'personalization'); + const persLen = leftEncode(_8n * BigInt(pers.length)); // length in bits + if (!fn.length && !pers.length) + return h; + // SP 800-185 cSHAKE appends `00` instead of SHAKE's `1111`; in this Keccak implementation + // that changes the delimited suffix byte from `0x1f` to `0x04` once N or S is non-empty. + h.suffix = 0x04; + h.update(blockLenBytes).update(fnLen).update(fn).update(persLen).update(pers); + let totalLen = blockLenBytes.length + fnLen.length + fn.length + persLen.length + pers.length; + h.update(getPadding(totalLen, h.blockLen)); + return h; +} +const gencShake = (suffix, blockLen, outputLen) => createHasher((opts = {}) => cshakePers(new Keccak(blockLen, suffix, chooseLen(opts, outputLen), true), opts)); +/** + * 128-bit NIST cSHAKE XOF. + * @param msg - message bytes to hash + * @param opts - Optional output, personalization, and NIST function-name + * settings. When both `NISTfn` and `personalization` are empty, + * SP 800-185 defines this as plain SHAKE128. Defaults to 16 output bytes + * when `dkLen` is omitted. See {@link cShakeOpts}. + * @returns Digest bytes. + * @example + * Hash a message with cSHAKE128. + * ```ts + * cshake128(new Uint8Array([1, 2, 3]), { dkLen: 32 }); + * ``` + */ +export const cshake128 = /* @__PURE__ */ gencShake(0x1f, 168, 16); +/** + * 256-bit NIST cSHAKE XOF. + * @param msg - message bytes to hash + * @param opts - Optional output, personalization, and NIST function-name + * settings. When both `NISTfn` and `personalization` are empty, + * SP 800-185 defines this as plain SHAKE256. Defaults to 32 output bytes + * when `dkLen` is omitted. See {@link cShakeOpts}. + * @returns Digest bytes. + * @example + * Hash a message with cSHAKE256. + * ```ts + * cshake256(new Uint8Array([1, 2, 3]), { dkLen: 64 }); + * ``` + */ +export const cshake256 = /* @__PURE__ */ gencShake(0x1f, 136, 32); +/** + * Internal KMAC class. + * SP 800-185 §8.4.1 still recommends keys at least as long as the target + * security strength. + */ +export class _KMAC extends Keccak { + constructor(blockLen, outputLen, enableXOF, key, opts = {}) { + super(blockLen, 0x1f, outputLen, enableXOF); + // Preload T = bytepad(encode_string("KMAC") || encode_string(S), rate); later updates append + // newX = bytepad(encode_string(K), rate) || X and `finish()` appends right_encode(L or 0). + cshakePers(this, { + NISTfn: 'KMAC', + personalization: opts.personalization, + }); + abytes(key, undefined, 'key'); + // 1. newX = bytepad(encode_string(K), rate) || X || right_encode(L), + // with `rate = this.blockLen`. + const blockLenBytes = leftEncode(this.blockLen); + const keyLen = leftEncode(_8n * BigInt(key.length)); + this.update(blockLenBytes).update(keyLen).update(key); + const totalLen = blockLenBytes.length + keyLen.length + key.length; + this.update(getPadding(totalLen, this.blockLen)); + } + finish() { + // SP 800-185 uses right_encode(L) for fixed-length KMAC and right_encode(0) for KMACXOF. + // outputLen in bits + if (!this.finished) + this.update(rightEncode(this.enableXOF ? 0 : _8n * BigInt(this.outputLen))); + super.finish(); + } + _cloneInto(to) { + // Create new instance without calling constructor since the key + // is already in state and we don't know it. + // Force "to" to be instance of KMAC instead of Sha3. + if (!to) { + to = Object.create(Object.getPrototypeOf(this), {}); + to.state = this.state.slice(); + to.blockLen = this.blockLen; + to.state32 = u32(to.state); + } + return super._cloneInto(to); + } + clone() { + return this._cloneInto(); + } +} +function genKmac(blockLen, outputLen, xof = false) { + // One-shot XOF wrappers still finalize via `.digest()` because `_KMAC` + // already bakes the requested output length into the state. + const kmac = (key, message, opts) => kmac.create(key, opts).update(message).digest(); + kmac.create = (key, opts = {}) => new _KMAC(blockLen, chooseLen(opts, outputLen), xof, key, opts); + return kmac; +} +/** + * 128-bit Keccak MAC. + * @param key - MAC key bytes + * @param message - message bytes to authenticate + * @param opts - Optional output and personalization settings. Defaults to + * 16 output bytes when `dkLen` is omitted. See {@link cShakeOpts}. + * @returns Authentication tag bytes. + * @example + * Authenticate a message with KMAC128. + * ```ts + * kmac128(new Uint8Array([1, 2, 3]), new Uint8Array([4, 5, 6])); + * ``` + */ +export const kmac128 = /* @__PURE__ */ genKmac(168, 16); +/** + * 256-bit Keccak MAC. + * @param key - MAC key bytes + * @param message - message bytes to authenticate + * @param opts - Optional output and personalization settings. Defaults to + * 32 output bytes when `dkLen` is omitted. See {@link cShakeOpts}. + * @returns Authentication tag bytes. + * @example + * Authenticate a message with KMAC256. + * ```ts + * kmac256(new Uint8Array([1, 2, 3]), new Uint8Array([4, 5, 6])); + * ``` + */ +export const kmac256 = /* @__PURE__ */ genKmac(136, 32); +/** + * 128-bit Keccak-MAC XOF. + * @param key - MAC key bytes + * @param message - message bytes to authenticate + * @param opts - Optional output and personalization settings. Defaults to + * 16 output bytes when `dkLen` is omitted. See {@link cShakeOpts}. + * @returns Authentication tag bytes. + * @example + * Authenticate a message with KMAC128 XOF output. + * ```ts + * kmac128xof(new Uint8Array([1, 2, 3]), new Uint8Array([4, 5, 6]), { dkLen: 32 }); + * ``` + */ +export const kmac128xof = /* @__PURE__ */ genKmac(168, 16, true); +/** + * 256-bit Keccak-MAC XOF. + * @param key - MAC key bytes + * @param message - message bytes to authenticate + * @param opts - Optional output and personalization settings. Defaults to + * 32 output bytes when `dkLen` is omitted. See {@link cShakeOpts}. + * @returns Authentication tag bytes. + * @example + * Authenticate a message with KMAC256 XOF output. + * ```ts + * kmac256xof(new Uint8Array([1, 2, 3]), new Uint8Array([4, 5, 6]), { dkLen: 64 }); + * ``` + */ +export const kmac256xof = /* @__PURE__ */ genKmac(136, 32, true); +/** + * Internal TupleHash class for byte-array tuple elements. + * This implementation relies on SP 800-185's byte-oriented encoding form + * rather than arbitrary bit strings. + */ +export class _TupleHash extends Keccak { + constructor(blockLen, outputLen, enableXOF, opts = {}) { + super(blockLen, 0x1f, outputLen, enableXOF); + cshakePers(this, { + NISTfn: 'TupleHash', + personalization: opts.personalization, + }); + // Change update after cshake processed + this.update = (data) => { + abytes(data); + // SP 800-185 encodes each tuple element as + // encode_string(X[i]) = left_encode(len(X[i])) || X[i]. + super.update(leftEncode(_8n * BigInt(data.length))); + super.update(data); + return this; + }; + } + finish() { + // SP 800-185 uses right_encode(L) for fixed-length TupleHash + // and right_encode(0) for TupleHashXOF. + if (!this.finished) + // outputLen in bits + super.update(rightEncode(this.enableXOF ? 0 : _8n * BigInt(this.outputLen))); + super.finish(); + } + _cloneInto(to) { + to ||= new _TupleHash(this.blockLen, this.outputLen, this.enableXOF); + return super._cloneInto(to); + } + clone() { + return this._cloneInto(); + } +} +function genTuple(blockLen, outputLen, xof = false) { + // One-shot XOF wrappers still use `.digest()` because `_TupleHash` stores + // the requested output length in the state itself. + const tuple = (messages, opts) => { + const h = tuple.create(opts); + if (!Array.isArray(messages)) + throw new Error('expected array of messages'); + for (const msg of messages) + h.update(msg); + return h.digest(); + }; + tuple.create = (opts = {}) => new _TupleHash(blockLen, chooseLen(opts, outputLen), xof, opts); + return tuple; +} +/** + * 128-bit TupleHASH. `tuple(['ab', 'cd']) != tuple(['a', 'bcd'])`. + * @param messages - ordered byte-array tuple + * @param opts - Optional output and personalization settings. Defaults to + * 16 output bytes when `dkLen` is omitted. See {@link cShakeOpts}. + * @returns Digest bytes. + * @example + * Hash a tuple of byte arrays with TupleHash128. + * ```ts + * tuplehash128([new Uint8Array([1]), new Uint8Array([2])]); + * ``` + */ +export const tuplehash128 = /* @__PURE__ */ genTuple(168, 16); +/** + * 256-bit TupleHASH. `tuple(['ab', 'cd']) != tuple(['a', 'bcd'])`. + * @param messages - ordered byte-array tuple + * @param opts - Optional output and personalization settings. Defaults to + * 32 output bytes when `dkLen` is omitted. See {@link cShakeOpts}. + * @returns Digest bytes. + * @example + * Hash a tuple of byte arrays with TupleHash256. + * ```ts + * tuplehash256([new Uint8Array([1]), new Uint8Array([2])]); + * ``` + */ +export const tuplehash256 = /* @__PURE__ */ genTuple(136, 32); +/** + * 128-bit TupleHASH XOF. + * @param messages - ordered byte-array tuple + * @param opts - Optional output and personalization settings. Defaults to + * 16 output bytes when `dkLen` is omitted. See {@link cShakeOpts}. + * @returns Digest bytes. + * @example + * Hash a tuple of byte arrays with TupleHash128 XOF output. + * ```ts + * tuplehash128xof([new Uint8Array([1]), new Uint8Array([2])], { dkLen: 32 }); + * ``` + */ +export const tuplehash128xof = /* @__PURE__ */ genTuple(168, 16, true); +/** + * 256-bit TupleHASH XOF. + * @param messages - ordered byte-array tuple + * @param opts - Optional output and personalization settings. Defaults to + * 32 output bytes when `dkLen` is omitted. See {@link cShakeOpts}. + * @returns Digest bytes. + * @example + * Hash a tuple of byte arrays with TupleHash256 XOF output. + * ```ts + * tuplehash256xof([new Uint8Array([1]), new Uint8Array([2])], { dkLen: 64 }); + * ``` + */ +export const tuplehash256xof = /* @__PURE__ */ genTuple(136, 32, true); +/** Internal Parallel Keccak Hash class. */ +export class _ParallelHash extends Keccak { + leafHash; + leafCons; + chunkPos = 0; // Position of current block in chunk + chunksDone = 0; // How many chunks we already have + chunkLen; + constructor(blockLen, outputLen, leafCons, enableXOF, opts = {}) { + super(blockLen, 0x1f, outputLen, enableXOF); + cshakePers(this, { + NISTfn: 'ParallelHash', + personalization: opts.personalization, + }); + this.leafCons = leafCons; + let { blockLen: B = 8 } = opts; + anumber(B); + // blockLen=0 makes take=0 in update(), so pos never advances and the hash hangs. + if (B < 1) + throw new Error('"blockLen" must be >= 1, got ' + B); + this.chunkLen = B; + // SP 800-185 initializes z = left_encode(B); each completed chunk appends + // one fixed-size cSHAKE leaf digest before finish() adds right_encode(n) + // and right_encode(L or 0). + super.update(leftEncode(B)); + // Change update after cshake processed + this.update = (data) => { + abytes(data); + const { chunkLen, leafCons } = this; + for (let pos = 0, len = data.length; pos < len;) { + if (this.chunkPos == chunkLen || !this.leafHash) { + if (this.leafHash) { + super.update(this.leafHash.digest()); + this.chunksDone++; + } + this.leafHash = leafCons(); + this.chunkPos = 0; + } + const take = Math.min(chunkLen - this.chunkPos, len - pos); + this.leafHash.update(data.subarray(pos, pos + take)); + this.chunkPos += take; + pos += take; + } + return this; + }; + } + finish() { + if (this.finished) + return; + if (this.leafHash) { + super.update(this.leafHash.digest()); + this.chunksDone++; + } + // SP 800-185 finishes ParallelHash as + // z || right_encode(n) || right_encode(L); XOF mode replaces + // right_encode(L) with right_encode(0). + super.update(rightEncode(this.chunksDone)); + // outputLen in bits + super.update(rightEncode(this.enableXOF ? 0 : _8n * BigInt(this.outputLen))); + super.finish(); + } + _cloneInto(to) { + to ||= new _ParallelHash(this.blockLen, this.outputLen, this.leafCons, this.enableXOF); + to.leafCons = this.leafCons; + // Reused destinations can carry a stale partial leaf + // when the source is still on the root sponge. + if (this.leafHash) + to.leafHash = this.leafHash._cloneInto(to.leafHash); + else if (to.leafHash) { + to.leafHash.destroy(); + to.leafHash = undefined; + } + to.chunkPos = this.chunkPos; + to.chunkLen = this.chunkLen; + to.chunksDone = this.chunksDone; + return super._cloneInto(to); + } + destroy() { + super.destroy.call(this); + if (this.leafHash) + this.leafHash.destroy(); + } + clone() { + return this._cloneInto(); + } +} +function genPrl(blockLen, outputLen, leaf, xof = false) { + const parallel = (message, opts) => parallel.create(opts).update(message).digest(); + parallel.create = (opts = {}) => new _ParallelHash(blockLen, chooseLen(opts, outputLen), + // SP 800-185 fixes leaf digests at 256 bits for ParallelHash128 and + // 512 bits for ParallelHash256; only the final cSHAKE output uses the + // caller-selected dkLen. + () => leaf.create({ dkLen: 2 * outputLen }), xof, opts); + parallel.outputLen = outputLen; + parallel.blockLen = blockLen; + parallel.canXOF = xof; + return parallel; +} +/** + * 128-bit ParallelHash. In JS, it is not parallel. + * @param msg - message bytes to hash + * @param opts - Optional output, personalization, and chunking settings. + * Defaults to 16 output bytes when `dkLen` is omitted. + * See {@link ParallelOpts}. + * @returns Digest bytes. + * @example + * Hash a message with ParallelHash128. + * ```ts + * parallelhash128(new Uint8Array([1, 2, 3])); + * ``` + */ +export const parallelhash128 = /* @__PURE__ */ genPrl(168, 16, cshake128); +/** + * 256-bit ParallelHash. In JS, it is not parallel. + * @param msg - message bytes to hash + * @param opts - Optional output, personalization, and chunking settings. + * Defaults to 32 output bytes when `dkLen` is omitted. + * See {@link ParallelOpts}. + * @returns Digest bytes. + * @example + * Hash a message with ParallelHash256. + * ```ts + * parallelhash256(new Uint8Array([1, 2, 3])); + * ``` + */ +export const parallelhash256 = /* @__PURE__ */ genPrl(136, 32, cshake256); +/** + * 128-bit ParallelHash XOF. In JS, it is not parallel. + * @param msg - message bytes to hash + * @param opts - Optional output, personalization, and chunking settings. + * Defaults to 16 output bytes when `dkLen` is omitted. + * See {@link ParallelOpts}. + * @returns Digest bytes. + * @example + * Hash a message with ParallelHash128 XOF output. + * ```ts + * parallelhash128xof(new Uint8Array([1, 2, 3]), { dkLen: 32 }); + * ``` + */ +export const parallelhash128xof = /* @__PURE__ */ genPrl(168, 16, cshake128, true); +/** + * 256-bit ParallelHash XOF. In JS, it is not parallel. + * @param msg - message bytes to hash + * @param opts - Optional output, personalization, and chunking settings. + * Defaults to 32 output bytes when `dkLen` is omitted. + * See {@link ParallelOpts}. + * @returns Digest bytes. + * @example + * Hash a message with ParallelHash256 XOF output. + * ```ts + * parallelhash256xof(new Uint8Array([1, 2, 3]), { dkLen: 64 }); + * ``` + */ +export const parallelhash256xof = /* @__PURE__ */ genPrl(136, 32, cshake256, true); +const genTurbo = (blockLen, outputLen) => createHasher((opts = {}) => { + const D = opts.D === undefined ? 0x1f : opts.D; + // RFC 9861 §2.1 fixes the default `D = 0x1f`; §2.2 defines the 12-round + // TurboSHAKE family selected here. + if (!Number.isSafeInteger(D) || D < 0x01 || D > 0x7f) + throw new Error('"D" (domain separation byte) must be 0x01..0x7f, got: ' + D); + const dkLen = opts.dkLen === undefined ? outputLen : opts.dkLen; + // RFC 9861 §§2.1-2.2 define output length L as a positive integer. + if (dkLen < 1) + throw new Error('"dkLen" must be >= 1'); + return new Keccak(blockLen, D, dkLen, true, 12); +}); +/** + * TurboSHAKE 128-bit: reduced 12-round keccak. + * Should've been a simple "shake with 12 rounds", but we got a whole new + * spec about Turbo SHAKE Pro MAX. + * @param msg - message bytes to hash + * @param opts - Optional output-length and domain-separation settings. + * RFC 9861 §2.1 defaults `D` to `0x1f`. Defaults to 32 output bytes when + * `dkLen` is omitted. See {@link TurboshakeOpts}. + * @returns Digest bytes. + * @example + * Hash a message with TurboSHAKE128. + * ```ts + * turboshake128(new Uint8Array([1, 2, 3]), { dkLen: 32 }); + * ``` + */ +export const turboshake128 = /* @__PURE__ */ genTurbo(168, 32); +/** + * TurboSHAKE 256-bit: reduced 12-round keccak. + * @param msg - message bytes to hash + * @param opts - Optional output-length and domain-separation settings. + * RFC 9861 §2.1 defaults `D` to `0x1f`. Defaults to 64 output bytes when + * `dkLen` is omitted. See {@link TurboshakeOpts}. + * @returns Digest bytes. + * @example + * Hash a message with TurboSHAKE256. + * ```ts + * turboshake256(new Uint8Array([1, 2, 3]), { dkLen: 64 }); + * ``` + */ +export const turboshake256 = /* @__PURE__ */ genTurbo(136, 64); +// Same as NIST rightEncode, but returns `[0]` for the zero string. +// Callers still need to keep `x < 256^255` per RFC 9861 §3.3. +function rightEncodeK12(n) { + n = BigInt(n); + const res = []; + for (; n > 0; n >>= _8n) + res.unshift(Number(n & _ffn)); + res.push(res.length); + return Uint8Array.from(res); +} +const EMPTY_BUFFER = /* @__PURE__ */ Uint8Array.of(); +/** Internal K12 hash class. */ +export class _KangarooTwelve extends Keccak { + chunkLen = 8192; + leafHash; + leafLen; + personalization; + chunkPos = 0; // Position of current block in chunk + chunksDone = 0; // How many chunks we already have + constructor(blockLen, leafLen, outputLen, rounds, opts) { + super(blockLen, 0x07, outputLen, true, rounds); + // RFC 9861 §3 defines output length L as a positive integer. + if (outputLen < 1) + throw new Error('"dkLen" must be >= 1'); + this.leafLen = leafLen; + this.personalization = + opts.personalization === undefined + ? EMPTY_BUFFER + : copyBytes(abytes(opts.personalization, undefined, 'personalization')); + } + update(data) { + abytes(data); + const { chunkLen, blockLen, leafLen, rounds } = this; + for (let pos = 0, len = data.length; pos < len;) { + if (this.chunkPos == chunkLen) { + if (this.leafHash) + super.update(this.leafHash.digest()); + else { + // RFC 9861 §3.2 switches from SingleNode (`07`) to FinalNode (`06`) + // once S exceeds 8192 bytes and prefixes S_0 with + // `03 00 00 00 00 00 00 00`. + this.suffix = 0x06; // Its safe to change suffix here since its used only in digest() + super.update(Uint8Array.from([3, 0, 0, 0, 0, 0, 0, 0])); + } + // Secondary chunks S_1..S_(n-1) become fixed-length + // CV_i = TurboSHAKE*(S_i, `0B`, 32|64) chaining values. + this.leafHash = new Keccak(blockLen, 0x0b, leafLen, false, rounds); + this.chunksDone++; + this.chunkPos = 0; + } + const take = Math.min(chunkLen - this.chunkPos, len - pos); + const chunk = data.subarray(pos, pos + take); + if (this.leafHash) + this.leafHash.update(chunk); + else + super.update(chunk); + this.chunkPos += take; + pos += take; + } + return this; + } + finish() { + if (this.finished) + return; + const { personalization } = this; + // RFC 9861 §3.2 forms S = M || C || length_encode(|C|) before any tree hashing logic. + this.update(personalization).update(rightEncodeK12(personalization.length)); + // Leaf hash + if (this.leafHash) { + // Multi-chunk K12 appends + // CV_1..CV_(n-1) || length_encode(n-1) || `FF FF` + // before the final TurboSHAKE call. + super.update(this.leafHash.digest()); + super.update(rightEncodeK12(this.chunksDone)); + super.update(Uint8Array.from([0xff, 0xff])); + } + super.finish.call(this); + } + destroy() { + super.destroy.call(this); + if (this.leafHash) + this.leafHash.destroy(); + // Personalization is copied on create/clone, so destroy can wipe it + // without touching caller input. + if (this.personalization !== EMPTY_BUFFER) + clean(this.personalization); + this.personalization = EMPTY_BUFFER; + } + _cloneInto(to) { + const { blockLen, leafLen, leafHash, outputLen, rounds } = this; + const personalization = this.personalization === EMPTY_BUFFER ? EMPTY_BUFFER : copyBytes(this.personalization); + // Personalization is absorbed only during finish(), so clones need the same pending value. + to ||= new _KangarooTwelve(blockLen, leafLen, outputLen, rounds, { + personalization, + }); + super._cloneInto(to); + // Reused destinations can carry a stale leaf from an older multi-chunk state. + if (leafHash) + to.leafHash = leafHash._cloneInto(to.leafHash); + else if (to.leafHash) { + to.leafHash.destroy(); + to.leafHash = undefined; + } + // Snapshot the pending personalization so clone state does not alias caller-owned input. + to.personalization = personalization; + to.leafLen = this.leafLen; + to.chunkPos = this.chunkPos; + to.chunksDone = this.chunksDone; + return to; + } + clone() { + return this._cloneInto(); + } +} +/** + * 128-bit KangarooTwelve (k12): reduced 12-round keccak. + * @param msg - message bytes to hash + * @param opts - Optional output and personalization settings. Defaults to + * 32 output bytes when `dkLen` is omitted. See {@link KangarooOpts}. + * @returns Digest bytes. + * @example + * Hash a message with KangarooTwelve-128. + * ```ts + * kt128(new Uint8Array([1, 2, 3])); + * ``` + */ +export const kt128 = /* @__PURE__ */ createHasher((opts = {}) => new _KangarooTwelve(168, 32, chooseLen(opts, 32), 12, opts)); +/** + * 256-bit KangarooTwelve (k12): reduced 12-round keccak. + * @param msg - message bytes to hash + * @param opts - Optional output and personalization settings. Defaults to + * 64 output bytes when `dkLen` is omitted. See {@link KangarooOpts}. + * @returns Digest bytes. + * @example + * Hash a message with KangarooTwelve-256. + * ```ts + * kt256(new Uint8Array([1, 2, 3])); + * ``` + */ +export const kt256 = /* @__PURE__ */ createHasher((opts = {}) => new _KangarooTwelve(136, 64, chooseLen(opts, 64), 12, opts)); +const genHopMAC = (hash) => (key, message, personalization, dkLen) => { + const h = hash; + return h(key, { personalization: h(message, { personalization }), dkLen }); +}; +/** + * 128-bit KangarooTwelve-based MAC. + * + * These untested (there is no test vectors or implementation available). Use at your own risk. + * HopMAC128(Key, M, C, L) = KT128(Key, KT128(M, C, 32), L) + * HopMAC256(Key, M, C, L) = KT256(Key, KT256(M, C, 64), L) + * The inner KangarooTwelve call always uses a fixed 32-byte digest here, + * regardless of the outer `dkLen`. + * @param key - MAC key bytes + * @param message - message bytes to authenticate + * @param personalization - personalization bytes mixed into the inner hash + * @param dkLen - optional output length in bytes + * @returns Authentication tag bytes. + * @example + * Authenticate a message with HopMAC128. + * ```ts + * HopMAC128(new Uint8Array([1]), new Uint8Array([2]), new Uint8Array([3]), 32); + * ``` + */ +export const HopMAC128 = /* @__PURE__ */ genHopMAC(kt128); +/** + * 256-bit KangarooTwelve-based MAC. + * Like `HopMAC128`, there are no test vectors or known independent + * implementations available for cross-checking. + * @param key - MAC key bytes + * @param message - message bytes to authenticate + * @param personalization - personalization bytes mixed into the inner hash + * @param dkLen - optional output length in bytes. The inner KangarooTwelve + * call still uses a fixed 64-byte digest here, regardless of the outer + * `dkLen`. + * @returns Authentication tag bytes. + * @example + * Authenticate a message with HopMAC256. + * ```ts + * HopMAC256(new Uint8Array([1]), new Uint8Array([2]), new Uint8Array([3]), 64); + * ``` + */ +export const HopMAC256 = /* @__PURE__ */ genHopMAC(kt256); +/** + * More at + * {@link https://github.com/XKCP/XKCP/tree/master/lib/high/Keccak/PRG}. + * Accepted capacities must keep `rho = 1598 - capacity` byte-aligned, and + * `.clean()` later also requires `rate > 801`. + */ +export class _KeccakPRG extends Keccak { + rate; + constructor(capacity) { + anumber(capacity); + const rate = 1600 - capacity; + const rho = rate - 2; + // Rho must be full bytes + if (capacity < 0 || capacity > 1600 - 10 || rho % 8) + throw new Error('invalid capacity'); + // blockLen = rho in bytes + super(rho / 8, 0, 0, true); + this.rate = rate; + this.posOut = Math.floor((rate + 7) / 8); + } + keccak() { + // Duplex padding + this.state[this.pos] ^= 0x01; + this.state[this.blockLen] ^= 0x02; // Rho is full bytes + super.keccak(); + this.pos = 0; + this.posOut = 0; + } + update(data) { + super.update(data); + this.posOut = this.blockLen; + return this; + } + finish() { } + digestInto(_out) { + throw new Error('digest is not allowed, use .randomBytes() instead'); + } + addEntropy(seed) { + this.update(seed); + } + randomBytes(length) { + return this.xof(length); + } + clean() { + // clean() mutates live sponge state just like randomBytes(), + // so destroyed instances must reject it. + aexists(this, false); + if (this.rate < 1600 / 2 + 1) + throw new Error('rate is too low to use .forget()'); + this.keccak(); + for (let i = 0; i < this.blockLen; i++) + this.state[i] = 0; + this.pos = this.blockLen; + this.keccak(); + this.posOut = this.blockLen; + } + _cloneInto(to) { + const { rate } = this; + to ||= new _KeccakPRG(1600 - rate); + super._cloneInto(to); + to.rate = rate; + return to; + } + clone() { + return this._cloneInto(); + } +} +/** + * KeccakPRG: pseudo-random generator based on Keccak. + * See {@link https://keccak.team/files/CSF-0.1.pdf}. + * @param capacity - sponge capacity in bits. Accepted values are those that + * keep `rho = 1598 - capacity` byte-aligned; the default `254` is chosen + * because it satisfies that duplex layout while leaving a wide byte-aligned + * rate. + * @returns PRG instance backed by a Keccak sponge. + * @example + * Create a Keccak-based pseudorandom generator and read bytes from it. + * ```ts + * const prg = keccakprg(254); + * prg.randomBytes(8); + * ``` + */ +export const keccakprg = (capacity = 254) => new _KeccakPRG(capacity); +//# sourceMappingURL=sha3-addons.js.map \ No newline at end of file diff --git a/node_modules/@noble/hashes/sha3-addons.js.map b/node_modules/@noble/hashes/sha3-addons.js.map new file mode 100644 index 0000000..1065329 --- /dev/null +++ b/node_modules/@noble/hashes/sha3-addons.js.map @@ -0,0 +1 @@ +{"version":3,"file":"sha3-addons.js","sourceRoot":"","sources":["src/sha3-addons.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,MAAM,EAAkB,MAAM,WAAW,CAAC;AACnD,OAAO,EACL,MAAM,EACN,OAAO,EACP,OAAO,EAGP,KAAK,EACL,SAAS,EACT,YAAY,EAIZ,eAAe,EAIf,GAAG,GACJ,MAAM,YAAY,CAAC;AAEpB,kCAAkC;AAClC,MAAM,GAAG,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACtC,MAAM,IAAI,GAAG,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AAE1C,8FAA8F;AAC9F,4CAA4C;AAC5C,gEAAgE;AAChE,gEAAgE;AAChE,SAAS,UAAU,CAAC,CAAkB;IACpC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IACd,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IAC/B,CAAC,KAAK,GAAG,CAAC;IACV,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,GAAG;QAAE,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IACvD,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACxB,OAAO,IAAI,UAAU,CAAC,GAAG,CAAqB,CAAC;AACjD,CAAC;AAED,6FAA6F;AAC7F,SAAS,WAAW,CAAC,CAAkB;IACrC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IACd,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IAC/B,CAAC,KAAK,GAAG,CAAC;IACV,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,GAAG;QAAE,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IACvD,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACrB,OAAO,IAAI,UAAU,CAAC,GAAG,CAAqB,CAAC;AACjD,CAAC;AAED,uEAAuE;AACvE,SAAS,SAAS,CAAC,IAAe,EAAE,SAAiB;IACnD,OAAO,IAAI,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;AAC3D,CAAC;AAED,MAAM,YAAY,GAAG,CAAC,GAAsB,EAAE,KAAK,GAAG,EAAE,EAAE,EAAE;IAC1D,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,YAAY,CAAC;IAC3C,MAAM,CAAC,GAAG,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;IAC9B,OAAO,GAAG,CAAC;AACb,CAAC,CAAC;AACF,6EAA6E;AAC7E,uCAAuC;AACvC,2EAA2E;AAC3E,yCAAyC;AACzC,MAAM,UAAU,GAAG,CAAC,GAAW,EAAE,KAAa,EAAE,EAAE,CAAC,IAAI,UAAU,CAAC,CAAC,KAAK,GAAG,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC;AAanG,kBAAkB;AAClB,SAAS,UAAU,CAAC,IAAkB,EAAE,OAAyB,EAAE;IACjE,MAAM,CAAC,GAAG,IAAyB,CAAC;IACpC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,eAAe,KAAK,SAAS,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC;QAC5E,OAAO,CAAiB,CAAC;IAC3B,yEAAyE;IACzE,iCAAiC;IACjC,2EAA2E;IAC3E,2DAA2D;IAC3D,MAAM,aAAa,GAAG,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IAC7C,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACnF,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,GAAG,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,iBAAiB;IACpE,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,eAAe,EAAE,iBAAiB,CAAC,CAAC;IACnE,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,iBAAiB;IACxE,IAAI,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM;QAAE,OAAO,CAAiB,CAAC;IACzD,0FAA0F;IAC1F,yFAAyF;IACzF,CAAC,CAAC,MAAM,GAAG,IAAI,CAAC;IAChB,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC9E,IAAI,QAAQ,GAAG,aAAa,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,EAAE,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IAC9F,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC3C,OAAO,CAAiB,CAAC;AAC3B,CAAC;AAED,MAAM,SAAS,GAAG,CAChB,MAAc,EACd,QAAgB,EAChB,SAAiB,EACmB,EAAE,CACtC,YAAY,CACV,CAAC,OAAyB,EAAE,EAAE,EAAE,CAC9B,UAAU,CACR,IAAI,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,IAAI,CAA4B,EACzF,IAAI,CACK,CACd,CAAC;AAkBJ;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,SAAS,GAAuC,eAAe,CAAC,SAAS,CACpF,IAAI,EACJ,GAAG,EACH,EAAE,CACH,CAAC;AACF;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,SAAS,GAAuC,eAAe,CAAC,SAAS,CACpF,IAAI,EACJ,GAAG,EACH,EAAE,CACH,CAAC;AAEF;;;;GAIG;AACH,MAAM,OAAO,KAAM,SAAQ,MAAM;IAC/B,YACE,QAAgB,EAChB,SAAiB,EACjB,SAAkB,EAClB,GAAqB,EACrB,OAAyB,EAAE;QAE3B,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;QAC5C,6FAA6F;QAC7F,2FAA2F;QAC3F,UAAU,CAAC,IAA+B,EAAE;YAC1C,MAAM,EAAE,MAAM;YACd,eAAe,EAAE,IAAI,CAAC,eAAe;SACtC,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;QAC9B,qEAAqE;QACrE,+BAA+B;QAC/B,MAAM,aAAa,GAAG,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAChD,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;QACpD,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACtD,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;QACnE,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;IACnD,CAAC;IACS,MAAM;QACd,yFAAyF;QACzF,oBAAoB;QACpB,IAAI,CAAC,IAAI,CAAC,QAAQ;YAAE,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;QAChG,KAAK,CAAC,MAAM,EAAE,CAAC;IACjB,CAAC;IACD,UAAU,CAAC,EAAU;QACnB,gEAAgE;QAChE,4CAA4C;QAC5C,qDAAqD;QACrD,IAAI,CAAC,EAAE,EAAE,CAAC;YACR,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,EAAE,CAAU,CAAC;YAC7D,EAAE,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YAC9B,EAAE,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;YAC5B,EAAE,CAAC,OAAO,GAAG,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;QAC7B,CAAC;QACD,OAAO,KAAK,CAAC,UAAU,CAAC,EAAE,CAAU,CAAC;IACvC,CAAC;IACD,KAAK;QACH,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC;IAC3B,CAAC;CACF;AAED,SAAS,OAAO,CAAC,QAAgB,EAAE,SAAiB,EAAE,GAAG,GAAG,KAAK;IAC/D,uEAAuE;IACvE,4DAA4D;IAC5D,MAAM,IAAI,GAAG,CACX,GAAqB,EACrB,OAAyB,EACzB,IAAuB,EACL,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC;IACvE,IAAI,CAAC,MAAM,GAAG,CAAC,GAAqB,EAAE,OAAyB,EAAE,EAAE,EAAE,CACnE,IAAI,KAAK,CAAC,QAAQ,EAAE,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IAClE,OAAO,IAAmB,CAAC;AAC7B,CAAC;AAoBD;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,OAAO,GAAgB,eAAe,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;AACrE;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,OAAO,GAAgB,eAAe,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;AACrE;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,UAAU,GAAgB,eAAe,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC;AAC9E;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,UAAU,GAAgB,eAAe,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC;AAE9E;;;;GAIG;AACH,MAAM,OAAO,UAAW,SAAQ,MAAM;IACpC,YACE,QAAgB,EAChB,SAAiB,EACjB,SAAkB,EAClB,OAAyB,EAAE;QAE3B,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;QAC5C,UAAU,CAAC,IAA+B,EAAE;YAC1C,MAAM,EAAE,WAAW;YACnB,eAAe,EAAE,IAAI,CAAC,eAAe;SACtC,CAAC,CAAC;QACH,uCAAuC;QACvC,IAAI,CAAC,MAAM,GAAG,CAAC,IAAsB,EAAE,EAAE;YACvC,MAAM,CAAC,IAAI,CAAC,CAAC;YACb,2CAA2C;YAC3C,wDAAwD;YACxD,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YACpD,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACnB,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;IACJ,CAAC;IACS,MAAM;QACd,6DAA6D;QAC7D,wCAAwC;QACxC,IAAI,CAAC,IAAI,CAAC,QAAQ;YAChB,oBAAoB;YACpB,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;QAC/E,KAAK,CAAC,MAAM,EAAE,CAAC;IACjB,CAAC;IACD,UAAU,CAAC,EAAe;QACxB,EAAE,KAAK,IAAI,UAAU,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QACrE,OAAO,KAAK,CAAC,UAAU,CAAC,EAAE,CAAe,CAAC;IAC5C,CAAC;IACD,KAAK;QACH,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC;IAC3B,CAAC;CACF;AAED,SAAS,QAAQ,CAAC,QAAgB,EAAE,SAAiB,EAAE,GAAG,GAAG,KAAK;IAChE,0EAA0E;IAC1E,mDAAmD;IACnD,MAAM,KAAK,GAAG,CAAC,QAA4B,EAAE,IAAuB,EAAoB,EAAE;QACxF,MAAM,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAC5E,KAAK,MAAM,GAAG,IAAI,QAAQ;YAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC1C,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC;IACpB,CAAC,CAAC;IACF,KAAK,CAAC,MAAM,GAAG,CAAC,OAAyB,EAAE,EAAE,EAAE,CAC7C,IAAI,UAAU,CAAC,QAAQ,EAAE,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IAClE,OAAO,KAAyB,CAAC;AACnC,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,YAAY,GAAqB,eAAe,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;AAChF;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,YAAY,GAAqB,eAAe,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;AAChF;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,eAAe,GAAqB,eAAe,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC;AACzF;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,eAAe,GAAqB,eAAe,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC;AAMzF,2CAA2C;AAC3C,MAAM,OAAO,aAAc,SAAQ,MAAM;IAC/B,QAAQ,CAAgB;IACtB,QAAQ,CAAqB;IAC/B,QAAQ,GAAG,CAAC,CAAC,CAAC,qCAAqC;IACnD,UAAU,GAAG,CAAC,CAAC,CAAC,kCAAkC;IAClD,QAAQ,CAAS;IACzB,YACE,QAAgB,EAChB,SAAiB,EACjB,QAA4B,EAC5B,SAAkB,EAClB,OAA2B,EAAE;QAE7B,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;QAC5C,UAAU,CAAC,IAA+B,EAAE;YAC1C,MAAM,EAAE,cAAc;YACtB,eAAe,EAAE,IAAI,CAAC,eAAe;SACtC,CAAC,CAAC;QACH,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,EAAE,QAAQ,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC;QAC/B,OAAO,CAAC,CAAC,CAAC,CAAC;QACX,iFAAiF;QACjF,IAAI,CAAC,GAAG,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,GAAG,CAAC,CAAC,CAAC;QAChE,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;QAClB,0EAA0E;QAC1E,yEAAyE;QACzE,4BAA4B;QAC5B,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5B,uCAAuC;QACvC,IAAI,CAAC,MAAM,GAAG,CAAC,IAAsB,EAAE,EAAE;YACvC,MAAM,CAAC,IAAI,CAAC,CAAC;YACb,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;YACpC,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,GAAG,GAAI,CAAC;gBACjD,IAAI,IAAI,CAAC,QAAQ,IAAI,QAAQ,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;oBAChD,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;wBAClB,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;wBACrC,IAAI,CAAC,UAAU,EAAE,CAAC;oBACpB,CAAC;oBACD,IAAI,CAAC,QAAQ,GAAG,QAAQ,EAAE,CAAC;oBAC3B,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;gBACpB,CAAC;gBACD,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,GAAG,GAAG,GAAG,CAAC,CAAC;gBAC3D,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC;gBACrD,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC;gBACtB,GAAG,IAAI,IAAI,CAAC;YACd,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;IACJ,CAAC;IACS,MAAM;QACd,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO;QAC1B,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;YACrC,IAAI,CAAC,UAAU,EAAE,CAAC;QACpB,CAAC;QACD,sCAAsC;QACtC,6DAA6D;QAC7D,wCAAwC;QACxC,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;QAC3C,oBAAoB;QACpB,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;QAC7E,KAAK,CAAC,MAAM,EAAE,CAAC;IACjB,CAAC;IACD,UAAU,CAAC,EAAkB;QAC3B,EAAE,KAAK,IAAI,aAAa,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QACvF,EAAE,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC5B,qDAAqD;QACrD,+CAA+C;QAC/C,IAAI,IAAI,CAAC,QAAQ;YAAE,EAAE,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,QAAkB,CAAC,CAAC;aAC5E,IAAI,EAAE,CAAC,QAAQ,EAAE,CAAC;YACrB,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;YACtB,EAAE,CAAC,QAAQ,GAAG,SAAS,CAAC;QAC1B,CAAC;QACD,EAAE,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC5B,EAAE,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC5B,EAAE,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;QAChC,OAAO,KAAK,CAAC,UAAU,CAAC,EAAE,CAAkB,CAAC;IAC/C,CAAC;IACD,OAAO;QACL,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzB,IAAI,IAAI,CAAC,QAAQ;YAAE,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;IAC7C,CAAC;IACD,KAAK;QACH,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC;IAC3B,CAAC;CACF;AAED,SAAS,MAAM,CACb,QAAgB,EAChB,SAAiB,EACjB,IAAkC,EAClC,GAAG,GAAG,KAAK;IAEX,MAAM,QAAQ,GAAG,CAAC,OAAyB,EAAE,IAAyB,EAAoB,EAAE,CAC1F,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC;IACjD,QAAQ,CAAC,MAAM,GAAG,CAAC,OAA2B,EAAE,EAAE,EAAE,CAClD,IAAI,aAAa,CACf,QAAQ,EACR,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC;IAC1B,oEAAoE;IACpE,sEAAsE;IACtE,yBAAyB;IACzB,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,EAC3C,GAAG,EACH,IAAI,CACL,CAAC;IACJ,QAAQ,CAAC,SAAS,GAAG,SAAS,CAAC;IAC/B,QAAQ,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC7B,QAAQ,CAAC,MAAM,GAAG,GAAG,CAAC;IACtB,OAAO,QAAgD,CAAC;AAC1D,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,eAAe,GAAsC,eAAe,CAAC,MAAM,CACtF,GAAG,EACH,EAAE,EACF,SAAS,CACV,CAAC;AACF;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,eAAe,GAAsC,eAAe,CAAC,MAAM,CACtF,GAAG,EACH,EAAE,EACF,SAAS,CACV,CAAC;AACF;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAyC,eAAe,CAAC,MAAM,CAC5F,GAAG,EACH,EAAE,EACF,SAAS,EACT,IAAI,CACL,CAAC;AACF;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAyC,eAAe,CAAC,MAAM,CAC5F,GAAG,EACH,EAAE,EACF,SAAS,EACT,IAAI,CACL,CAAC;AAYF,MAAM,QAAQ,GAAG,CAAC,QAAgB,EAAE,SAAiB,EAAE,EAAE,CACvD,YAAY,CAAyB,CAAC,OAA6B,EAAE,EAAE,EAAE;IACvE,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAC/C,wEAAwE;IACxE,mCAAmC;IACnC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,IAAI;QAClD,MAAM,IAAI,KAAK,CAAC,wDAAwD,GAAG,CAAC,CAAC,CAAC;IAChF,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;IAChE,mEAAmE;IACnE,IAAI,KAAK,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;IACvD,OAAO,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;AAClD,CAAC,CAAC,CAAC;AAEL;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,aAAa,GAA2C,eAAe,CAAC,QAAQ,CAC3F,GAAG,EACH,EAAE,CACH,CAAC;AACF;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,aAAa,GAA2C,eAAe,CAAC,QAAQ,CAC3F,GAAG,EACH,EAAE,CACH,CAAC;AAEF,mEAAmE;AACnE,8DAA8D;AAC9D,SAAS,cAAc,CAAC,CAAkB;IACxC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IACd,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,GAAG;QAAE,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IACvD,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACrB,OAAO,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC9B,CAAC;AAgBD,MAAM,YAAY,GAAG,eAAe,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC;AAErD,+BAA+B;AAC/B,MAAM,OAAO,eAAgB,SAAQ,MAAM;IAChC,QAAQ,GAAG,IAAI,CAAC;IACjB,QAAQ,CAAU;IAChB,OAAO,CAAS;IAClB,eAAe,CAAa;IAC5B,QAAQ,GAAG,CAAC,CAAC,CAAC,qCAAqC;IACnD,UAAU,GAAG,CAAC,CAAC,CAAC,kCAAkC;IAC1D,YACE,QAAgB,EAChB,OAAe,EACf,SAAiB,EACjB,MAAc,EACd,IAAwB;QAExB,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QAC/C,6DAA6D;QAC7D,IAAI,SAAS,GAAG,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;QAC3D,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,eAAe;YAClB,IAAI,CAAC,eAAe,KAAK,SAAS;gBAChC,CAAC,CAAC,YAAY;gBACd,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,EAAE,SAAS,EAAE,iBAAiB,CAAC,CAAC,CAAC;IAC9E,CAAC;IACD,MAAM,CAAC,IAAsB;QAC3B,MAAM,CAAC,IAAI,CAAC,CAAC;QACb,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QACrD,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,GAAG,GAAI,CAAC;YACjD,IAAI,IAAI,CAAC,QAAQ,IAAI,QAAQ,EAAE,CAAC;gBAC9B,IAAI,IAAI,CAAC,QAAQ;oBAAE,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;qBACnD,CAAC;oBACJ,oEAAoE;oBACpE,kDAAkD;oBAClD,6BAA6B;oBAC7B,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,iEAAiE;oBACrF,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC1D,CAAC;gBACD,oDAAoD;gBACpD,wDAAwD;gBACxD,IAAI,CAAC,QAAQ,GAAG,IAAI,MAAM,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;gBACnE,IAAI,CAAC,UAAU,EAAE,CAAC;gBAClB,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;YACpB,CAAC;YACD,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,GAAG,GAAG,GAAG,CAAC,CAAC;YAC3D,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,CAAC,CAAC;YAC7C,IAAI,IAAI,CAAC,QAAQ;gBAAE,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;;gBAC1C,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACzB,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC;YACtB,GAAG,IAAI,IAAI,CAAC;QACd,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACS,MAAM;QACd,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO;QAC1B,MAAM,EAAE,eAAe,EAAE,GAAG,IAAI,CAAC;QACjC,sFAAsF;QACtF,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC;QAC5E,YAAY;QACZ,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,0BAA0B;YAC1B,kDAAkD;YAClD,oCAAoC;YACpC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;YACrC,KAAK,CAAC,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;YAC9C,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;QAC9C,CAAC;QACD,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IACD,OAAO;QACL,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzB,IAAI,IAAI,CAAC,QAAQ;YAAE,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;QAC3C,oEAAoE;QACpE,iCAAiC;QACjC,IAAI,IAAI,CAAC,eAAe,KAAK,YAAY;YAAE,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QACvE,IAAI,CAAC,eAAe,GAAG,YAAY,CAAC;IACtC,CAAC;IACD,UAAU,CAAC,EAAoB;QAC7B,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QAChE,MAAM,eAAe,GACnB,IAAI,CAAC,eAAe,KAAK,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QACzF,2FAA2F;QAC3F,EAAE,KAAK,IAAI,eAAe,CAAC,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE;YAC/D,eAAe;SAChB,CAAC,CAAC;QACH,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QACrB,8EAA8E;QAC9E,IAAI,QAAQ;YAAE,EAAE,CAAC,QAAQ,GAAG,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC;aACxD,IAAI,EAAE,CAAC,QAAQ,EAAE,CAAC;YACrB,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;YACtB,EAAE,CAAC,QAAQ,GAAG,SAAS,CAAC;QAC1B,CAAC;QACD,yFAAyF;QACzF,EAAE,CAAC,eAAe,GAAG,eAAe,CAAC;QACrC,EAAE,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;QAC1B,EAAE,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC5B,EAAE,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;QAChC,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,KAAK;QACH,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC;IAC3B,CAAC;CACF;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,KAAK,GAA+C,eAAe,CAAC,YAAY,CAC3F,CAAC,OAA2B,EAAE,EAAE,EAAE,CAAC,IAAI,eAAe,CAAC,GAAG,EAAE,EAAE,EAAE,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,CAC/F,CAAC;AACF;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,KAAK,GAA+C,eAAe,CAAC,YAAY,CAC3F,CAAC,OAA2B,EAAE,EAAE,EAAE,CAAC,IAAI,eAAe,CAAC,GAAG,EAAE,EAAE,EAAE,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,CAC/F,CAAC;AAYF,MAAM,SAAS,GACb,CAAC,IAAgD,EAAgB,EAAE,CACnE,CACE,GAAqB,EACrB,OAAyB,EACzB,eAAiC,EACjC,KAAc,EACd,EAAE;IACF,MAAM,CAAC,GAAG,IAAuD,CAAC;IAClE,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,eAAe,EAAE,CAAC,CAAC,OAAO,EAAE,EAAE,eAAe,EAAE,CAAC,EAAE,KAAK,EAAE,CAAqB,CAAC;AACjG,CAAC,CAAC;AAEJ;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,MAAM,SAAS,GAAiB,eAAe,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;AACxE;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,MAAM,SAAS,GAAiB,eAAe,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;AAExE;;;;;GAKG;AACH,MAAM,OAAO,UAAW,SAAQ,MAAM;IAC1B,IAAI,CAAS;IACvB,YAAY,QAAgB;QAC1B,OAAO,CAAC,QAAQ,CAAC,CAAC;QAClB,MAAM,IAAI,GAAG,IAAI,GAAG,QAAQ,CAAC;QAC7B,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,CAAC;QACrB,yBAAyB;QACzB,IAAI,QAAQ,GAAG,CAAC,IAAI,QAAQ,GAAG,IAAI,GAAG,EAAE,IAAI,GAAG,GAAG,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;QACzF,0BAA0B;QAC1B,KAAK,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;QAC3B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3C,CAAC;IACS,MAAM;QACd,iBAAiB;QACjB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC;QAC7B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,CAAC,oBAAoB;QACvD,KAAK,CAAC,MAAM,EAAE,CAAC;QACf,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC;QACb,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;IAClB,CAAC;IACD,MAAM,CAAC,IAAsB;QAC3B,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACnB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC5B,OAAO,IAAI,CAAC;IACd,CAAC;IACS,MAAM,KAAU,CAAC;IAC3B,UAAU,CAAC,IAAsB;QAC/B,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;IACvE,CAAC;IACD,UAAU,CAAC,IAAsB;QAC/B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACpB,CAAC;IACD,WAAW,CAAC,MAAc;QACxB,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC1B,CAAC;IACD,KAAK;QACH,6DAA6D;QAC7D,yCAAyC;QACzC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACrB,IAAI,IAAI,CAAC,IAAI,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;QAClF,IAAI,CAAC,MAAM,EAAE,CAAC;QACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,EAAE;YAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAC1D,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC;QACzB,IAAI,CAAC,MAAM,EAAE,CAAC;QACd,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC;IAC9B,CAAC;IACD,UAAU,CAAC,EAAe;QACxB,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC;QACtB,EAAE,KAAK,IAAI,UAAU,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;QACnC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QACrB,EAAE,CAAC,IAAI,GAAG,IAAI,CAAC;QACf,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,KAAK;QACH,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC;IAC3B,CAAC;CACF;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,QAAQ,GAAG,GAAG,EAAoB,EAAE,CAC5D,IAAI,UAAU,CAAC,QAAQ,CAAqB,CAAC"} \ No newline at end of file diff --git a/node_modules/@noble/hashes/sha3.d.ts b/node_modules/@noble/hashes/sha3.d.ts new file mode 100644 index 0000000..19e8075 --- /dev/null +++ b/node_modules/@noble/hashes/sha3.d.ts @@ -0,0 +1,199 @@ +import { type CHash, type CHashXOF, type Hash, type HashXOF, type TArg, type TRet } from './utils.ts'; +/** + * `keccakf1600` internal permutation, additionally allows adjusting the round count. + * @param s - 5x5 Keccak state encoded as 25 lanes split into 50 uint32 words + * in this file's local little-endian lane-word order + * @param rounds - number of rounds to execute + * @throws If `rounds` is outside the supported `1..24` range. {@link Error} + * @example + * Permute a Keccak state with the default 24 rounds. + * ```ts + * keccakP(new Uint32Array(50)); + * ``` + */ +export declare function keccakP(s: TArg, rounds?: number): void; +/** + * Keccak sponge function. + * @param blockLen - absorb/squeeze rate in bytes + * @param suffix - domain separation suffix byte + * @param outputLen - default digest length in bytes. This base sponge only + * requires a non-negative integer; wrappers that need positive output + * lengths must enforce that themselves. + * @param enableXOF - whether XOF output is allowed + * @param rounds - number of Keccak-f rounds + * @example + * Build a sponge state, absorb bytes, then finalize a digest. + * ```ts + * const hash = new Keccak(136, 0x06, 32); + * hash.update(new Uint8Array([1, 2, 3])); + * hash.digest(); + * ``` + */ +export declare class Keccak implements Hash, HashXOF { + protected state: Uint8Array; + protected pos: number; + protected posOut: number; + protected finished: boolean; + protected state32: Uint32Array; + protected destroyed: boolean; + blockLen: number; + suffix: number; + outputLen: number; + canXOF: boolean; + protected enableXOF: boolean; + protected rounds: number; + constructor(blockLen: number, suffix: number, outputLen: number, enableXOF?: boolean, rounds?: number); + clone(): Keccak; + protected keccak(): void; + update(data: TArg): this; + protected finish(): void; + protected writeInto(out: TArg): TRet; + xofInto(out: TArg): TRet; + xof(bytes: number): TRet; + digestInto(out: TArg): void; + digest(): TRet; + destroy(): void; + _cloneInto(to?: Keccak): Keccak; +} +/** + * SHA3-224 hash function. + * @param msg - message bytes to hash + * @returns Digest bytes. + * @example + * Hash a message with SHA3-224. + * ```ts + * sha3_224(new Uint8Array([97, 98, 99])); + * ``` + */ +export declare const sha3_224: TRet; +/** + * SHA3-256 hash function. Different from keccak-256. + * @param msg - message bytes to hash + * @returns Digest bytes. + * @example + * Hash a message with SHA3-256. + * ```ts + * sha3_256(new Uint8Array([97, 98, 99])); + * ``` + */ +export declare const sha3_256: TRet; +/** + * SHA3-384 hash function. + * @param msg - message bytes to hash + * @returns Digest bytes. + * @example + * Hash a message with SHA3-384. + * ```ts + * sha3_384(new Uint8Array([97, 98, 99])); + * ``` + */ +export declare const sha3_384: TRet; +/** + * SHA3-512 hash function. + * @param msg - message bytes to hash + * @returns Digest bytes. + * @example + * Hash a message with SHA3-512. + * ```ts + * sha3_512(new Uint8Array([97, 98, 99])); + * ``` + */ +export declare const sha3_512: TRet; +/** + * Keccak-224 hash function. + * @param msg - message bytes to hash + * @returns Digest bytes. + * @example + * Hash a message with Keccak-224. + * ```ts + * keccak_224(new Uint8Array([97, 98, 99])); + * ``` + */ +export declare const keccak_224: TRet; +/** + * Keccak-256 hash function. Different from SHA3-256. + * @param msg - message bytes to hash + * @returns Digest bytes. + * @example + * Hash a message with Keccak-256. + * ```ts + * keccak_256(new Uint8Array([97, 98, 99])); + * ``` + */ +export declare const keccak_256: TRet; +/** + * Keccak-384 hash function. + * @param msg - message bytes to hash + * @returns Digest bytes. + * @example + * Hash a message with Keccak-384. + * ```ts + * keccak_384(new Uint8Array([97, 98, 99])); + * ``` + */ +export declare const keccak_384: TRet; +/** + * Keccak-512 hash function. + * @param msg - message bytes to hash + * @returns Digest bytes. + * @example + * Hash a message with Keccak-512. + * ```ts + * keccak_512(new Uint8Array([97, 98, 99])); + * ``` + */ +export declare const keccak_512: TRet; +/** Options for SHAKE XOF. */ +export type ShakeOpts = { + /** Desired number of output bytes. */ + dkLen?: number; +}; +/** + * SHAKE128 XOF with 128-bit security and a 16-byte default output. + * @param msg - message bytes to hash + * @param opts - Optional output-length override. See {@link ShakeOpts}. + * @returns Digest bytes. + * @example + * Hash a message with SHAKE128. + * ```ts + * shake128(new Uint8Array([97, 98, 99]), { dkLen: 32 }); + * ``` + */ +export declare const shake128: TRet>; +/** + * SHAKE256 XOF with 256-bit security and a 32-byte default output. + * @param msg - message bytes to hash + * @param opts - Optional output-length override. See {@link ShakeOpts}. + * @returns Digest bytes. + * @example + * Hash a message with SHAKE256. + * ```ts + * shake256(new Uint8Array([97, 98, 99]), { dkLen: 64 }); + * ``` + */ +export declare const shake256: TRet>; +/** + * SHAKE128 XOF with 256-bit output (NIST version). + * @param msg - message bytes to hash + * @param opts - Optional output-length override. See {@link ShakeOpts}. + * @returns Digest bytes. + * @example + * Hash a message with SHAKE128 using a 32-byte default output. + * ```ts + * shake128_32(new Uint8Array([97, 98, 99]), { dkLen: 32 }); + * ``` + */ +export declare const shake128_32: TRet>; +/** + * SHAKE256 XOF with 512-bit output (NIST version). + * @param msg - message bytes to hash + * @param opts - Optional output-length override. See {@link ShakeOpts}. + * @returns Digest bytes. + * @example + * Hash a message with SHAKE256 using a 64-byte default output. + * ```ts + * shake256_64(new Uint8Array([97, 98, 99]), { dkLen: 64 }); + * ``` + */ +export declare const shake256_64: TRet>; +//# sourceMappingURL=sha3.d.ts.map \ No newline at end of file diff --git a/node_modules/@noble/hashes/sha3.d.ts.map b/node_modules/@noble/hashes/sha3.d.ts.map new file mode 100644 index 0000000..12d5be2 --- /dev/null +++ b/node_modules/@noble/hashes/sha3.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"sha3.d.ts","sourceRoot":"","sources":["src/sha3.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@noble/hashes/sha3.js b/node_modules/@noble/hashes/sha3.js new file mode 100644 index 0000000..02e6432 --- /dev/null +++ b/node_modules/@noble/hashes/sha3.js @@ -0,0 +1,431 @@ +/** + * SHA3 (keccak) hash function, based on a new "Sponge function" design. + * Different from older hashes, the internal state is bigger than output size. + * + * Check out + * {@link https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf | FIPS-202}, + * {@link https://keccak.team/keccak.html | Website}, and + * {@link https://crypto.stackexchange.com/q/15727 | the differences between + * SHA-3 and Keccak}. + * + * Check out `sha3-addons` module for cSHAKE, k12, and others. + * @module + */ +import { rotlBH, rotlBL, rotlSH, rotlSL, split } from "./_u64.js"; +// prettier-ignore +import { abytes, aexists, anumber, aoutput, clean, createHasher, oidNist, swap32IfBE, u32 } from "./utils.js"; +// No __PURE__ annotations in sha3 header: +// EVERYTHING is in fact used on every export. +// Various per round constants calculations +const _0n = BigInt(0); +const _1n = BigInt(1); +const _2n = BigInt(2); +const _7n = BigInt(7); +const _256n = BigInt(256); +// FIPS 202 Algorithm 5 rc(): when the outgoing bit is 1, the 8-bit LFSR xors +// taps 0, 4, 5, and 6, which compresses to the feedback mask `0x71`. +const _0x71n = BigInt(0x71); +const SHA3_PI = []; +const SHA3_ROTL = []; +const _SHA3_IOTA = []; // no pure annotation: var is always used +for (let round = 0, R = _1n, x = 1, y = 0; round < 24; round++) { + // Pi + [x, y] = [y, (2 * x + 3 * y) % 5]; + SHA3_PI.push(2 * (5 * y + x)); + // Rotational + SHA3_ROTL.push((((round + 1) * (round + 2)) / 2) % 64); + // Iota + let t = _0n; + for (let j = 0; j < 7; j++) { + R = ((R << _1n) ^ ((R >> _7n) * _0x71n)) % _256n; + if (R & _2n) + t ^= _1n << ((_1n << BigInt(j)) - _1n); + } + _SHA3_IOTA.push(t); +} +const IOTAS = split(_SHA3_IOTA, true); +// `split(..., true)` keeps the local little-endian lane-word layout used by +// `state32`, so these `H` / `L` tables follow the file's first-word / +// second-word lane slots rather than `_u64.ts`'s usual high/low naming. +const SHA3_IOTA_H = IOTAS[0]; +const SHA3_IOTA_L = IOTAS[1]; +// Left rotation (without 0, 32, 64) +const rotlH = (h, l, s) => (s > 32 ? rotlBH(h, l, s) : rotlSH(h, l, s)); +const rotlL = (h, l, s) => (s > 32 ? rotlBL(h, l, s) : rotlSL(h, l, s)); +/** + * `keccakf1600` internal permutation, additionally allows adjusting the round count. + * @param s - 5x5 Keccak state encoded as 25 lanes split into 50 uint32 words + * in this file's local little-endian lane-word order + * @param rounds - number of rounds to execute + * @throws If `rounds` is outside the supported `1..24` range. {@link Error} + * @example + * Permute a Keccak state with the default 24 rounds. + * ```ts + * keccakP(new Uint32Array(50)); + * ``` + */ +export function keccakP(s, rounds = 24) { + anumber(rounds, 'rounds'); + // This implementation precomputes only the standard Keccak-f[1600] 24-round Iota table. + if (rounds < 1 || rounds > 24) + throw new Error('"rounds" expected integer 1..24'); + const B = new Uint32Array(5 * 2); + // NOTE: all indices are x2 since we store state as u32 instead of u64 (bigints to slow in js) + for (let round = 24 - rounds; round < 24; round++) { + // Theta θ + for (let x = 0; x < 10; x++) + B[x] = s[x] ^ s[x + 10] ^ s[x + 20] ^ s[x + 30] ^ s[x + 40]; + for (let x = 0; x < 10; x += 2) { + const idx1 = (x + 8) % 10; + const idx0 = (x + 2) % 10; + const B0 = B[idx0]; + const B1 = B[idx0 + 1]; + const Th = rotlH(B0, B1, 1) ^ B[idx1]; + const Tl = rotlL(B0, B1, 1) ^ B[idx1 + 1]; + for (let y = 0; y < 50; y += 10) { + s[x + y] ^= Th; + s[x + y + 1] ^= Tl; + } + } + // Rho (ρ) and Pi (π) + let curH = s[2]; + let curL = s[3]; + for (let t = 0; t < 24; t++) { + const shift = SHA3_ROTL[t]; + const Th = rotlH(curH, curL, shift); + const Tl = rotlL(curH, curL, shift); + const PI = SHA3_PI[t]; + curH = s[PI]; + curL = s[PI + 1]; + s[PI] = Th; + s[PI + 1] = Tl; + } + // Chi (χ) + // Same as: + // for (let x = 0; x < 10; x++) B[x] = s[y + x]; + // for (let x = 0; x < 10; x++) s[y + x] ^= ~B[(x + 2) % 10] & B[(x + 4) % 10]; + for (let y = 0; y < 50; y += 10) { + const b0 = s[y], b1 = s[y + 1], b2 = s[y + 2], b3 = s[y + 3]; + s[y] ^= ~s[y + 2] & s[y + 4]; + s[y + 1] ^= ~s[y + 3] & s[y + 5]; + s[y + 2] ^= ~s[y + 4] & s[y + 6]; + s[y + 3] ^= ~s[y + 5] & s[y + 7]; + s[y + 4] ^= ~s[y + 6] & s[y + 8]; + s[y + 5] ^= ~s[y + 7] & s[y + 9]; + s[y + 6] ^= ~s[y + 8] & b0; + s[y + 7] ^= ~s[y + 9] & b1; + s[y + 8] ^= ~b0 & b2; + s[y + 9] ^= ~b1 & b3; + } + // Iota (ι) + s[0] ^= SHA3_IOTA_H[round]; + s[1] ^= SHA3_IOTA_L[round]; + } + clean(B); +} +/** + * Keccak sponge function. + * @param blockLen - absorb/squeeze rate in bytes + * @param suffix - domain separation suffix byte + * @param outputLen - default digest length in bytes. This base sponge only + * requires a non-negative integer; wrappers that need positive output + * lengths must enforce that themselves. + * @param enableXOF - whether XOF output is allowed + * @param rounds - number of Keccak-f rounds + * @example + * Build a sponge state, absorb bytes, then finalize a digest. + * ```ts + * const hash = new Keccak(136, 0x06, 32); + * hash.update(new Uint8Array([1, 2, 3])); + * hash.digest(); + * ``` + */ +export class Keccak { + state; + pos = 0; + posOut = 0; + finished = false; + state32; + destroyed = false; + blockLen; + suffix; + outputLen; + canXOF; + enableXOF = false; + rounds; + // NOTE: we accept arguments in bytes instead of bits here. + constructor(blockLen, suffix, outputLen, enableXOF = false, rounds = 24) { + this.blockLen = blockLen; + this.suffix = suffix; + this.outputLen = outputLen; + this.enableXOF = enableXOF; + this.canXOF = enableXOF; + this.rounds = rounds; + // Can be passed from user as dkLen + anumber(outputLen, 'outputLen'); + // 1600 = 5x5 matrix of 64bit. 1600 bits === 200 bytes + // 0 < blockLen < 200 + if (!(0 < blockLen && blockLen < 200)) + throw new Error('only keccak-f1600 function is supported'); + this.state = new Uint8Array(200); + this.state32 = u32(this.state); + } + clone() { + return this._cloneInto(); + } + keccak() { + swap32IfBE(this.state32); + keccakP(this.state32, this.rounds); + swap32IfBE(this.state32); + this.posOut = 0; + this.pos = 0; + } + update(data) { + aexists(this); + abytes(data); + const { blockLen, state } = this; + const len = data.length; + for (let pos = 0; pos < len;) { + const take = Math.min(blockLen - this.pos, len - pos); + for (let i = 0; i < take; i++) + state[this.pos++] ^= data[pos++]; + if (this.pos === blockLen) + this.keccak(); + } + return this; + } + finish() { + if (this.finished) + return; + this.finished = true; + const { state, suffix, pos, blockLen } = this; + // FIPS 202 appends the SHA3/SHAKE domain-separation suffix before pad10*1. + // These byte values already include the first padding bit, while the + // final `0x80` below supplies the closing `1` bit in the last rate byte. + state[pos] ^= suffix; + // If that combined suffix lands in the last rate byte and already sets + // bit 7, absorb it first so the final pad10*1 bit can be xored into a + // fresh block. + if ((suffix & 0x80) !== 0 && pos === blockLen - 1) + this.keccak(); + state[blockLen - 1] ^= 0x80; + this.keccak(); + } + writeInto(out) { + aexists(this, false); + abytes(out); + this.finish(); + const bufferOut = this.state; + const { blockLen } = this; + for (let pos = 0, len = out.length; pos < len;) { + if (this.posOut >= blockLen) + this.keccak(); + const take = Math.min(blockLen - this.posOut, len - pos); + out.set(bufferOut.subarray(this.posOut, this.posOut + take), pos); + this.posOut += take; + pos += take; + } + return out; + } + xofInto(out) { + // Plain SHA3/Keccak usage with XOF is probably a mistake, but this base + // class is also reused by SHAKE/cSHAKE/KMAC/TupleHash/ParallelHash/ + // TurboSHAKE/KangarooTwelve wrappers that intentionally enable XOF. + if (!this.enableXOF) + throw new Error('XOF is not possible for this instance'); + return this.writeInto(out); + } + xof(bytes) { + anumber(bytes); + return this.xofInto(new Uint8Array(bytes)); + } + digestInto(out) { + aoutput(out, this); + if (this.finished) + throw new Error('digest() was already called'); + // `aoutput(...)` allows oversized buffers; digestInto() must fill only the advertised digest. + this.writeInto(out.subarray(0, this.outputLen)); + this.destroy(); + } + digest() { + const out = new Uint8Array(this.outputLen); + this.digestInto(out); + return out; + } + destroy() { + this.destroyed = true; + clean(this.state); + } + _cloneInto(to) { + const { blockLen, suffix, outputLen, rounds, enableXOF } = this; + to ||= new Keccak(blockLen, suffix, outputLen, enableXOF, rounds); + // Reused destinations can come from a different rate/capacity variant, so clone must rewrite + // the sponge geometry as well as the state words. + to.blockLen = blockLen; + to.state32.set(this.state32); + to.pos = this.pos; + to.posOut = this.posOut; + to.finished = this.finished; + to.rounds = rounds; + // Suffix can change in cSHAKE + to.suffix = suffix; + to.outputLen = outputLen; + to.enableXOF = enableXOF; + // Clones must preserve the public capability bit too; `_KMAC` reuses this path and deep clone + // tests compare instance fields directly, so leaving `canXOF` behind makes the clone lie. + to.canXOF = this.canXOF; + to.destroyed = this.destroyed; + return to; + } +} +const genKeccak = (suffix, blockLen, outputLen, info = {}) => createHasher(() => new Keccak(blockLen, suffix, outputLen), info); +/** + * SHA3-224 hash function. + * @param msg - message bytes to hash + * @returns Digest bytes. + * @example + * Hash a message with SHA3-224. + * ```ts + * sha3_224(new Uint8Array([97, 98, 99])); + * ``` + */ +export const sha3_224 = /* @__PURE__ */ genKeccak(0x06, 144, 28, +/* @__PURE__ */ oidNist(0x07)); +/** + * SHA3-256 hash function. Different from keccak-256. + * @param msg - message bytes to hash + * @returns Digest bytes. + * @example + * Hash a message with SHA3-256. + * ```ts + * sha3_256(new Uint8Array([97, 98, 99])); + * ``` + */ +export const sha3_256 = /* @__PURE__ */ genKeccak(0x06, 136, 32, +/* @__PURE__ */ oidNist(0x08)); +/** + * SHA3-384 hash function. + * @param msg - message bytes to hash + * @returns Digest bytes. + * @example + * Hash a message with SHA3-384. + * ```ts + * sha3_384(new Uint8Array([97, 98, 99])); + * ``` + */ +export const sha3_384 = /* @__PURE__ */ genKeccak(0x06, 104, 48, +/* @__PURE__ */ oidNist(0x09)); +/** + * SHA3-512 hash function. + * @param msg - message bytes to hash + * @returns Digest bytes. + * @example + * Hash a message with SHA3-512. + * ```ts + * sha3_512(new Uint8Array([97, 98, 99])); + * ``` + */ +export const sha3_512 = /* @__PURE__ */ genKeccak(0x06, 72, 64, +/* @__PURE__ */ oidNist(0x0a)); +/** + * Keccak-224 hash function. + * @param msg - message bytes to hash + * @returns Digest bytes. + * @example + * Hash a message with Keccak-224. + * ```ts + * keccak_224(new Uint8Array([97, 98, 99])); + * ``` + */ +export const keccak_224 = /* @__PURE__ */ genKeccak(0x01, 144, 28); +/** + * Keccak-256 hash function. Different from SHA3-256. + * @param msg - message bytes to hash + * @returns Digest bytes. + * @example + * Hash a message with Keccak-256. + * ```ts + * keccak_256(new Uint8Array([97, 98, 99])); + * ``` + */ +export const keccak_256 = /* @__PURE__ */ genKeccak(0x01, 136, 32); +/** + * Keccak-384 hash function. + * @param msg - message bytes to hash + * @returns Digest bytes. + * @example + * Hash a message with Keccak-384. + * ```ts + * keccak_384(new Uint8Array([97, 98, 99])); + * ``` + */ +export const keccak_384 = /* @__PURE__ */ genKeccak(0x01, 104, 48); +/** + * Keccak-512 hash function. + * @param msg - message bytes to hash + * @returns Digest bytes. + * @example + * Hash a message with Keccak-512. + * ```ts + * keccak_512(new Uint8Array([97, 98, 99])); + * ``` + */ +export const keccak_512 = /* @__PURE__ */ genKeccak(0x01, 72, 64); +const genShake = (suffix, blockLen, outputLen, info = {}) => createHasher((opts = {}) => new Keccak(blockLen, suffix, opts.dkLen === undefined ? outputLen : opts.dkLen, true), info); +/** + * SHAKE128 XOF with 128-bit security and a 16-byte default output. + * @param msg - message bytes to hash + * @param opts - Optional output-length override. See {@link ShakeOpts}. + * @returns Digest bytes. + * @example + * Hash a message with SHAKE128. + * ```ts + * shake128(new Uint8Array([97, 98, 99]), { dkLen: 32 }); + * ``` + */ +export const shake128 = +/* @__PURE__ */ +genShake(0x1f, 168, 16, /* @__PURE__ */ oidNist(0x0b)); +/** + * SHAKE256 XOF with 256-bit security and a 32-byte default output. + * @param msg - message bytes to hash + * @param opts - Optional output-length override. See {@link ShakeOpts}. + * @returns Digest bytes. + * @example + * Hash a message with SHAKE256. + * ```ts + * shake256(new Uint8Array([97, 98, 99]), { dkLen: 64 }); + * ``` + */ +export const shake256 = +/* @__PURE__ */ +genShake(0x1f, 136, 32, /* @__PURE__ */ oidNist(0x0c)); +/** + * SHAKE128 XOF with 256-bit output (NIST version). + * @param msg - message bytes to hash + * @param opts - Optional output-length override. See {@link ShakeOpts}. + * @returns Digest bytes. + * @example + * Hash a message with SHAKE128 using a 32-byte default output. + * ```ts + * shake128_32(new Uint8Array([97, 98, 99]), { dkLen: 32 }); + * ``` + */ +export const shake128_32 = +/* @__PURE__ */ +genShake(0x1f, 168, 32, /* @__PURE__ */ oidNist(0x0b)); +/** + * SHAKE256 XOF with 512-bit output (NIST version). + * @param msg - message bytes to hash + * @param opts - Optional output-length override. See {@link ShakeOpts}. + * @returns Digest bytes. + * @example + * Hash a message with SHAKE256 using a 64-byte default output. + * ```ts + * shake256_64(new Uint8Array([97, 98, 99]), { dkLen: 64 }); + * ``` + */ +export const shake256_64 = +/* @__PURE__ */ +genShake(0x1f, 136, 64, /* @__PURE__ */ oidNist(0x0c)); +//# sourceMappingURL=sha3.js.map \ No newline at end of file diff --git a/node_modules/@noble/hashes/sha3.js.map b/node_modules/@noble/hashes/sha3.js.map new file mode 100644 index 0000000..4be5999 --- /dev/null +++ b/node_modules/@noble/hashes/sha3.js.map @@ -0,0 +1 @@ +{"version":3,"file":"sha3.js","sourceRoot":"","sources":["src/sha3.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAClE,kBAAkB;AAClB,OAAO,EACL,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EACjC,KAAK,EAAE,YAAY,EACnB,OAAO,EACP,UAAU,EACV,GAAG,EAOJ,MAAM,YAAY,CAAC;AAEpB,0CAA0C;AAC1C,8CAA8C;AAC9C,2CAA2C;AAC3C,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;AACtB,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;AACtB,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;AACtB,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;AACtB,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;AAC1B,6EAA6E;AAC7E,qEAAqE;AACrE,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;AAC5B,MAAM,OAAO,GAAa,EAAE,CAAC;AAC7B,MAAM,SAAS,GAAa,EAAE,CAAC;AAC/B,MAAM,UAAU,GAAa,EAAE,CAAC,CAAC,yCAAyC;AAC1E,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,GAAG,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC;IAC/D,KAAK;IACL,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAClC,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC9B,aAAa;IACb,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IACvD,OAAO;IACP,IAAI,CAAC,GAAG,GAAG,CAAC;IACZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,GAAG,KAAK,CAAC;QACjD,IAAI,CAAC,GAAG,GAAG;YAAE,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;IACtD,CAAC;IACD,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACrB,CAAC;AACD,MAAM,KAAK,GAAG,KAAK,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;AACtC,4EAA4E;AAC5E,sEAAsE;AACtE,wEAAwE;AACxE,MAAM,WAAW,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;AAC7B,MAAM,WAAW,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;AAE7B,oCAAoC;AACpC,MAAM,KAAK,GAAG,CAAC,CAAS,EAAE,CAAS,EAAE,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAChG,MAAM,KAAK,GAAG,CAAC,CAAS,EAAE,CAAS,EAAE,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAEhG;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,OAAO,CAAC,CAAoB,EAAE,SAAiB,EAAE;IAC/D,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC1B,wFAAwF;IACxF,IAAI,MAAM,GAAG,CAAC,IAAI,MAAM,GAAG,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;IAClF,MAAM,CAAC,GAAG,IAAI,WAAW,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACjC,8FAA8F;IAC9F,KAAK,IAAI,KAAK,GAAG,EAAE,GAAG,MAAM,EAAE,KAAK,GAAG,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC;QAClD,UAAU;QACV,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE;YAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;QACzF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/B,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;YAC1B,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;YAC1B,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;YACnB,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;YACvB,MAAM,EAAE,GAAG,KAAK,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;YACtC,MAAM,EAAE,GAAG,KAAK,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;YAC1C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC;gBAChC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;gBACf,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;YACrB,CAAC;QACH,CAAC;QACD,qBAAqB;QACrB,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAChB,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5B,MAAM,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;YAC3B,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;YACpC,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;YACpC,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;YACtB,IAAI,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;YACb,IAAI,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;YACjB,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC;YACX,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;QACjB,CAAC;QACD,UAAU;QACV,WAAW;QACX,gDAAgD;QAChD,+EAA+E;QAC/E,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC;YAChC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,EACb,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EACb,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EACb,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAChB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAC7B,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACjC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACjC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACjC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACjC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACjC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;YAC3B,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;YAC3B,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;YACrB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACvB,CAAC;QACD,WAAW;QACX,CAAC,CAAC,CAAC,CAAC,IAAI,WAAW,CAAC,KAAK,CAAC,CAAC;QAC3B,CAAC,CAAC,CAAC,CAAC,IAAI,WAAW,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC;IACD,KAAK,CAAC,CAAC,CAAC,CAAC;AACX,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,OAAO,MAAM;IACP,KAAK,CAAa;IAClB,GAAG,GAAG,CAAC,CAAC;IACR,MAAM,GAAG,CAAC,CAAC;IACX,QAAQ,GAAG,KAAK,CAAC;IACjB,OAAO,CAAc;IACrB,SAAS,GAAG,KAAK,CAAC;IAErB,QAAQ,CAAS;IACjB,MAAM,CAAS;IACf,SAAS,CAAS;IAClB,MAAM,CAAU;IACb,SAAS,GAAG,KAAK,CAAC;IAClB,MAAM,CAAS;IAEzB,2DAA2D;IAC3D,YACE,QAAgB,EAChB,MAAc,EACd,SAAiB,EACjB,SAAS,GAAG,KAAK,EACjB,SAAiB,EAAE;QAEnB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC;QACxB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,mCAAmC;QACnC,OAAO,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;QAChC,uDAAuD;QACvD,qBAAqB;QACrB,IAAI,CAAC,CAAC,CAAC,GAAG,QAAQ,IAAI,QAAQ,GAAG,GAAG,CAAC;YACnC,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;QAC7D,IAAI,CAAC,KAAK,GAAG,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,CAAC,OAAO,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACjC,CAAC;IACD,KAAK;QACH,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC;IAC3B,CAAC;IACS,MAAM;QACd,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACzB,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QACnC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACzB,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;QAChB,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC;IACf,CAAC;IACD,MAAM,CAAC,IAAsB;QAC3B,OAAO,CAAC,IAAI,CAAC,CAAC;QACd,MAAM,CAAC,IAAI,CAAC,CAAC;QACb,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC;QACjC,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC;QACxB,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,GAAG,GAAI,CAAC;YAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,CAAC,CAAC;YACtD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE;gBAAE,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;YAChE,IAAI,IAAI,CAAC,GAAG,KAAK,QAAQ;gBAAE,IAAI,CAAC,MAAM,EAAE,CAAC;QAC3C,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACS,MAAM;QACd,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO;QAC1B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;QAC9C,2EAA2E;QAC3E,qEAAqE;QACrE,yEAAyE;QACzE,KAAK,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC;QACrB,uEAAuE;QACvE,sEAAsE;QACtE,eAAe;QACf,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,KAAK,QAAQ,GAAG,CAAC;YAAE,IAAI,CAAC,MAAM,EAAE,CAAC;QACjE,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC;QAC5B,IAAI,CAAC,MAAM,EAAE,CAAC;IAChB,CAAC;IACS,SAAS,CAAC,GAAqB;QACvC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACrB,MAAM,CAAC,GAAG,CAAC,CAAC;QACZ,IAAI,CAAC,MAAM,EAAE,CAAC;QACd,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC;QAC7B,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;QAC1B,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,GAAG,CAAC,MAAM,EAAE,GAAG,GAAG,GAAG,GAAI,CAAC;YAChD,IAAI,IAAI,CAAC,MAAM,IAAI,QAAQ;gBAAE,IAAI,CAAC,MAAM,EAAE,CAAC;YAC3C,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,GAAG,CAAC,CAAC;YACzD,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;YAClE,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC;YACpB,GAAG,IAAI,IAAI,CAAC;QACd,CAAC;QACD,OAAO,GAAuB,CAAC;IACjC,CAAC;IACD,OAAO,CAAC,GAAqB;QAC3B,wEAAwE;QACxE,oEAAoE;QACpE,oEAAoE;QACpE,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;QAC9E,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;IACD,GAAG,CAAC,KAAa;QACf,OAAO,CAAC,KAAK,CAAC,CAAC;QACf,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;IAC7C,CAAC;IACD,UAAU,CAAC,GAAqB;QAC9B,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACnB,IAAI,IAAI,CAAC,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;QAClE,8FAA8F;QAC9F,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;QAChD,IAAI,CAAC,OAAO,EAAE,CAAC;IACjB,CAAC;IACD,MAAM;QACJ,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC3C,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QACrB,OAAO,GAAuB,CAAC;IACjC,CAAC;IACD,OAAO;QACL,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACpB,CAAC;IACD,UAAU,CAAC,EAAW;QACpB,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC;QAChE,EAAE,KAAK,IAAI,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;QAClE,6FAA6F;QAC7F,kDAAkD;QAClD,EAAE,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACvB,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC7B,EAAE,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC;QAClB,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QACxB,EAAE,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC5B,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC;QACnB,8BAA8B;QAC9B,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC;QACnB,EAAE,CAAC,SAAS,GAAG,SAAS,CAAC;QACzB,EAAE,CAAC,SAAS,GAAG,SAAS,CAAC;QACzB,8FAA8F;QAC9F,0FAA0F;QAC1F,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QACxB,EAAE,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;QAC9B,OAAO,EAAE,CAAC;IACZ,CAAC;CACF;AAED,MAAM,SAAS,GAAG,CAChB,MAAc,EACd,QAAgB,EAChB,SAAiB,EACjB,OAAuB,EAAE,EACzB,EAAE,CAAC,YAAY,CAAC,GAAG,EAAE,CAAC,IAAI,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,IAAI,CAAC,CAAC;AAEvE;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAgB,eAAe,CAAC,SAAS,CAC5D,IAAI,EACJ,GAAG,EACH,EAAE;AACF,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC,CAC9B,CAAC;AACF;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAgB,eAAe,CAAC,SAAS,CAC5D,IAAI,EACJ,GAAG,EACH,EAAE;AACF,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC,CAC9B,CAAC;AACF;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAgB,eAAe,CAAC,SAAS,CAC5D,IAAI,EACJ,GAAG,EACH,EAAE;AACF,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC,CAC9B,CAAC;AACF;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAgB,eAAe,CAAC,SAAS,CAC5D,IAAI,EACJ,EAAE,EACF,EAAE;AACF,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC,CAC9B,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,UAAU,GAAgB,eAAe,CAAC,SAAS,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;AAChF;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,UAAU,GAAgB,eAAe,CAAC,SAAS,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;AAChF;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,UAAU,GAAgB,eAAe,CAAC,SAAS,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;AAChF;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,UAAU,GAAgB,eAAe,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;AAQ/E,MAAM,QAAQ,GAAG,CAAC,MAAc,EAAE,QAAgB,EAAE,SAAiB,EAAE,OAAuB,EAAE,EAAE,EAAE,CAClG,YAAY,CACV,CAAC,OAAkB,EAAE,EAAE,EAAE,CACvB,IAAI,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,EACvF,IAAI,CACL,CAAC;AAEJ;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,QAAQ;AACnB,eAAe;AACf,QAAQ,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;AACzD;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,QAAQ;AACnB,eAAe;AACf,QAAQ,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;AAEzD;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,WAAW;AACtB,eAAe;AACf,QAAQ,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;AACzD;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,WAAW;AACtB,eAAe;AACf,QAAQ,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC"} \ No newline at end of file diff --git a/node_modules/@noble/hashes/src/_blake.ts b/node_modules/@noble/hashes/src/_blake.ts new file mode 100644 index 0000000..7433033 --- /dev/null +++ b/node_modules/@noble/hashes/src/_blake.ts @@ -0,0 +1,57 @@ +/** + * Internal helpers for blake hash. + * @module + */ +import { rotr, type TRet } from './utils.ts'; + +/** + * Internal blake permutation table. + * Rows `0..9` serve BLAKE2s, rows `0..11` serve BLAKE2b with `10..11 = 0..1`, and Blake1 also + * reuses the later rows shown below. Blake1 expands rounds `10..15` as `SIGMA[i % 10]`, so rows + * `10..15` intentionally repeat rows `0..5` for the 14-round (256) and 16-round (512) variants. + */ +// prettier-ignore +export const BSIGMA: TRet = /* @__PURE__ */ Uint8Array.from([ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3, + 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4, + 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8, + 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13, + 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9, + 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11, + 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10, + 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5, + 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3, + // Blake1, unused in others + 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4, + 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8, + 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13, + 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9, +]); + +// prettier-ignore +export type Num4 = { a: number; b: number; c: number; d: number; }; + +// 32-bit / BLAKE2s first half of G, with the fixed `(16, 12)` rotation pair. +// Parameter `x` is the RFC 7693 first-half message word, or Blake1's pre-mixed +// `m[sigma[r][2i]] ^ u[sigma[r][2i+1]]` addend in the 32-bit path. +export function G1s(a: number, b: number, c: number, d: number, x: number): Num4 { + a = (a + b + x) | 0; + d = rotr(d ^ a, 16); + c = (c + d) | 0; + b = rotr(b ^ c, 12); + return { a, b, c, d }; +} + +// 32-bit / BLAKE2s second half of G. +// Parameter `x` is the RFC 7693 second-half (`y`) message word, or Blake1's pre-mixed +// `m[sigma[r][2i + 1]] ^ u[sigma[r][2i]]` addend in the 32-bit path. +export function G2s(a: number, b: number, c: number, d: number, x: number): Num4 { + a = (a + b + x) | 0; + d = rotr(d ^ a, 8); + c = (c + d) | 0; + b = rotr(b ^ c, 7); + return { a, b, c, d }; +} diff --git a/node_modules/@noble/hashes/src/_md.ts b/node_modules/@noble/hashes/src/_md.ts new file mode 100644 index 0000000..1de1258 --- /dev/null +++ b/node_modules/@noble/hashes/src/_md.ts @@ -0,0 +1,222 @@ +/** + * Internal Merkle-Damgard hash utils. + * @module + */ +import { + abytes, + aexists, + aoutput, + clean, + createView, + type Hash, + type TArg, + type TRet, +} from './utils.ts'; + +/** + * Shared 32-bit conditional boolean primitive reused by SHA-256, SHA-1, and MD5 `F`. + * Returns bits from `b` when `a` is set, otherwise from `c`. + * The XOR form is equivalent to MD5's `F(X,Y,Z) = XY v not(X)Z` because the masked terms never + * set the same bit. + * @param a - selector word + * @param b - word chosen when selector bit is set + * @param c - word chosen when selector bit is clear + * @returns Mixed 32-bit word. + * @example + * Combine three words with the shared 32-bit choice primitive. + * ```ts + * Chi(0xffffffff, 0x12345678, 0x87654321); + * ``` + */ +export function Chi(a: number, b: number, c: number): number { + return (a & b) ^ (~a & c); +} + +/** + * Shared 32-bit majority primitive reused by SHA-256 and SHA-1. + * Returns bits shared by at least two inputs. + * @param a - first input word + * @param b - second input word + * @param c - third input word + * @returns Mixed 32-bit word. + * @example + * Combine three words with the shared 32-bit majority primitive. + * ```ts + * Maj(0xffffffff, 0x12345678, 0x87654321); + * ``` + */ +export function Maj(a: number, b: number, c: number): number { + return (a & b) ^ (a & c) ^ (b & c); +} + +/** + * Merkle-Damgard hash construction base class. + * Could be used to create MD5, RIPEMD, SHA1, SHA2. + * Accepts only byte-aligned `Uint8Array` input, even when the underlying spec describes bit + * strings with partial-byte tails. + * @param blockLen - internal block size in bytes + * @param outputLen - digest size in bytes + * @param padOffset - trailing length field size in bytes + * @param isLE - whether length and state words are encoded in little-endian + * @example + * Use a concrete subclass to get the shared Merkle-Damgard update/digest flow. + * ```ts + * import { _SHA1 } from '@noble/hashes/legacy.js'; + * const hash = new _SHA1(); + * hash.update(new Uint8Array([97, 98, 99])); + * hash.digest(); + * ``` + */ +export abstract class HashMD> implements Hash { + // Subclasses must treat `buf` as read-only: `update()` may pass a direct view over caller input + // when it can process whole blocks without buffering first. + protected abstract process(buf: DataView, offset: number): void; + protected abstract get(): number[]; + protected abstract set(...args: number[]): void; + abstract destroy(): void; + protected abstract roundClean(): void; + + readonly blockLen: number; + readonly outputLen: number; + readonly canXOF = false; + readonly padOffset: number; + readonly isLE: boolean; + + // For partial updates less than block size + protected buffer: Uint8Array; + protected view: DataView; + protected finished = false; + protected length = 0; + protected pos = 0; + protected destroyed = false; + + constructor(blockLen: number, outputLen: number, padOffset: number, isLE: boolean) { + this.blockLen = blockLen; + this.outputLen = outputLen; + this.padOffset = padOffset; + this.isLE = isLE; + this.buffer = new Uint8Array(blockLen); + this.view = createView(this.buffer); + } + update(data: TArg): this { + aexists(this); + abytes(data); + const { view, buffer, blockLen } = this; + const len = data.length; + for (let pos = 0; pos < len; ) { + const take = Math.min(blockLen - this.pos, len - pos); + // Fast path only when there is no buffered partial block: `take === blockLen` implies + // `this.pos === 0`, so we can process full blocks directly from the input view. + if (take === blockLen) { + const dataView = createView(data); + for (; blockLen <= len - pos; pos += blockLen) this.process(dataView, pos); + continue; + } + buffer.set(data.subarray(pos, pos + take), this.pos); + this.pos += take; + pos += take; + if (this.pos === blockLen) { + this.process(view, 0); + this.pos = 0; + } + } + this.length += data.length; + this.roundClean(); + return this; + } + digestInto(out: TArg): void { + aexists(this); + aoutput(out, this); + this.finished = true; + // Padding + // We can avoid allocation of buffer for padding completely if it + // was previously not allocated here. But it won't change performance. + const { buffer, view, blockLen, isLE } = this; + let { pos } = this; + // append the bit '1' to the message + buffer[pos++] = 0b10000000; + clean(this.buffer.subarray(pos)); + // we have less than padOffset left in buffer, so we cannot put length in + // current block, need process it and pad again + if (this.padOffset > blockLen - pos) { + this.process(view, 0); + pos = 0; + } + // Pad until full block byte with zeros + for (let i = pos; i < blockLen; i++) buffer[i] = 0; + // `padOffset` reserves the whole length field. For SHA-384/512 the high 64 bits stay zero from + // the padding fill above, and JS will overflow before user input can make that half non-zero. + // So we only need to write the low 64 bits here. + view.setBigUint64(blockLen - 8, BigInt(this.length * 8), isLE); + this.process(view, 0); + const oview = createView(out); + const len = this.outputLen; + // NOTE: we do division by 4 later, which must be fused in single op with modulo by JIT + if (len % 4) throw new Error('_sha2: outputLen must be aligned to 32bit'); + const outLen = len / 4; + const state = this.get(); + if (outLen > state.length) throw new Error('_sha2: outputLen bigger than state'); + for (let i = 0; i < outLen; i++) oview.setUint32(4 * i, state[i], isLE); + } + digest(): TRet { + const { buffer, outputLen } = this; + this.digestInto(buffer); + // Copy before destroy(): subclasses wipe `buffer` during cleanup, but `digest()` must return + // fresh bytes to the caller. + const res = buffer.slice(0, outputLen); + this.destroy(); + return res as TRet; + } + _cloneInto(to?: T): T { + to ||= new (this.constructor as any)() as T; + to.set(...this.get()); + const { blockLen, buffer, length, finished, destroyed, pos } = this; + to.destroyed = destroyed; + to.finished = finished; + to.length = length; + to.pos = pos; + // Only partial-block bytes need copying: when `length % blockLen === 0`, `pos === 0` and + // later `update()` / `digestInto()` overwrite `to.buffer` from the start before reading it. + if (length % blockLen) to.buffer.set(buffer); + return to as unknown as any; + } + clone(): T { + return this._cloneInto(); + } +} + +/** + * Initial SHA-2 state: fractional parts of square roots of first 16 primes 2..53. + * Check out `test/misc/sha2-gen-iv.js` for recomputation guide. + */ + +/** Initial SHA256 state from RFC 6234 §6.1: the first 32 bits of the fractional parts of the + * square roots of the first eight prime numbers. Exported as a shared table; callers must treat + * it as read-only because constructors copy words from it by index. */ +export const SHA256_IV: TRet = /* @__PURE__ */ Uint32Array.from([ + 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19, +]); + +/** Initial SHA224 state `H(0)` from RFC 6234 §6.1. Exported as a shared table; callers must + * treat it as read-only because constructors copy words from it by index. */ +export const SHA224_IV: TRet = /* @__PURE__ */ Uint32Array.from([ + 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4, +]); + +/** Initial SHA384 state from RFC 6234 §6.3: eight RFC 64-bit `H(0)` words stored as sixteen + * big-endian 32-bit halves. Derived from the fractional parts of the square roots of the ninth + * through sixteenth prime numbers. Exported as a shared table; callers must treat it as read-only + * because constructors copy halves from it by index. */ +export const SHA384_IV: TRet = /* @__PURE__ */ Uint32Array.from([ + 0xcbbb9d5d, 0xc1059ed8, 0x629a292a, 0x367cd507, 0x9159015a, 0x3070dd17, 0x152fecd8, 0xf70e5939, + 0x67332667, 0xffc00b31, 0x8eb44a87, 0x68581511, 0xdb0c2e0d, 0x64f98fa7, 0x47b5481d, 0xbefa4fa4, +]); + +/** Initial SHA512 state from RFC 6234 §6.3: eight RFC 64-bit `H(0)` words stored as sixteen + * big-endian 32-bit halves. Derived from the fractional parts of the square roots of the first + * eight prime numbers. Exported as a shared table; callers must treat it as read-only because + * constructors copy halves from it by index. */ +export const SHA512_IV: TRet = /* @__PURE__ */ Uint32Array.from([ + 0x6a09e667, 0xf3bcc908, 0xbb67ae85, 0x84caa73b, 0x3c6ef372, 0xfe94f82b, 0xa54ff53a, 0x5f1d36f1, + 0x510e527f, 0xade682d1, 0x9b05688c, 0x2b3e6c1f, 0x1f83d9ab, 0xfb41bd6b, 0x5be0cd19, 0x137e2179, +]); diff --git a/node_modules/@noble/hashes/src/_u64.ts b/node_modules/@noble/hashes/src/_u64.ts new file mode 100644 index 0000000..2b7c593 --- /dev/null +++ b/node_modules/@noble/hashes/src/_u64.ts @@ -0,0 +1,117 @@ +/** + * Internal helpers for u64. + * BigUint64Array is too slow as per 2026, so we implement it using + * Uint32Array. + * @privateRemarks TODO: re-check {@link https://issues.chromium.org/issues/42212588} + * @module + */ +import type { TRet } from './utils.ts'; + +const U32_MASK64 = /* @__PURE__ */ BigInt(2 ** 32 - 1); +const _32n = /* @__PURE__ */ BigInt(32); + +// Split bigint into two 32-bit halves. With `le=true`, returned fields become `{ h: low, l: high +// }` to match little-endian word order rather than the property names. +function fromBig( + n: bigint, + le = false +): { + h: number; + l: number; +} { + if (le) return { h: Number(n & U32_MASK64), l: Number((n >> _32n) & U32_MASK64) }; + return { h: Number((n >> _32n) & U32_MASK64) | 0, l: Number(n & U32_MASK64) | 0 }; +} + +// Split bigint list into `[highWords, lowWords]` when `le=false`; with `le=true`, the first array +// holds the low halves because `fromBig(...)` swaps the semantic meaning of `h` and `l`. +function split(lst: bigint[], le = false): TRet { + const len = lst.length; + let Ah = new Uint32Array(len); + let Al = new Uint32Array(len); + for (let i = 0; i < len; i++) { + const { h, l } = fromBig(lst[i], le); + [Ah[i], Al[i]] = [h, l]; + } + return [Ah, Al] as TRet; +} + +// Combine explicit `(high, low)` 32-bit halves into a bigint; `>>> 0` normalizes signed JS +// bitwise results back to uint32 first, and little-endian callers must swap. +const toBig = (h: number, l: number): bigint => (BigInt(h >>> 0) << _32n) | BigInt(l >>> 0); +// High 32-bit half of a 64-bit logical right shift for `s` in `0..31`. +const shrSH = (h: number, _l: number, s: number): number => h >>> s; +// Low 32-bit half of a 64-bit logical right shift, valid for `s` in `1..31`. +const shrSL = (h: number, l: number, s: number): number => (h << (32 - s)) | (l >>> s); +// High 32-bit half of a 64-bit right rotate, valid for `s` in `1..31`. +const rotrSH = (h: number, l: number, s: number): number => (h >>> s) | (l << (32 - s)); +// Low 32-bit half of a 64-bit right rotate, valid for `s` in `1..31`. +const rotrSL = (h: number, l: number, s: number): number => (h << (32 - s)) | (l >>> s); +// High 32-bit half of a 64-bit right rotate, valid for `s` in `33..63`; `32` uses `rotr32*`. +const rotrBH = (h: number, l: number, s: number): number => (h << (64 - s)) | (l >>> (s - 32)); +// Low 32-bit half of a 64-bit right rotate, valid for `s` in `33..63`; `32` uses `rotr32*`. +const rotrBL = (h: number, l: number, s: number): number => (h >>> (s - 32)) | (l << (64 - s)); +// High 32-bit half of a 64-bit right rotate for `s === 32`; this is just the swapped low half. +const rotr32H = (_h: number, l: number): number => l; +// Low 32-bit half of a 64-bit right rotate for `s === 32`; this is just the swapped high half. +const rotr32L = (h: number, _l: number): number => h; +// High 32-bit half of a 64-bit left rotate, valid for `s` in `1..31`. +const rotlSH = (h: number, l: number, s: number): number => (h << s) | (l >>> (32 - s)); +// Low 32-bit half of a 64-bit left rotate, valid for `s` in `1..31`. +const rotlSL = (h: number, l: number, s: number): number => (l << s) | (h >>> (32 - s)); +// High 32-bit half of a 64-bit left rotate, valid for `s` in `33..63`; `32` uses `rotr32*`. +const rotlBH = (h: number, l: number, s: number): number => (l << (s - 32)) | (h >>> (64 - s)); +// Low 32-bit half of a 64-bit left rotate, valid for `s` in `33..63`; `32` uses `rotr32*`. +const rotlBL = (h: number, l: number, s: number): number => (h << (s - 32)) | (l >>> (64 - s)); + +// Add two split 64-bit words and return the split `{ h, l }` sum. +// JS uses 32-bit signed integers for bitwise operations, so we cannot simply shift the carry out +// of the low sum and instead use division. +function add( + Ah: number, + Al: number, + Bh: number, + Bl: number +): { + h: number; + l: number; +} { + const l = (Al >>> 0) + (Bl >>> 0); + return { h: (Ah + Bh + ((l / 2 ** 32) | 0)) | 0, l: l | 0 }; +} +// Addition with more than 2 elements +// Unmasked low-word accumulator for 3-way addition; pass the raw result into `add3H(...)`. +const add3L = (Al: number, Bl: number, Cl: number): number => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0); +// High-word finalize step for 3-way addition; `low` must be the untruncated output of `add3L(...)`. +const add3H = (low: number, Ah: number, Bh: number, Ch: number): number => + (Ah + Bh + Ch + ((low / 2 ** 32) | 0)) | 0; +// Unmasked low-word accumulator for 4-way addition; pass the raw result into `add4H(...)`. +const add4L = (Al: number, Bl: number, Cl: number, Dl: number): number => + (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0); +// High-word finalize step for 4-way addition; `low` must be the untruncated output of `add4L(...)`. +const add4H = (low: number, Ah: number, Bh: number, Ch: number, Dh: number): number => + (Ah + Bh + Ch + Dh + ((low / 2 ** 32) | 0)) | 0; +// Unmasked low-word accumulator for 5-way addition; pass the raw result into `add5H(...)`. +const add5L = (Al: number, Bl: number, Cl: number, Dl: number, El: number): number => + (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0) + (El >>> 0); +// High-word finalize step for 5-way addition; `low` must be the untruncated output of `add5L(...)`. +const add5H = (low: number, Ah: number, Bh: number, Ch: number, Dh: number, Eh: number): number => + (Ah + Bh + Ch + Dh + Eh + ((low / 2 ** 32) | 0)) | 0; + +// prettier-ignore +export { + add, add3H, add3L, add4H, add4L, add5H, add5L, fromBig, rotlBH, rotlBL, rotlSH, rotlSL, rotr32H, rotr32L, rotrBH, rotrBL, rotrSH, rotrSL, shrSH, shrSL, split, toBig +}; +// Canonical grouped namespace for callers that prefer one object. +// Named exports stay for direct imports. +// prettier-ignore +const u64: { fromBig: typeof fromBig; split: typeof split; toBig: (h: number, l: number) => bigint; shrSH: (h: number, _l: number, s: number) => number; shrSL: (h: number, l: number, s: number) => number; rotrSH: (h: number, l: number, s: number) => number; rotrSL: (h: number, l: number, s: number) => number; rotrBH: (h: number, l: number, s: number) => number; rotrBL: (h: number, l: number, s: number) => number; rotr32H: (_h: number, l: number) => number; rotr32L: (h: number, _l: number) => number; rotlSH: (h: number, l: number, s: number) => number; rotlSL: (h: number, l: number, s: number) => number; rotlBH: (h: number, l: number, s: number) => number; rotlBL: (h: number, l: number, s: number) => number; add: typeof add; add3L: (Al: number, Bl: number, Cl: number) => number; add3H: (low: number, Ah: number, Bh: number, Ch: number) => number; add4L: (Al: number, Bl: number, Cl: number, Dl: number) => number; add4H: (low: number, Ah: number, Bh: number, Ch: number, Dh: number) => number; add5H: (low: number, Ah: number, Bh: number, Ch: number, Dh: number, Eh: number) => number; add5L: (Al: number, Bl: number, Cl: number, Dl: number, El: number) => number; } = { + fromBig, split, toBig, + shrSH, shrSL, + rotrSH, rotrSL, rotrBH, rotrBL, + rotr32H, rotr32L, + rotlSH, rotlSL, rotlBH, rotlBL, + add, add3L, add3H, add4L, add4H, add5H, add5L, +}; +// Default export mirrors named `u64` for compatibility with object-style imports. +export default u64; diff --git a/node_modules/@noble/hashes/src/argon2.ts b/node_modules/@noble/hashes/src/argon2.ts new file mode 100644 index 0000000..51fd315 --- /dev/null +++ b/node_modules/@noble/hashes/src/argon2.ts @@ -0,0 +1,667 @@ +/** + * Argon2 KDF from RFC 9106. Can be used to create a key from password and salt. + * We suggest to use Scrypt. JS Argon is 2-10x slower than native code because of 64-bitness: + * * argon uses uint64, but JS doesn't have fast uint64array + * * uint64 multiplication is 1/3 of time + * * `P` function would be very nice with u64, because most of value will be in registers, + * hovewer with u32 it will require 32 registers, which is too much. + * * JS arrays do slow bound checks, so reading from `A2_BUF` slows it down + * @module + */ +import { add3H, add3L, rotr32H, rotr32L, rotrBH, rotrBL, rotrSH, rotrSL } from './_u64.ts'; +import { blake2b } from './blake2.ts'; +import { + anumber, + clean, + kdfInputToBytes, + nextTick, + swap32IfBE, + swap8IfBE, + u32, + u8, + type KDFInput, + type TArg, + type TRet, +} from './utils.ts'; + +// RFC 9106 §3.1 type `y`: 0 = Argon2d, 1 = Argon2i, 2 = Argon2id. The numeric values are the +// spec-bound part here; the object keys are internal labels. +const AT = { Argond2d: 0, Argon2i: 1, Argon2id: 2 } as const; +type Types = (typeof AT)[keyof typeof AT]; + +// RFC 9106 sync points constant `SL = 4`, fixed by the design rather than exposed as a tuning knob. +const ARGON2_SYNC_POINTS = 4; +// Preserve Argon2's `LE32(len(X)) || X` encoding for omitted +// optional fields by emitting empty bytes. +const abytesOrZero = (buf?: TArg, errorTitle = ''): TRet => { + if (buf === undefined) return Uint8Array.of(); + return kdfInputToBytes(buf, errorTitle); +}; + +// Unsigned `u32 * u32 = { h, l }`, returned as split 64-bit halves. +function mul(a: number, b: number) { + // Split into 16-bit limbs so each partial product stays exact under `Math.imul`. + const aL = a & 0xffff; + const aH = a >>> 16; + const bL = b & 0xffff; + const bH = b >>> 16; + const ll = Math.imul(aL, bL); + const hl = Math.imul(aH, bL); + const lh = Math.imul(aL, bH); + const hh = Math.imul(aH, bH); + const carry = (ll >>> 16) + (hl & 0xffff) + lh; + const high = (hh + (hl >>> 16) + (carry >>> 16)) | 0; + const low = (carry << 16) | (ll & 0xffff); + return { h: high, l: low }; +} + +function mul2(a: number, b: number) { + // Double the split 64-bit product; carry from `l` is folded back into `h` via `l >>> 31`. + const { h, l } = mul(a, b); + return { h: ((h << 1) | (l >>> 31)) & 0xffff_ffff, l: (l << 1) & 0xffff_ffff }; +} + +// BlaMka permutation for Argon2 +// `A + B + 2 * trunc(A) * trunc(B)`, where `trunc(...)` means the low 32-bit halves. +function blamka(Ah: number, Al: number, Bh: number, Bl: number) { + const { h: Ch, l: Cl } = mul2(Al, Bl); + // A + B + (2 * A * B) + const Rll = add3L(Al, Bl, Cl); + return { h: add3H(Rll, Ah, Bh, Ch), l: Rll | 0 }; +} + +// Temporary block buffer. +// 1024-byte block: 256 u32 = 128 interleaved low/high halves = RFC's +// 8x8 matrix of 16-byte registers. +const A2_BUF = new Uint32Array(256); + +// Quarter-round over 64-bit word indices into `A2_BUF`; each index maps to adjacent low/high u32s. +function G(a: number, b: number, c: number, d: number) { + let Al = A2_BUF[2*a], Ah = A2_BUF[2*a + 1]; // prettier-ignore + let Bl = A2_BUF[2*b], Bh = A2_BUF[2*b + 1]; // prettier-ignore + let Cl = A2_BUF[2*c], Ch = A2_BUF[2*c + 1]; // prettier-ignore + let Dl = A2_BUF[2*d], Dh = A2_BUF[2*d + 1]; // prettier-ignore + + // RFC 9106 Figure 19 GB rotates by 32, 24, 16, and 63 bits after each XOR step. + ({ h: Ah, l: Al } = blamka(Ah, Al, Bh, Bl)); + ({ Dh, Dl } = { Dh: Dh ^ Ah, Dl: Dl ^ Al }); + ({ Dh, Dl } = { Dh: rotr32H(Dh, Dl), Dl: rotr32L(Dh, Dl) }); + + ({ h: Ch, l: Cl } = blamka(Ch, Cl, Dh, Dl)); + ({ Bh, Bl } = { Bh: Bh ^ Ch, Bl: Bl ^ Cl }); + ({ Bh, Bl } = { Bh: rotrSH(Bh, Bl, 24), Bl: rotrSL(Bh, Bl, 24) }); + + ({ h: Ah, l: Al } = blamka(Ah, Al, Bh, Bl)); + ({ Dh, Dl } = { Dh: Dh ^ Ah, Dl: Dl ^ Al }); + ({ Dh, Dl } = { Dh: rotrSH(Dh, Dl, 16), Dl: rotrSL(Dh, Dl, 16) }); + + ({ h: Ch, l: Cl } = blamka(Ch, Cl, Dh, Dl)); + ({ Bh, Bl } = { Bh: Bh ^ Ch, Bl: Bl ^ Cl }); + ({ Bh, Bl } = { Bh: rotrBH(Bh, Bl, 63), Bl: rotrBL(Bh, Bl, 63) }); + + ((A2_BUF[2 * a] = Al), (A2_BUF[2 * a + 1] = Ah)); + ((A2_BUF[2 * b] = Bl), (A2_BUF[2 * b + 1] = Bh)); + ((A2_BUF[2 * c] = Cl), (A2_BUF[2 * c + 1] = Ch)); + ((A2_BUF[2 * d] = Dl), (A2_BUF[2 * d + 1] = Dh)); +} + +// Argon2 permutation over 16 register indices into `A2_BUF`, not the register values themselves. +// RFC 9106 Figure 17: these arguments are the 16 `v0..v15` 64-bit word +// indices inside eight 16-byte inputs, not copied word values. +// prettier-ignore +function P( + v00: number, v01: number, v02: number, v03: number, v04: number, v05: number, v06: number, v07: number, + v08: number, v09: number, v10: number, v11: number, v12: number, v13: number, v14: number, v15: number, +) { + // RFC 9106 Figure 18: first apply GB across rows, then across columns of the 8x8 register matrix. + G(v00, v04, v08, v12); + G(v01, v05, v09, v13); + G(v02, v06, v10, v14); + G(v03, v07, v11, v15); + G(v00, v05, v10, v15); + G(v01, v06, v11, v12); + G(v02, v07, v08, v13); + G(v03, v04, v09, v14); +} + +function block(x: TArg, xPos: number, yPos: number, outPos: number, needXor: boolean) { + for (let i = 0; i < 256; i++) A2_BUF[i] = x[xPos + i] ^ x[yPos + i]; + // rows (8 consecutive 16-register groups) + for (let i = 0; i < 128; i += 16) { + // prettier-ignore + P( + i, i + 1, i + 2, i + 3, i + 4, i + 5, i + 6, i + 7, + i + 8, i + 9, i + 10, i + 11, i + 12, i + 13, i + 14, i + 15 + ); + } + // columns (8 strided 16-register groups) + for (let i = 0; i < 16; i += 2) { + // prettier-ignore + P( + i, i + 1, i + 16, i + 17, i + 32, i + 33, i + 48, i + 49, + i + 64, i + 65, i + 80, i + 81, i + 96, i + 97, i + 112, i + 113 + ); + } + + // RFC 9106 step 6: passes after the first XOR the old destination block into the new G(X, Y). + if (needXor) for (let i = 0; i < 256; i++) x[outPos + i] ^= A2_BUF[i] ^ x[xPos + i] ^ x[yPos + i]; + else for (let i = 0; i < 256; i++) x[outPos + i] = A2_BUF[i] ^ x[xPos + i] ^ x[yPos + i]; + clean(A2_BUF); +} + +// Variable-Length Hash Function H' +// Returns bytes, not words; 1024-byte block callers explicitly reinterpret with `u32(...)`. +function Hp(A: TArg, dkLen: number): TRet { + const A8 = u8(A); + const T = new Uint32Array(1); + const T8 = u8(T); + // Argon2 H' prefixes dkLen as LE32; native Uint32Array writes would serialize as BE on s390x. + T[0] = swap8IfBE(dkLen); + // Fast path + if (dkLen <= 64) return blake2b.create({ dkLen }).update(T8).update(A8).digest(); + const out = new Uint8Array(dkLen); + let V = blake2b.create({}).update(T8).update(A8).digest(); + let pos = 0; + // RFC 9106 Figure 8: each intermediate `V_i` contributes only `W_i`, its first 32 bytes; only + // `V_{r+1}` is emitted in full at the remaining length. + out.set(V.subarray(0, 32)); + pos += 32; + // Rest blocks + for (; dkLen - pos > 64; pos += 32) { + const Vh = blake2b.create({}).update(V); + Vh.digestInto(V); + Vh.destroy(); + out.set(V.subarray(0, 32), pos); + } + // Last block + out.set(blake2b(V, { dkLen: dkLen - pos }), pos); + clean(V, T); + // H' is byte-oriented; returning `u32(out)` would silently drop dkLen % 4 tail bytes. + return out as TRet; +} + +// Used only inside process block! +function indexAlpha( + r: number, + s: number, + laneLen: number, + segmentLen: number, + index: number, + randL: number, + sameLane: boolean = false +) { + // RFC 9106 §3.4.2 Figures 12-13: map `J1` / `J2` into the current lane's reference area `W`. + let area: number; + if (r === 0) { + if (s === 0) area = index - 1; + else if (sameLane) area = s * segmentLen + index - 1; + else area = s * segmentLen + (index == 0 ? -1 : 0); + } else if (sameLane) area = laneLen - segmentLen + index - 1; + else area = laneLen - segmentLen + (index == 0 ? -1 : 0); + const startPos = r !== 0 && s !== ARGON2_SYNC_POINTS - 1 ? (s + 1) * segmentLen : 0; + // RFC 9106 Figure 13: `mul(randL, randL).h` is `floor(J_1^2 / 2^32)`, and the outer high-half + // multiply computes `floor(|W| * x / 2^32)` without floating-point math. + const rel = area - 1 - mul(area, mul(randL, randL).h).h; + return (startPos + rel) % laneLen; +} + +/** Argon2 cost, output, and optional secret/personalization inputs. */ +export type ArgonOpts = { + /** Time cost measured in iterations. */ + t: number; + /** Memory cost in kibibytes. */ + m: number; + /** Parallelization parameter. */ + p: number; + /** Argon2 version number. Defaults to `0x13`. */ + version?: number; + /** Optional secret key mixed into initialization. */ + key?: KDFInput; + /** Optional personalization string or bytes. */ + personalization?: KDFInput; + /** Desired output length in bytes. RFC 9106 §3.1 requires `T` in the 4..(2^32 - 1) range. */ + dkLen?: number; + /** Max scheduler block time in milliseconds for the async variants. */ + asyncTick?: number; + /** Maximum temporary memory budget in bytes. */ + maxmem?: number; + /** + * Optional progress callback invoked during long-running derivations. + * param progress - completion fraction in the `0..1` range + */ + onProgress?: (progress: number) => void; +}; + +// Exclusive `2^32` sentinel used by `isU32(...)`, not the inclusive maximum u32 value. +const maxUint32 = Math.pow(2, 32); +// Validate safe JS integers in `[0, 2^32 - 1]`. +function isU32(num: number) { + return Number.isSafeInteger(num) && num >= 0 && num < maxUint32; +} + +function argon2Opts(opts: TArg) { + const merged: any = { + version: 0x13, + dkLen: 32, + maxmem: maxUint32 - 1, + asyncTick: 10, + }; + // Unknown keys are copied through unchanged here and later ignored unless + // destructuring consumes them. + for (let [k, v] of Object.entries(opts)) if (v !== undefined) merged[k] = v; + + const { dkLen, p, m, t, version, onProgress, asyncTick } = merged; + // RFC 9106 §3.1: tag length `T` MUST be an integer number of bytes from 4 to 2^32-1. + if (!isU32(dkLen) || dkLen < 4) throw new Error('"dkLen" must be 4..'); + if (!isU32(p) || p < 1 || p >= Math.pow(2, 24)) throw new Error('"p" must be 1..2^24'); + if (!isU32(m)) throw new Error('"m" must be 0..2^32'); + if (!isU32(t) || t < 1) throw new Error('"t" (iterations) must be 1..2^32'); + if (onProgress !== undefined && typeof onProgress !== 'function') + throw new Error('"progressCb" must be a function'); + anumber(asyncTick, 'asyncTick'); + /* + Memory size m MUST be an integer number of kibibytes from 8*p + to 2^(32)-1. The actual number of blocks is m', which is m + rounded down to the nearest multiple of 4*p. + */ + if (!isU32(m) || m < 8 * p) throw new Error('"m" (memory) must be at least 8*p bytes'); + // Accept legacy `0x10` for compatibility even though RFC 9106 profiles standardize `0x13`. + if (version !== 0x10 && version !== 0x13) + throw new Error('"version" must be 0x10 or 0x13, got ' + version); + return merged; +} + +function argon2Init( + password: TArg, + salt: TArg, + type: Types, + opts: TArg +) { + password = kdfInputToBytes(password, 'password'); + salt = kdfInputToBytes(salt, 'salt'); + if (!isU32(password.length)) throw new Error('"password" must be less of length 1..4Gb'); + // RFC 9106 §3.1 only requires S <= 2^32-1 bytes and says 16 bytes is RECOMMENDED for password + // hashing; this library intentionally takes the stricter common >=8-byte salt path. + if (!isU32(salt.length) || salt.length < 8) throw new Error('"salt" must be of length 8..4Gb'); + if (!Object.values(AT).includes(type)) throw new Error('"type" was invalid'); + let { p, dkLen, m, t, version, key, personalization, maxmem, onProgress, asyncTick } = + argon2Opts(opts); + // Validation + key = abytesOrZero(key, 'key'); + personalization = abytesOrZero(personalization, 'personalization'); + // H_0 = H^(64)(LE32(p) || LE32(T) || LE32(m) || LE32(t) || + // LE32(v) || LE32(y) || LE32(length(P)) || P || + // LE32(length(S)) || S || LE32(length(K)) || K || + // LE32(length(X)) || X) + const h = blake2b.create(); + const BUF = new Uint32Array(1); + const BUF8 = u8(BUF); + for (let item of [p, dkLen, m, t, version, type]) { + // RFC 9106 H0 encodes these scalars as LE32, so normalize the host word before exposing bytes. + BUF[0] = swap8IfBE(item); + h.update(BUF8); + } + for (let i of [password, salt, key, personalization]) { + BUF[0] = swap8IfBE(i.length); // BUF is u32 array, this is valid once normalized to LE bytes + h.update(BUF8).update(i); + } + // Reserve two extra LE32 words after the 64-byte `H_0` so Figures 3-4 can append + // `LE32(0 or 1) || LE32(i)` in place for the lane-starting blocks. + const H0 = new Uint32Array(18); + const H0_8 = u8(H0); + h.digestInto(H0_8); + // 256 u32 = 1024 (BLOCK_SIZE), fills A2_BUF on processing + + // Params + const lanes = p; + // m' = 4 * p * floor (m / 4p) + const mP = 4 * p * Math.floor(m / (ARGON2_SYNC_POINTS * p)); + //q = m' / p columns + const laneLen = Math.floor(mP / p); + const segmentLen = Math.floor(laneLen / ARGON2_SYNC_POINTS); + // `maxmem` is documented in bytes; compare against the actual 1024-byte block allocation. + const memUsed = mP * 1024; + if (!isU32(maxmem)) throw new Error('"maxmem" expected <2**32, got ' + maxmem); + if (memUsed > maxmem) + throw new Error('"maxmem" limit was hit: memUsed(mP*1024)=' + memUsed + ', maxmem=' + maxmem); + const B = new Uint32Array(memUsed / 4); + // Fill first blocks + for (let l = 0; l < p; l++) { + const i = 256 * laneLen * l; + // B[i][0] = H'^(1024)(H_0 || LE32(0) || LE32(i)) + H0[17] = swap8IfBE(l); + H0[16] = swap8IfBE(0); + B.set(swap32IfBE(u32(Hp(H0, 1024))), i); + // B[i][1] = H'^(1024)(H_0 || LE32(1) || LE32(i)) + H0[16] = swap8IfBE(1); + B.set(swap32IfBE(u32(Hp(H0, 1024))), i + 256); + } + let perBlock = () => {}; + if (onProgress) { + // The first segment of the first pass skips two preinitialized blocks per lane. + const totalBlock = t * ARGON2_SYNC_POINTS * p * segmentLen - 2 * p; + // Invoke callback if progress changes from 10.01 to 10.02 + // Allows to draw smooth progress bar on up to 8K screen + const callbackPer = Math.max(Math.floor(totalBlock / 10000), 1); + let blockCnt = 0; + perBlock = () => { + blockCnt++; + if (onProgress && (!(blockCnt % callbackPer) || blockCnt === totalBlock)) + onProgress(blockCnt / totalBlock); + }; + } + clean(BUF, H0); + return { type, mP, p, t, version, B, laneLen, lanes, segmentLen, dkLen, perBlock, asyncTick }; +} + +function argon2Output( + B: TArg, + p: number, + laneLen: number, + dkLen: number +): TRet { + const B_final = new Uint32Array(256); + for (let l = 0; l < p; l++) + for (let j = 0; j < 256; j++) B_final[j] ^= B[256 * (laneLen * l + laneLen - 1) + j]; + // RFC 9106 steps 7-8 feed the byte string `C` into `H'^T(C)`, so normalize the xor'ed words + // back to spec byte order before `Hp(...)` reinterprets them as bytes. + const res = Hp(swap32IfBE(B_final), dkLen); + // Wipe both the xor scratch and the full working matrix once final digest bytes exist. + // JS cleanup is still only best-effort, but this local buffer is no longer needed here. + clean(B, B_final); + return res; +} + +function processBlock( + B: TArg, + address: TArg, + l: number, + r: number, + s: number, + index: number, + laneLen: number, + segmentLen: number, + lanes: number, + offset: number, + prev: number, + dataIndependent: boolean, + needXor: boolean +) { + if (offset % laneLen) prev = offset - 1; + let randL, randH; + if (dataIndependent) { + let i128 = index % 128; + // RFC 9106 §3.4.1.2: each 1024-byte address block yields 128 `(J1, J2)` pairs, so regenerate + // it whenever the segment index crosses a multiple of 128. + if (i128 === 0) { + address[256 + 12]++; + block(address, 256, 2 * 256, 0, false); + block(address, 0, 2 * 256, 0, false); + } + randL = address[2 * i128]; + randH = address[2 * i128 + 1]; + } else { + const T = 256 * prev; + randL = B[T]; + randH = B[T + 1]; + } + // Address-block path selects `J1` / `J2`, then maps them to the reference + // lane/block per RFC 9106 §3.4. + const refLane = r === 0 && s === 0 ? l : randH % lanes; + const refPos = indexAlpha(r, s, laneLen, segmentLen, index, randL, refLane == l); + const refBlock = laneLen * refLane + refPos; + // B[i][j] = G(B[i][j-1], B[l][z]) + block(B, 256 * prev, 256 * refBlock, offset * 256, needXor); +} + +function argon2( + type: Types, + password: TArg, + salt: TArg, + opts: TArg +): TRet { + const { mP, p, t, version, B, laneLen, lanes, segmentLen, dkLen, perBlock } = argon2Init( + password, + salt, + type, + opts + ); + // Pre-loop setup + // [address, input, zero_block] format so we can pass single U32 to block function + const address = new Uint32Array(3 * 256); + address[256 + 6] = mP; + address[256 + 8] = t; + address[256 + 10] = type; + for (let r = 0; r < t; r++) { + // RFC 9106 step 6 applies the XOR-on-later-passes rule only for version `0x13`; legacy + // `0x10` keeps the older overwrite behavior used by the v16 test vectors. + const needXor = r !== 0 && version === 0x13; + address[256 + 0] = r; + for (let s = 0; s < ARGON2_SYNC_POINTS; s++) { + address[256 + 4] = s; + // RFC 9106 §3.4.1.3: Argon2id uses Argon2i's data-independent `J1` / `J2` generation only + // in pass 0, slices 0 and 1; Argon2i uses it in every segment. + const dataIndependent = type == AT.Argon2i || (type == AT.Argon2id && r === 0 && s < 2); + for (let l = 0; l < p; l++) { + address[256 + 2] = l; + address[256 + 12] = 0; + let startPos = 0; + if (r === 0 && s === 0) { + startPos = 2; + if (dataIndependent) { + address[256 + 12]++; + block(address, 256, 2 * 256, 0, false); + block(address, 0, 2 * 256, 0, false); + } + } + // current block postion + let offset = l * laneLen + s * segmentLen + startPos; + // previous block position + let prev = offset % laneLen ? offset - 1 : offset + laneLen - 1; + for (let index = startPos; index < segmentLen; index++, offset++, prev++) { + perBlock(); + processBlock( + B, + address, + l, + r, + s, + index, + laneLen, + segmentLen, + lanes, + offset, + prev, + dataIndependent, + needXor + ); + } + } + } + } + clean(address); + return argon2Output(B, p, laneLen, dkLen); +} + +/** + * Argon2d GPU-resistant version. + * @param password - password or input key material + * @param salt - unique salt value + * @param opts - Argon2 cost and optional tuning parameters. See {@link ArgonOpts}. + * @returns Derived key bytes. + * @throws If the Argon2 input or cost parameters are invalid. {@link Error} + * @example + * Derive a key with Argon2d. + * ```ts + * argon2d('password', 'salt1234', { t: 1, m: 8, p: 1, dkLen: 32 }); + * ``` + */ +export const argon2d = ( + password: TArg, + salt: TArg, + opts: TArg +): TRet => argon2(AT.Argond2d, password, salt, opts); +/** + * Argon2i side-channel-resistant version. + * @param password - password or input key material + * @param salt - unique salt value + * @param opts - Argon2 cost and optional tuning parameters. See {@link ArgonOpts}. + * @returns Derived key bytes. + * @throws If the Argon2 input or cost parameters are invalid. {@link Error} + * @example + * Derive a key with Argon2i. + * ```ts + * argon2i('password', 'salt1234', { t: 1, m: 8, p: 1, dkLen: 32 }); + * ``` + */ +export const argon2i = ( + password: TArg, + salt: TArg, + opts: TArg +): TRet => argon2(AT.Argon2i, password, salt, opts); +/** + * Argon2id, combining i+d, the most popular version from RFC 9106. + * @param password - password or input key material + * @param salt - unique salt value + * @param opts - Argon2 cost and optional tuning parameters. See {@link ArgonOpts}. + * @returns Derived key bytes. + * @throws If the Argon2 input or cost parameters are invalid. {@link Error} + * @example + * Derive a key with Argon2id. + * ```ts + * argon2id('password', 'salt1234', { t: 1, m: 8, p: 1, dkLen: 32 }); + * ``` + */ +export const argon2id = ( + password: TArg, + salt: TArg, + opts: TArg +): TRet => argon2(AT.Argon2id, password, salt, opts); + +async function argon2Async( + type: Types, + password: TArg, + salt: TArg, + opts: TArg +): Promise> { + const { mP, p, t, version, B, laneLen, lanes, segmentLen, dkLen, perBlock, asyncTick } = + argon2Init(password, salt, type, opts); + // Pre-loop setup + // [address, input, zero_block] format so we can pass single U32 to block function + const address = new Uint32Array(3 * 256); + address[256 + 6] = mP; + address[256 + 8] = t; + address[256 + 10] = type; + let ts = Date.now(); + for (let r = 0; r < t; r++) { + // RFC 9106 step 6 applies the XOR-on-later-passes rule only for version `0x13`; legacy + // `0x10` keeps the older overwrite behavior used by the v16 test vectors. + const needXor = r !== 0 && version === 0x13; + address[256 + 0] = r; + for (let s = 0; s < ARGON2_SYNC_POINTS; s++) { + address[256 + 4] = s; + // RFC 9106 §3.4.1.3: Argon2id uses Argon2i's data-independent `J1` / `J2` generation only + // in pass 0, slices 0 and 1; Argon2i uses it in every segment. + const dataIndependent = type == AT.Argon2i || (type == AT.Argon2id && r === 0 && s < 2); + for (let l = 0; l < p; l++) { + address[256 + 2] = l; + address[256 + 12] = 0; + let startPos = 0; + if (r === 0 && s === 0) { + startPos = 2; + if (dataIndependent) { + address[256 + 12]++; + block(address, 256, 2 * 256, 0, false); + block(address, 0, 2 * 256, 0, false); + } + } + // current block postion + let offset = l * laneLen + s * segmentLen + startPos; + // previous block position + let prev = offset % laneLen ? offset - 1 : offset + laneLen - 1; + for (let index = startPos; index < segmentLen; index++, offset++, prev++) { + perBlock(); + processBlock( + B, + address, + l, + r, + s, + index, + laneLen, + segmentLen, + lanes, + offset, + prev, + dataIndependent, + needXor + ); + // Date.now() is not monotonic. If the clock goes backwards, + // still yield control. + const diff = Date.now() - ts; + if (!(diff >= 0 && diff < asyncTick)) { + await nextTick(); + ts += diff; + } + } + } + } + } + clean(address); + return argon2Output(B, p, laneLen, dkLen); +} + +/** + * Argon2d async GPU-resistant version. + * @param password - password or input key material + * @param salt - unique salt value + * @param opts - Argon2 cost and optional tuning parameters. See {@link ArgonOpts}. + * @returns Promise resolving to derived key bytes. + * @throws If the Argon2 input or cost parameters are invalid. {@link Error} + * @example + * Derive a key with Argon2d asynchronously. + * ```ts + * await argon2dAsync('password', 'salt1234', { t: 1, m: 8, p: 1, dkLen: 32 }); + * ``` + */ +export const argon2dAsync = ( + password: TArg, + salt: TArg, + opts: TArg +): Promise> => argon2Async(AT.Argond2d, password, salt, opts); +/** + * Argon2i async side-channel-resistant version. + * @param password - password or input key material + * @param salt - unique salt value + * @param opts - Argon2 cost and optional tuning parameters. See {@link ArgonOpts}. + * @returns Promise resolving to derived key bytes. + * @throws If the Argon2 input or cost parameters are invalid. {@link Error} + * @example + * Derive a key with Argon2i asynchronously. + * ```ts + * await argon2iAsync('password', 'salt1234', { t: 1, m: 8, p: 1, dkLen: 32 }); + * ``` + */ +export const argon2iAsync = ( + password: TArg, + salt: TArg, + opts: TArg +): Promise> => argon2Async(AT.Argon2i, password, salt, opts); +/** + * Argon2id async, combining i+d, the most popular version from RFC 9106. + * @param password - password or input key material + * @param salt - unique salt value + * @param opts - Argon2 cost and optional tuning parameters. See {@link ArgonOpts}. + * @returns Promise resolving to derived key bytes. + * @throws If the Argon2 input or cost parameters are invalid. {@link Error} + * @example + * Derive a key with Argon2id asynchronously. + * ```ts + * await argon2idAsync('password', 'salt1234', { t: 1, m: 8, p: 1, dkLen: 32 }); + * ``` + */ +export const argon2idAsync = ( + password: TArg, + salt: TArg, + opts: TArg +): Promise> => argon2Async(AT.Argon2id, password, salt, opts); diff --git a/node_modules/@noble/hashes/src/blake1.ts b/node_modules/@noble/hashes/src/blake1.ts new file mode 100644 index 0000000..72cb4f6 --- /dev/null +++ b/node_modules/@noble/hashes/src/blake1.ts @@ -0,0 +1,614 @@ +/** + * Blake1 legacy hash function, one of SHA3 proposals. + * Rarely used. Check out blake2 or blake3 instead. + * {@link https://www.aumasson.jp/blake/blake.pdf} + * + * In the best case, there are 0 allocations. + * + * Differences from blake2: + * + * - BE instead of LE + * - Paddings, similar to MD5, RIPEMD, SHA1, SHA2, but: + * - length flag is located before actual length + * - padding block is compressed differently (no lengths) + * Instead of msg[sigma[k]], we have `msg[sigma[k]] ^ constants[sigma[k-1]]` + * (-1 for g1, g2 without -1) + * - Salt is XOR-ed into constants instead of state + * - Salt is XOR-ed with output in `compress` + * - Additional rows (+64 bytes) in SIGMA for new rounds + * - Different round count: + * - 14 / 10 rounds in blake256 / blake2s + * - 16 / 12 rounds in blake512 / blake2b + * - blake512: G1b: rotr 24 -> 25, G2b: rotr 63 -> 11 + * @module + */ +import { BSIGMA, G1s, G2s } from './_blake.ts'; +import { SHA224_IV, SHA256_IV, SHA384_IV, SHA512_IV } from './_md.ts'; +import * as u64 from './_u64.ts'; +// prettier-ignore +import { + abytes, aexists, aoutput, + clean, createHasher, + createView, + type CHash, + type Hash, + type TArg, + type TRet +} from './utils.ts'; + +/** Blake1 options. Basically just `salt`. */ +export type BlakeOpts = { + /** Optional salt mixed into initialization. */ + salt?: Uint8Array; +}; + +// Shared unsalted sentinel, sized for the 64-bit path and reused by the 32-bit path via prefix. +const EMPTY_SALT = /* @__PURE__ */ new Uint32Array(8); + +// Base destroy logic only clears salt-derived state; the partial message buffer and length/position +// bookkeeping remain until the instance or backing buffer is reused. +abstract class BLAKE1> implements Hash { + readonly canXOF = false; + protected finished = false; + protected length = 0; + protected pos = 0; + protected destroyed = false; + // For partial updates less than block size + protected buffer: Uint8Array; + protected view: DataView; + protected salt: Uint32Array; + abstract compress(view: DataView, offset: number, withLength?: boolean): void; + protected abstract get(): number[]; + protected abstract set(...args: number[]): void; + + readonly blockLen: number; + readonly outputLen: number; + private lengthFlag: number; + private counterLen: number; + protected constants: Uint32Array; + + constructor( + blockLen: number, + outputLen: number, + lengthFlag: number, + counterLen: number, + saltLen: number, + constants: Uint32Array, + opts: BlakeOpts = {} + ) { + const { salt } = opts; + this.blockLen = blockLen; + this.outputLen = outputLen; + this.lengthFlag = lengthFlag; + this.counterLen = counterLen; + this.buffer = new Uint8Array(blockLen); + this.view = createView(this.buffer); + if (salt !== undefined) { + let slt = salt; + abytes(slt, 4 * saltLen, 'salt'); + // if (slt.length !== 4 * saltLen) throw new Error('wrong salt length'); + const salt32 = (this.salt = new Uint32Array(saltLen)); + const sv = createView(slt); + this.constants = constants.slice(); + for (let i = 0, offset = 0; i < salt32.length; i++, offset += 4) { + salt32[i] = sv.getUint32(offset, false); + this.constants[i] ^= salt32[i]; + } + } else { + this.salt = EMPTY_SALT; + this.constants = constants; + } + } + update(data: TArg): this { + aexists(this); + abytes(data); + // From _md, but update length before each compress + const { view, buffer, blockLen } = this; + const len = data.length; + let dataView; + for (let pos = 0; pos < len; ) { + const take = Math.min(blockLen - this.pos, len - pos); + // Fast path only when there is no buffered partial block: `take === blockLen` implies + // `this.pos === 0`, so we can process full blocks directly from the input view. + if (take === blockLen) { + if (!dataView) dataView = createView(data); + for (; blockLen <= len - pos; pos += blockLen) { + this.length += blockLen; + this.compress(dataView, pos); + } + continue; + } + buffer.set(data.subarray(pos, pos + take), this.pos); + this.pos += take; + pos += take; + if (this.pos === blockLen) { + this.length += blockLen; + this.compress(view, 0, true); + this.pos = 0; + } + } + return this; + } + destroy(): void { + this.destroyed = true; + if (this.salt !== EMPTY_SALT) { + clean(this.salt, this.constants); + } + } + _cloneInto(to?: T): T { + to ||= new (this.constructor as any)() as T; + to.set(...this.get()); + const { buffer, length, finished, destroyed, constants, salt, pos } = this; + to.buffer.set(buffer); + // Clone salt-derived arrays by value so destroying the clone cannot wipe the source instance. + to.constants = constants.slice(); + to.destroyed = destroyed; + to.finished = finished; + to.length = length; + to.pos = pos; + to.salt = salt.slice(); + return to; + } + clone(): T { + return this._cloneInto(); + } + digestInto(out: TArg): void { + aexists(this); + aoutput(out, this); + this.finished = true; + // Padding + const { buffer, blockLen, counterLen, lengthFlag, view } = this; + clean(buffer.subarray(this.pos)); // clean buf + const counter = BigInt((this.length + this.pos) * 8); + const counterPos = blockLen - counterLen - 1; + buffer[this.pos] |= 0b1000_0000; // End block flag + this.length += this.pos; // add unwritten length + // Not enough in buffer for length: write what we have. + if (this.pos > counterPos) { + this.compress(view, 0); + clean(buffer); + this.pos = 0; + } + // Difference with md: here we have lengthFlag! + buffer[counterPos] |= lengthFlag; // Length flag + // We always set 8 byte length flag. Because length will overflow significantly sooner. + view.setBigUint64(blockLen - 8, counter, false); + // Blake1 omits the counter from the extra all-padding block; only the block that still carries + // message bytes mixes in the final bit length. + this.compress(view, 0, this.pos !== 0); + // Write output + clean(buffer); + const v = createView(out); + const state = this.get(); + for (let i = 0; i < this.outputLen / 4; ++i) v.setUint32(i * 4, state[i]); + } + digest(): TRet { + const { buffer, outputLen } = this; + this.digestInto(buffer); + // Return a copy so callers do not alias the instance scratch buffer used during finalization. + const res = buffer.slice(0, outputLen); + this.destroy(); + return res as TRet; + } +} + +// Blake1-512 / Blake1-384 constant table `C512`. +// Stored as sixteen 64-bit constants split into `[high32, low32]` halves so +// the Blake1-64 path can reuse one layout for both `v8..v15` initialization +// and the permuted constant lookups. +const B64C = /* @__PURE__ */ Uint32Array.from([ + 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, + 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, + 0x9216d5d9, 0x8979fb1b, 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96, + 0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, +]); +// Blake1-256 / Blake1-224 constant table `C256`, derived as the first half of `C512`. +const B32C = /* @__PURE__ */ B64C.slice(0, 16); + +// Blake1-256 IV cloned from SHA-256. +const B256_IV = /* @__PURE__ */ SHA256_IV.slice(); +// Blake1-224 IV cloned from SHA-224. +const B224_IV = /* @__PURE__ */ SHA224_IV.slice(); +// Blake1-384 IV cloned from the SHA-384 high-then-low 32-bit halves. +const B384_IV = /* @__PURE__ */ SHA384_IV.slice(); +// Blake1-512 IV cloned from the SHA-512 high-then-low 32-bit halves. +const B512_IV = /* @__PURE__ */ SHA512_IV.slice(); + +// Precompute the odd/even companion constants used by all 14 Blake1-32 rounds. +// Each pair stores `u[sigma[2i + 1]]` then `u[sigma[2i]]`, matching the `G1s` / `G2s` xor order. +function generateTBL256() { + const TBL = []; + for (let i = 0, j = 0; i < 14; i++, j += 16) { + for (let offset = 1; offset < 16; offset += 2) { + TBL.push(B32C[BSIGMA[j + offset]]); + TBL.push(B32C[BSIGMA[j + offset - 1]]); + } + } + return new Uint32Array(TBL); +} +// Full 14-round companion-constant table for Blake1-32. +const TBL256 = /* @__PURE__ */ generateTBL256(); + +// Shared synchronous message-word scratch for the 32-bit Blake1 path. +const BLAKE256_W = /* @__PURE__ */ new Uint32Array(16); + +class BLAKE1_32B extends BLAKE1 { + private v0: number; + private v1: number; + private v2: number; + private v3: number; + private v4: number; + private v5: number; + private v6: number; + private v7: number; + constructor(outputLen: number, IV: Uint32Array, lengthFlag: number, opts: BlakeOpts = {}) { + super(64, outputLen, lengthFlag, 8, 4, B32C, opts); + this.v0 = IV[0] | 0; + this.v1 = IV[1] | 0; + this.v2 = IV[2] | 0; + this.v3 = IV[3] | 0; + this.v4 = IV[4] | 0; + this.v5 = IV[5] | 0; + this.v6 = IV[6] | 0; + this.v7 = IV[7] | 0; + } + protected get(): [number, number, number, number, number, number, number, number] { + const { v0, v1, v2, v3, v4, v5, v6, v7 } = this; + return [v0, v1, v2, v3, v4, v5, v6, v7]; + } + // prettier-ignore + protected set( + v0: number, v1: number, v2: number, v3: number, v4: number, v5: number, v6: number, v7: number + ): void { + this.v0 = v0 | 0; + this.v1 = v1 | 0; + this.v2 = v2 | 0; + this.v3 = v3 | 0; + this.v4 = v4 | 0; + this.v5 = v5 | 0; + this.v6 = v6 | 0; + this.v7 = v7 | 0; + } + destroy(): void { + super.destroy(); + this.set(0, 0, 0, 0, 0, 0, 0, 0); + } + compress(view: DataView, offset: number, withLength = true): void { + for (let i = 0; i < 16; i++, offset += 4) BLAKE256_W[i] = view.getUint32(offset, false); + // Cannot reuse blake2s compress: Blake1 mixes each message word with the companion constants + // precomputed in `TBL256`, rather than using the raw schedule words directly. + let v00 = this.v0 | 0; + let v01 = this.v1 | 0; + let v02 = this.v2 | 0; + let v03 = this.v3 | 0; + let v04 = this.v4 | 0; + let v05 = this.v5 | 0; + let v06 = this.v6 | 0; + let v07 = this.v7 | 0; + let v08 = this.constants[0] | 0; + let v09 = this.constants[1] | 0; + let v10 = this.constants[2] | 0; + let v11 = this.constants[3] | 0; + // Blake1-32 injects the 64-bit bit counter as `[t0, t0, t1, t1]` across `v12..v15`; the + // final all-padding block passes `withLength = false`, leaving these lanes as raw constants. + const { h, l } = u64.fromBig(BigInt(withLength ? this.length * 8 : 0)); + let v12 = (this.constants[4] ^ l) >>> 0; + let v13 = (this.constants[5] ^ l) >>> 0; + let v14 = (this.constants[6] ^ h) >>> 0; + let v15 = (this.constants[7] ^ h) >>> 0; + // prettier-ignore + for (let i = 0, k = 0, j = 0; i < 14; i++) { + ({ a: v00, b: v04, c: v08, d: v12 } = G1s(v00, v04, v08, v12, BLAKE256_W[BSIGMA[k++]] ^ TBL256[j++])); + ({ a: v00, b: v04, c: v08, d: v12 } = G2s(v00, v04, v08, v12, BLAKE256_W[BSIGMA[k++]] ^ TBL256[j++])); + ({ a: v01, b: v05, c: v09, d: v13 } = G1s(v01, v05, v09, v13, BLAKE256_W[BSIGMA[k++]] ^ TBL256[j++])); + ({ a: v01, b: v05, c: v09, d: v13 } = G2s(v01, v05, v09, v13, BLAKE256_W[BSIGMA[k++]] ^ TBL256[j++])); + ({ a: v02, b: v06, c: v10, d: v14 } = G1s(v02, v06, v10, v14, BLAKE256_W[BSIGMA[k++]] ^ TBL256[j++])); + ({ a: v02, b: v06, c: v10, d: v14 } = G2s(v02, v06, v10, v14, BLAKE256_W[BSIGMA[k++]] ^ TBL256[j++])); + ({ a: v03, b: v07, c: v11, d: v15 } = G1s(v03, v07, v11, v15, BLAKE256_W[BSIGMA[k++]] ^ TBL256[j++])); + ({ a: v03, b: v07, c: v11, d: v15 } = G2s(v03, v07, v11, v15, BLAKE256_W[BSIGMA[k++]] ^ TBL256[j++])); + ({ a: v00, b: v05, c: v10, d: v15 } = G1s(v00, v05, v10, v15, BLAKE256_W[BSIGMA[k++]] ^ TBL256[j++])); + ({ a: v00, b: v05, c: v10, d: v15 } = G2s(v00, v05, v10, v15, BLAKE256_W[BSIGMA[k++]] ^ TBL256[j++])); + ({ a: v01, b: v06, c: v11, d: v12 } = G1s(v01, v06, v11, v12, BLAKE256_W[BSIGMA[k++]] ^ TBL256[j++])); + ({ a: v01, b: v06, c: v11, d: v12 } = G2s(v01, v06, v11, v12, BLAKE256_W[BSIGMA[k++]] ^ TBL256[j++])); + ({ a: v02, b: v07, c: v08, d: v13 } = G1s(v02, v07, v08, v13, BLAKE256_W[BSIGMA[k++]] ^ TBL256[j++])); + ({ a: v02, b: v07, c: v08, d: v13 } = G2s(v02, v07, v08, v13, BLAKE256_W[BSIGMA[k++]] ^ TBL256[j++])); + ({ a: v03, b: v04, c: v09, d: v14 } = G1s(v03, v04, v09, v14, BLAKE256_W[BSIGMA[k++]] ^ TBL256[j++])); + ({ a: v03, b: v04, c: v09, d: v14 } = G2s(v03, v04, v09, v14, BLAKE256_W[BSIGMA[k++]] ^ TBL256[j++])); + } + this.v0 = (this.v0 ^ v00 ^ v08 ^ this.salt[0]) >>> 0; + this.v1 = (this.v1 ^ v01 ^ v09 ^ this.salt[1]) >>> 0; + this.v2 = (this.v2 ^ v02 ^ v10 ^ this.salt[2]) >>> 0; + this.v3 = (this.v3 ^ v03 ^ v11 ^ this.salt[3]) >>> 0; + this.v4 = (this.v4 ^ v04 ^ v12 ^ this.salt[0]) >>> 0; + this.v5 = (this.v5 ^ v05 ^ v13 ^ this.salt[1]) >>> 0; + this.v6 = (this.v6 ^ v06 ^ v14 ^ this.salt[2]) >>> 0; + this.v7 = (this.v7 ^ v07 ^ v15 ^ this.salt[3]) >>> 0; + clean(BLAKE256_W); + } +} + +// Shared Blake1-64 work vector storing 16 working words as adjacent high/low 32-bit halves. +const BBUF = /* @__PURE__ */ new Uint32Array(32); +// Shared synchronous message-word scratch for the 64-bit Blake1 path. +const BLAKE512_W = /* @__PURE__ */ new Uint32Array(32); + +// Precompute the high/low companion constants used by all 16 Blake1-64 rounds. +// Each quartet stores `u[sigma[2i + 1]]` high/low halves, then `u[sigma[2i]]` high/low halves. +function generateTBL512() { + const TBL = []; + for (let r = 0, k = 0; r < 16; r++, k += 16) { + for (let offset = 1; offset < 16; offset += 2) { + TBL.push(B64C[BSIGMA[k + offset] * 2 + 0]); + TBL.push(B64C[BSIGMA[k + offset] * 2 + 1]); + TBL.push(B64C[BSIGMA[k + offset - 1] * 2 + 0]); + TBL.push(B64C[BSIGMA[k + offset - 1] * 2 + 1]); + } + } + return new Uint32Array(TBL); +} +// Full 16-round companion-constant table as high/low halves. +const TBL512 = /* @__PURE__ */ generateTBL512(); + +// Blake1-64 first half-round with rotations `32` and `25`; `k` is the half-call schedule index. +function G1b(a: number, b: number, c: number, d: number, msg: TArg, k: number) { + const Xpos = 2 * BSIGMA[k]; + const Xl = msg[Xpos + 1] ^ TBL512[k * 2 + 1], Xh = msg[Xpos] ^ TBL512[k * 2]; // prettier-ignore + let Al = BBUF[2 * a + 1], Ah = BBUF[2 * a]; // prettier-ignore + let Bl = BBUF[2 * b + 1], Bh = BBUF[2 * b]; // prettier-ignore + let Cl = BBUF[2 * c + 1], Ch = BBUF[2 * c]; // prettier-ignore + let Dl = BBUF[2 * d + 1], Dh = BBUF[2 * d]; // prettier-ignore + // v[a] = (v[a] + v[b] + x) | 0; + let ll = u64.add3L(Al, Bl, Xl); + Ah = u64.add3H(ll, Ah, Bh, Xh) >>> 0; + Al = (ll | 0) >>> 0; + // v[d] = rotr(v[d] ^ v[a], 32) + ({ Dh, Dl } = { Dh: Dh ^ Ah, Dl: Dl ^ Al }); + ({ Dh, Dl } = { Dh: u64.rotr32H(Dh, Dl), Dl: u64.rotr32L(Dh, Dl) }); + // v[c] = (v[c] + v[d]) | 0; + ({ h: Ch, l: Cl } = u64.add(Ch, Cl, Dh, Dl)); + // v[b] = rotr(v[b] ^ v[c], 25) + ({ Bh, Bl } = { Bh: Bh ^ Ch, Bl: Bl ^ Cl }); + ({ Bh, Bl } = { Bh: u64.rotrSH(Bh, Bl, 25), Bl: u64.rotrSL(Bh, Bl, 25) }); + ((BBUF[2 * a + 1] = Al), (BBUF[2 * a] = Ah)); + ((BBUF[2 * b + 1] = Bl), (BBUF[2 * b] = Bh)); + ((BBUF[2 * c + 1] = Cl), (BBUF[2 * c] = Ch)); + ((BBUF[2 * d + 1] = Dl), (BBUF[2 * d] = Dh)); +} + +// Blake1-64 second half-round with rotations `16` and `11`; `k` is the half-call schedule index. +function G2b(a: number, b: number, c: number, d: number, msg: TArg, k: number) { + const Xpos = 2 * BSIGMA[k]; + const Xl = msg[Xpos + 1] ^ TBL512[k * 2 + 1], Xh = msg[Xpos] ^ TBL512[k * 2]; // prettier-ignore + let Al = BBUF[2 * a + 1], Ah = BBUF[2 * a]; // prettier-ignore + let Bl = BBUF[2 * b + 1], Bh = BBUF[2 * b]; // prettier-ignore + let Cl = BBUF[2 * c + 1], Ch = BBUF[2 * c]; // prettier-ignore + let Dl = BBUF[2 * d + 1], Dh = BBUF[2 * d]; // prettier-ignore + // v[a] = (v[a] + v[b] + x) | 0; + let ll = u64.add3L(Al, Bl, Xl); + Ah = u64.add3H(ll, Ah, Bh, Xh); + Al = ll | 0; + // v[d] = rotr(v[d] ^ v[a], 16) + ({ Dh, Dl } = { Dh: Dh ^ Ah, Dl: Dl ^ Al }); + ({ Dh, Dl } = { Dh: u64.rotrSH(Dh, Dl, 16), Dl: u64.rotrSL(Dh, Dl, 16) }); + // v[c] = (v[c] + v[d]) | 0; + ({ h: Ch, l: Cl } = u64.add(Ch, Cl, Dh, Dl)); + // v[b] = rotr(v[b] ^ v[c], 11) + ({ Bh, Bl } = { Bh: Bh ^ Ch, Bl: Bl ^ Cl }); + ({ Bh, Bl } = { Bh: u64.rotrSH(Bh, Bl, 11), Bl: u64.rotrSL(Bh, Bl, 11) }); + ((BBUF[2 * a + 1] = Al), (BBUF[2 * a] = Ah)); + ((BBUF[2 * b + 1] = Bl), (BBUF[2 * b] = Bh)); + ((BBUF[2 * c + 1] = Cl), (BBUF[2 * c] = Ch)); + ((BBUF[2 * d + 1] = Dl), (BBUF[2 * d] = Dh)); +} + +// Legacy field names keep the local `l/h` spelling, but array/state order stays `[high, low]` to +// match the IV tables and `BBUF` layout. +class BLAKE1_64B extends BLAKE1 { + private v0l: number; + private v0h: number; + private v1l: number; + private v1h: number; + private v2l: number; + private v2h: number; + private v3l: number; + private v3h: number; + private v4l: number; + private v4h: number; + private v5l: number; + private v5h: number; + private v6l: number; + private v6h: number; + private v7l: number; + private v7h: number; + constructor(outputLen: number, IV: Uint32Array, lengthFlag: number, opts: BlakeOpts = {}) { + super(128, outputLen, lengthFlag, 16, 8, B64C, opts); + this.v0l = IV[0] | 0; + this.v0h = IV[1] | 0; + this.v1l = IV[2] | 0; + this.v1h = IV[3] | 0; + this.v2l = IV[4] | 0; + this.v2h = IV[5] | 0; + this.v3l = IV[6] | 0; + this.v3h = IV[7] | 0; + this.v4l = IV[8] | 0; + this.v4h = IV[9] | 0; + this.v5l = IV[10] | 0; + this.v5h = IV[11] | 0; + this.v6l = IV[12] | 0; + this.v6h = IV[13] | 0; + this.v7l = IV[14] | 0; + this.v7h = IV[15] | 0; + } + // prettier-ignore + protected get(): [ + number, number, number, number, number, number, number, number, + number, number, number, number, number, number, number, number + ] { + let { v0l, v0h, v1l, v1h, v2l, v2h, v3l, v3h, v4l, v4h, v5l, v5h, v6l, v6h, v7l, v7h } = this; + return [v0l, v0h, v1l, v1h, v2l, v2h, v3l, v3h, v4l, v4h, v5l, v5h, v6l, v6h, v7l, v7h]; + } + // prettier-ignore + protected set( + v0l: number, v0h: number, v1l: number, v1h: number, + v2l: number, v2h: number, v3l: number, v3h: number, + v4l: number, v4h: number, v5l: number, v5h: number, + v6l: number, v6h: number, v7l: number, v7h: number + ): void { + this.v0l = v0l | 0; + this.v0h = v0h | 0; + this.v1l = v1l | 0; + this.v1h = v1h | 0; + this.v2l = v2l | 0; + this.v2h = v2h | 0; + this.v3l = v3l | 0; + this.v3h = v3h | 0; + this.v4l = v4l | 0; + this.v4h = v4h | 0; + this.v5l = v5l | 0; + this.v5h = v5h | 0; + this.v6l = v6l | 0; + this.v6h = v6h | 0; + this.v7l = v7l | 0; + this.v7h = v7h | 0; + } + destroy(): void { + super.destroy(); + this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + } + compress(view: DataView, offset: number, withLength = true): void { + for (let i = 0; i < 32; i++, offset += 4) BLAKE512_W[i] = view.getUint32(offset, false); + + this.get().forEach((v, i) => (BBUF[i] = v)); // First half from state. + BBUF.set(this.constants.subarray(0, 16), 16); + if (withLength) { + // Blake1-64 injects the 64-bit bit counter into `v12` and `v13`; the final all-padding + // block passes `withLength = false`, leaving the trailing constant lanes untouched. + const { h, l } = u64.fromBig(BigInt(this.length * 8)); + BBUF[24] = (BBUF[24] ^ h) >>> 0; + BBUF[25] = (BBUF[25] ^ l) >>> 0; + BBUF[26] = (BBUF[26] ^ h) >>> 0; + BBUF[27] = (BBUF[27] ^ l) >>> 0; + } + for (let i = 0, k = 0; i < 16; i++) { + G1b(0, 4, 8, 12, BLAKE512_W, k++); + G2b(0, 4, 8, 12, BLAKE512_W, k++); + G1b(1, 5, 9, 13, BLAKE512_W, k++); + G2b(1, 5, 9, 13, BLAKE512_W, k++); + G1b(2, 6, 10, 14, BLAKE512_W, k++); + G2b(2, 6, 10, 14, BLAKE512_W, k++); + G1b(3, 7, 11, 15, BLAKE512_W, k++); + G2b(3, 7, 11, 15, BLAKE512_W, k++); + + G1b(0, 5, 10, 15, BLAKE512_W, k++); + G2b(0, 5, 10, 15, BLAKE512_W, k++); + G1b(1, 6, 11, 12, BLAKE512_W, k++); + G2b(1, 6, 11, 12, BLAKE512_W, k++); + G1b(2, 7, 8, 13, BLAKE512_W, k++); + G2b(2, 7, 8, 13, BLAKE512_W, k++); + G1b(3, 4, 9, 14, BLAKE512_W, k++); + G2b(3, 4, 9, 14, BLAKE512_W, k++); + } + this.v0l ^= BBUF[0] ^ BBUF[16] ^ this.salt[0]; + this.v0h ^= BBUF[1] ^ BBUF[17] ^ this.salt[1]; + this.v1l ^= BBUF[2] ^ BBUF[18] ^ this.salt[2]; + this.v1h ^= BBUF[3] ^ BBUF[19] ^ this.salt[3]; + this.v2l ^= BBUF[4] ^ BBUF[20] ^ this.salt[4]; + this.v2h ^= BBUF[5] ^ BBUF[21] ^ this.salt[5]; + this.v3l ^= BBUF[6] ^ BBUF[22] ^ this.salt[6]; + this.v3h ^= BBUF[7] ^ BBUF[23] ^ this.salt[7]; + this.v4l ^= BBUF[8] ^ BBUF[24] ^ this.salt[0]; + this.v4h ^= BBUF[9] ^ BBUF[25] ^ this.salt[1]; + this.v5l ^= BBUF[10] ^ BBUF[26] ^ this.salt[2]; + this.v5h ^= BBUF[11] ^ BBUF[27] ^ this.salt[3]; + this.v6l ^= BBUF[12] ^ BBUF[28] ^ this.salt[4]; + this.v6h ^= BBUF[13] ^ BBUF[29] ^ this.salt[5]; + this.v7l ^= BBUF[14] ^ BBUF[30] ^ this.salt[6]; + this.v7h ^= BBUF[15] ^ BBUF[31] ^ this.salt[7]; + clean(BBUF, BLAKE512_W); + } +} + +/** Internal blake1-224 hash class. */ +export class _BLAKE224 extends BLAKE1_32B { + constructor(opts: BlakeOpts = {}) { + super(28, B224_IV, 0b0000_0000, opts); + } +} +/** Internal blake1-256 hash class. */ +export class _BLAKE256 extends BLAKE1_32B { + constructor(opts: BlakeOpts = {}) { + super(32, B256_IV, 0b0000_0001, opts); + } +} +/** Internal blake1-384 hash class. */ +export class _BLAKE384 extends BLAKE1_64B { + constructor(opts: BlakeOpts = {}) { + super(48, B384_IV, 0b0000_0000, opts); + } +} +/** Internal blake1-512 hash class. */ +export class _BLAKE512 extends BLAKE1_64B { + constructor(opts: BlakeOpts = {}) { + super(64, B512_IV, 0b0000_0001, opts); + } +} +/** + * Blake1-224 hash function. + * @param msg - message bytes to hash + * @param opts - Optional Blake1 settings. See {@link BlakeOpts}. If set, + * `opts.salt` must be exactly 16 bytes. + * @returns Digest bytes. + * @example + * Hash a message with Blake1-224. + * ```ts + * blake224(new Uint8Array([97, 98, 99])); + * ``` + */ +export const blake224: TRet> = /* @__PURE__ */ createHasher( + (opts) => new _BLAKE224(opts) +); +/** + * Blake1-256 hash function. + * @param msg - message bytes to hash + * @param opts - Optional Blake1 settings. See {@link BlakeOpts}. If set, + * `opts.salt` must be exactly 16 bytes. + * @returns Digest bytes. + * @example + * Hash a message with Blake1-256. + * ```ts + * blake256(new Uint8Array([97, 98, 99])); + * ``` + */ +export const blake256: TRet> = /* @__PURE__ */ createHasher( + (opts) => new _BLAKE256(opts) +); +/** + * Blake1-384 hash function. + * @param msg - message bytes to hash + * @param opts - Optional Blake1 settings. See {@link BlakeOpts}. If set, + * `opts.salt` must be exactly 32 bytes. + * @returns Digest bytes. + * @example + * Hash a message with Blake1-384. + * ```ts + * blake384(new Uint8Array([97, 98, 99])); + * ``` + */ +export const blake384: TRet> = /* @__PURE__ */ createHasher( + (opts) => new _BLAKE384(opts) +); +/** + * Blake1-512 hash function. + * @param msg - message bytes to hash + * @param opts - Optional Blake1 settings. See {@link BlakeOpts}. If set, + * `opts.salt` must be exactly 32 bytes. + * @returns Digest bytes. + * @example + * Hash a message with Blake1-512. + * ```ts + * blake512(new Uint8Array([97, 98, 99])); + * ``` + */ +export const blake512: TRet> = /* @__PURE__ */ createHasher( + (opts) => new _BLAKE512(opts) +); diff --git a/node_modules/@noble/hashes/src/blake2.ts b/node_modules/@noble/hashes/src/blake2.ts new file mode 100644 index 0000000..01f6046 --- /dev/null +++ b/node_modules/@noble/hashes/src/blake2.ts @@ -0,0 +1,582 @@ +/** + * blake2b (64-bit) & blake2s (8 to 32-bit) hash functions. + * b could have been faster, but there is no fast u64 in js, so s is 1.5x faster. + * @module + */ +import { BSIGMA, G1s, G2s } from './_blake.ts'; +import { SHA256_IV } from './_md.ts'; +import * as u64 from './_u64.ts'; +// prettier-ignore +import { + abytes, aexists, anumber, aoutput, + clean, createHasher, + swap32IfBE, swap8IfBE, + u32, + type CHash, + type Hash, + type TArg, + type TRet +} from './utils.ts'; + +/** + * Blake hash options. + * `dkLen` is output length. `key` is used in MAC mode. `salt` is used in + * KDF mode. + */ +export type Blake2Opts = { + /** Desired digest length in bytes. RFC 7693 uses 1..64 for blake2b and 1..32 for blake2s. */ + dkLen?: number; + /** Optional MAC key. */ + key?: Uint8Array; + /** Optional salt mixed into initialization. */ + salt?: Uint8Array; + /** Optional personalization bytes. */ + personalization?: Uint8Array; +}; + +// Same IV words as `SHA512_IV`, but endian-swapped into LE u32 low/high halves +// for the BLAKE2b u64 helpers below. +const B2B_IV = /* @__PURE__ */ Uint32Array.from([ + 0xf3bcc908, 0x6a09e667, 0x84caa73b, 0xbb67ae85, 0xfe94f82b, 0x3c6ef372, 0x5f1d36f1, 0xa54ff53a, + 0xade682d1, 0x510e527f, 0x2b3e6c1f, 0x9b05688c, 0xfb41bd6b, 0x1f83d9ab, 0x137e2179, 0x5be0cd19, +]); +// Shared synchronous BLAKE2b work vector as LE u32 low/high halves. +const BBUF = /* @__PURE__ */ new Uint32Array(32); + +// BLAKE2b G mix split into two half-rounds over LE u32 low/high limbs. +function G1b(a: number, b: number, c: number, d: number, msg: TArg, x: number) { + // NOTE: V is LE here + const Xl = msg[x], Xh = msg[x + 1]; // prettier-ignore + let Al = BBUF[2 * a], Ah = BBUF[2 * a + 1]; // prettier-ignore + let Bl = BBUF[2 * b], Bh = BBUF[2 * b + 1]; // prettier-ignore + let Cl = BBUF[2 * c], Ch = BBUF[2 * c + 1]; // prettier-ignore + let Dl = BBUF[2 * d], Dh = BBUF[2 * d + 1]; // prettier-ignore + // v[a] = (v[a] + v[b] + x) | 0; + let ll = u64.add3L(Al, Bl, Xl); + Ah = u64.add3H(ll, Ah, Bh, Xh); + Al = ll | 0; + // v[d] = rotr(v[d] ^ v[a], 32) + ({ Dh, Dl } = { Dh: Dh ^ Ah, Dl: Dl ^ Al }); + ({ Dh, Dl } = { Dh: u64.rotr32H(Dh, Dl), Dl: u64.rotr32L(Dh, Dl) }); + // v[c] = (v[c] + v[d]) | 0; + ({ h: Ch, l: Cl } = u64.add(Ch, Cl, Dh, Dl)); + // v[b] = rotr(v[b] ^ v[c], 24) + ({ Bh, Bl } = { Bh: Bh ^ Ch, Bl: Bl ^ Cl }); + ({ Bh, Bl } = { Bh: u64.rotrSH(Bh, Bl, 24), Bl: u64.rotrSL(Bh, Bl, 24) }); + ((BBUF[2 * a] = Al), (BBUF[2 * a + 1] = Ah)); + ((BBUF[2 * b] = Bl), (BBUF[2 * b + 1] = Bh)); + ((BBUF[2 * c] = Cl), (BBUF[2 * c + 1] = Ch)); + ((BBUF[2 * d] = Dl), (BBUF[2 * d + 1] = Dh)); +} + +// Second half-round of the same LE-limb BLAKE2b G mix; `x` is the message word offset. +function G2b(a: number, b: number, c: number, d: number, msg: TArg, x: number) { + // NOTE: V is LE here + const Xl = msg[x], Xh = msg[x + 1]; // prettier-ignore + let Al = BBUF[2 * a], Ah = BBUF[2 * a + 1]; // prettier-ignore + let Bl = BBUF[2 * b], Bh = BBUF[2 * b + 1]; // prettier-ignore + let Cl = BBUF[2 * c], Ch = BBUF[2 * c + 1]; // prettier-ignore + let Dl = BBUF[2 * d], Dh = BBUF[2 * d + 1]; // prettier-ignore + // v[a] = (v[a] + v[b] + x) | 0; + let ll = u64.add3L(Al, Bl, Xl); + Ah = u64.add3H(ll, Ah, Bh, Xh); + Al = ll | 0; + // v[d] = rotr(v[d] ^ v[a], 16) + ({ Dh, Dl } = { Dh: Dh ^ Ah, Dl: Dl ^ Al }); + ({ Dh, Dl } = { Dh: u64.rotrSH(Dh, Dl, 16), Dl: u64.rotrSL(Dh, Dl, 16) }); + // v[c] = (v[c] + v[d]) | 0; + ({ h: Ch, l: Cl } = u64.add(Ch, Cl, Dh, Dl)); + // v[b] = rotr(v[b] ^ v[c], 63) + ({ Bh, Bl } = { Bh: Bh ^ Ch, Bl: Bl ^ Cl }); + ({ Bh, Bl } = { Bh: u64.rotrBH(Bh, Bl, 63), Bl: u64.rotrBL(Bh, Bl, 63) }); + ((BBUF[2 * a] = Al), (BBUF[2 * a + 1] = Ah)); + ((BBUF[2 * b] = Bl), (BBUF[2 * b + 1] = Bh)); + ((BBUF[2 * c] = Cl), (BBUF[2 * c + 1] = Ch)); + ((BBUF[2 * d] = Dl), (BBUF[2 * d + 1] = Dh)); +} + +function checkBlake2Opts( + outputLen: number, + opts: TArg = {}, + keyLen: number, + saltLen: number, + persLen: number +) { + anumber(keyLen); + // RFC 7693 §2.1 requires digest length nn in 1..keyLen. + if (outputLen <= 0 || outputLen > keyLen) throw new Error('outputLen bigger than keyLen'); + const { key, salt, personalization } = opts; + // This API uses `undefined` for the RFC 7693 `kk = 0` case, so a provided key must be non-empty. + if (key !== undefined && (key.length < 1 || key.length > keyLen)) + throw new Error('"key" expected to be undefined or of length=1..' + keyLen); + if (salt !== undefined) abytes(salt, saltLen, 'salt'); + if (personalization !== undefined) abytes(personalization, persLen, 'personalization'); +} + +/** Internal base class for BLAKE2. */ +export abstract class _BLAKE2> implements Hash { + protected abstract compress(msg: Uint32Array, offset: number, isLast: boolean): void; + protected abstract get(): number[]; + protected abstract set(...args: number[]): void; + abstract destroy(): void; + protected buffer: Uint8Array; + protected buffer32: Uint32Array; + protected finished = false; + protected destroyed = false; + protected length: number = 0; + protected pos: number = 0; + readonly blockLen: number; + readonly outputLen: number; + readonly canXOF: boolean = false; + + constructor(blockLen: number, outputLen: number) { + anumber(blockLen); + anumber(outputLen); + this.blockLen = blockLen; + this.outputLen = outputLen; + this.buffer = new Uint8Array(blockLen); + this.buffer32 = u32(this.buffer); + } + update(data: TArg): this { + aexists(this); + abytes(data); + // Main difference with other hashes: there is flag for last block, + // so we cannot process current block before we know that there + // is the next one. This significantly complicates logic and reduces ability + // to do zero-copy processing + const { blockLen, buffer, buffer32 } = this; + const len = data.length; + const offset = data.byteOffset; + const buf = data.buffer; + for (let pos = 0; pos < len; ) { + // If buffer is full and we still have input (don't process last block, same as blake2s) + if (this.pos === blockLen) { + swap32IfBE(buffer32); + this.compress(buffer32, 0, false); + swap32IfBE(buffer32); + this.pos = 0; + } + const take = Math.min(blockLen - this.pos, len - pos); + const dataOffset = offset + pos; + // Zero-copy only for full, 4-byte-aligned, non-final blocks. + if (take === blockLen && !(dataOffset % 4) && pos + take < len) { + const data32 = new Uint32Array(buf, dataOffset, Math.floor((len - pos) / 4)); + swap32IfBE(data32); + for (let pos32 = 0; pos + blockLen < len; pos32 += buffer32.length, pos += blockLen) { + this.length += blockLen; + this.compress(data32, pos32, false); + } + swap32IfBE(data32); + continue; + } + buffer.set(data.subarray(pos, pos + take), this.pos); + this.pos += take; + this.length += take; + pos += take; + } + return this; + } + digestInto(out: TArg): void { + aexists(this); + aoutput(out, this); + const { pos, buffer32 } = this; + this.finished = true; + // Padding + clean(this.buffer.subarray(pos)); + swap32IfBE(buffer32); + this.compress(buffer32, 0, true); + swap32IfBE(buffer32); + // Reject unaligned views explicitly instead of hiding them behind a full scratch copy. + if (out.byteOffset & 3) + throw new RangeError( + '"digestInto() output" expected 4-byte aligned byteOffset, got ' + out.byteOffset + ); + const state = this.get(); + const out32 = u32(out); + const full = Math.floor(this.outputLen / 4); + for (let i = 0; i < full; i++) out32[i] = swap8IfBE(state[i]); + const tail = this.outputLen % 4; + if (!tail) return; + const off = full * 4; + const word = state[full]; + for (let i = 0; i < tail; i++) out[off + i] = word >>> (8 * i); + } + digest(): TRet { + const { buffer, outputLen } = this; + this.digestInto(buffer); + // Return a copy so callers do not alias the instance scratch buffer used during finalization. + const res = buffer.slice(0, outputLen); + this.destroy(); + return res as TRet; + } + _cloneInto(to?: T): T { + const { buffer, length, finished, destroyed, outputLen, pos } = this; + // Recreate only `dkLen`; key/salt/personalization are already absorbed into the copied state. + to ||= new (this.constructor as any)({ dkLen: outputLen }) as T; + to.set(...this.get()); + to.buffer.set(buffer); + to.destroyed = destroyed; + to.finished = finished; + to.length = length; + to.pos = pos; + // @ts-ignore + to.outputLen = outputLen; + return to; + } + clone(): T { + return this._cloneInto(); + } +} + +/** Internal blake2b hash class with state stored as LE u32 low/high halves. */ +export class _BLAKE2b extends _BLAKE2<_BLAKE2b> { + // Same IV words as SHA-512 / BLAKE2b, encoded as LE u32 low/high halves. + private v0l = B2B_IV[0] | 0; + private v0h = B2B_IV[1] | 0; + private v1l = B2B_IV[2] | 0; + private v1h = B2B_IV[3] | 0; + private v2l = B2B_IV[4] | 0; + private v2h = B2B_IV[5] | 0; + private v3l = B2B_IV[6] | 0; + private v3h = B2B_IV[7] | 0; + private v4l = B2B_IV[8] | 0; + private v4h = B2B_IV[9] | 0; + private v5l = B2B_IV[10] | 0; + private v5h = B2B_IV[11] | 0; + private v6l = B2B_IV[12] | 0; + private v6h = B2B_IV[13] | 0; + private v7l = B2B_IV[14] | 0; + private v7h = B2B_IV[15] | 0; + + constructor(opts: Blake2Opts = {}) { + const olen = opts.dkLen === undefined ? 64 : opts.dkLen; + super(128, olen); + checkBlake2Opts(olen, opts, 64, 16, 16); + let { key, personalization, salt } = opts; + let keyLength = 0; + if (key !== undefined) { + abytes(key, undefined, 'key'); + keyLength = key.length; + } + // RFC 7693 §2.5: xor `p[0] = 0x0101kknn` into the low 32 bits of `h[0]`; + // the high 32 bits stay at `IV[0]`. + this.v0l ^= this.outputLen | (keyLength << 8) | (0x01 << 16) | (0x01 << 24); + if (salt !== undefined) { + abytes(salt, undefined, 'salt'); + const slt = u32(salt); + this.v4l ^= swap8IfBE(slt[0]); + this.v4h ^= swap8IfBE(slt[1]); + this.v5l ^= swap8IfBE(slt[2]); + this.v5h ^= swap8IfBE(slt[3]); + } + if (personalization !== undefined) { + abytes(personalization, undefined, 'personalization'); + const pers = u32(personalization); + this.v6l ^= swap8IfBE(pers[0]); + this.v6h ^= swap8IfBE(pers[1]); + this.v7l ^= swap8IfBE(pers[2]); + this.v7h ^= swap8IfBE(pers[3]); + } + if (key !== undefined) { + // Pad to blockLen and update + const tmp = new Uint8Array(this.blockLen); + tmp.set(key); + this.update(tmp); + } + } + // prettier-ignore + protected get(): [ + number, number, number, number, number, number, number, number, + number, number, number, number, number, number, number, number + ] { + let { v0l, v0h, v1l, v1h, v2l, v2h, v3l, v3h, v4l, v4h, v5l, v5h, v6l, v6h, v7l, v7h } = this; + return [v0l, v0h, v1l, v1h, v2l, v2h, v3l, v3h, v4l, v4h, v5l, v5h, v6l, v6h, v7l, v7h]; + } + // prettier-ignore + protected set( + v0l: number, v0h: number, v1l: number, v1h: number, + v2l: number, v2h: number, v3l: number, v3h: number, + v4l: number, v4h: number, v5l: number, v5h: number, + v6l: number, v6h: number, v7l: number, v7h: number + ): void { + this.v0l = v0l | 0; + this.v0h = v0h | 0; + this.v1l = v1l | 0; + this.v1h = v1h | 0; + this.v2l = v2l | 0; + this.v2h = v2h | 0; + this.v3l = v3l | 0; + this.v3h = v3h | 0; + this.v4l = v4l | 0; + this.v4h = v4h | 0; + this.v5l = v5l | 0; + this.v5h = v5h | 0; + this.v6l = v6l | 0; + this.v6h = v6h | 0; + this.v7l = v7l | 0; + this.v7h = v7h | 0; + } + protected compress(msg: Uint32Array, offset: number, isLast: boolean): void { + this.get().forEach((v, i) => (BBUF[i] = v)); // First half from state. + BBUF.set(B2B_IV, 16); // Second half from IV. + let { h, l } = u64.fromBig(BigInt(this.length)); + BBUF[24] = B2B_IV[8] ^ l; // Low word of the offset. + BBUF[25] = B2B_IV[9] ^ h; // High word. + // Invert all bits for last block + if (isLast) { + BBUF[28] = ~BBUF[28]; + BBUF[29] = ~BBUF[29]; + } + let j = 0; + const s = BSIGMA; + // SIGMA selects 64-bit message words; multiply by 2 because `msg` stores + // each word as [low32, high32]. + for (let i = 0; i < 12; i++) { + G1b(0, 4, 8, 12, msg, offset + 2 * s[j++]); + G2b(0, 4, 8, 12, msg, offset + 2 * s[j++]); + G1b(1, 5, 9, 13, msg, offset + 2 * s[j++]); + G2b(1, 5, 9, 13, msg, offset + 2 * s[j++]); + G1b(2, 6, 10, 14, msg, offset + 2 * s[j++]); + G2b(2, 6, 10, 14, msg, offset + 2 * s[j++]); + G1b(3, 7, 11, 15, msg, offset + 2 * s[j++]); + G2b(3, 7, 11, 15, msg, offset + 2 * s[j++]); + + G1b(0, 5, 10, 15, msg, offset + 2 * s[j++]); + G2b(0, 5, 10, 15, msg, offset + 2 * s[j++]); + G1b(1, 6, 11, 12, msg, offset + 2 * s[j++]); + G2b(1, 6, 11, 12, msg, offset + 2 * s[j++]); + G1b(2, 7, 8, 13, msg, offset + 2 * s[j++]); + G2b(2, 7, 8, 13, msg, offset + 2 * s[j++]); + G1b(3, 4, 9, 14, msg, offset + 2 * s[j++]); + G2b(3, 4, 9, 14, msg, offset + 2 * s[j++]); + } + this.v0l ^= BBUF[0] ^ BBUF[16]; + this.v0h ^= BBUF[1] ^ BBUF[17]; + this.v1l ^= BBUF[2] ^ BBUF[18]; + this.v1h ^= BBUF[3] ^ BBUF[19]; + this.v2l ^= BBUF[4] ^ BBUF[20]; + this.v2h ^= BBUF[5] ^ BBUF[21]; + this.v3l ^= BBUF[6] ^ BBUF[22]; + this.v3h ^= BBUF[7] ^ BBUF[23]; + this.v4l ^= BBUF[8] ^ BBUF[24]; + this.v4h ^= BBUF[9] ^ BBUF[25]; + this.v5l ^= BBUF[10] ^ BBUF[26]; + this.v5h ^= BBUF[11] ^ BBUF[27]; + this.v6l ^= BBUF[12] ^ BBUF[28]; + this.v6h ^= BBUF[13] ^ BBUF[29]; + this.v7l ^= BBUF[14] ^ BBUF[30]; + this.v7h ^= BBUF[15] ^ BBUF[31]; + clean(BBUF); + } + destroy(): void { + this.destroyed = true; + clean(this.buffer32); + this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + } +} + +/** + * Blake2b hash function. 64-bit. 1.5x slower than blake2s in JS. + * @param msg - message that would be hashed + * @param opts - Optional output, MAC, salt, and personalization settings. + * `dkLen` must be 1..64 bytes; `salt` and `personalization`, if present, + * must be 16 bytes each. See {@link Blake2Opts}. + * @returns Digest bytes. + * @example + * Hash a message with Blake2b. + * ```ts + * blake2b(new Uint8Array([97, 98, 99])); + * ``` + */ +export const blake2b: TRet> = /* @__PURE__ */ createHasher( + (opts) => new _BLAKE2b(opts) +); + +// ================= +// Blake2S +// ================= + +/** Internal type, 16 numbers. */ +// prettier-ignore +export type _Num16 = { + v0: number; v1: number; v2: number; v3: number; + v4: number; v5: number; v6: number; v7: number; + v8: number; v9: number; v10: number; v11: number; + v12: number; v13: number; v14: number; v15: number; +}; + +/** + * BLAKE2-compress core method. + * Runs only the round function over a caller-supplied local vector; callers initialize `v0..v15` + * and apply the final `h[i] ^= v[i] ^ v[i + 8]` fold themselves. + * @param s - flattened sigma schedule bytes + * @param offset - starting word offset inside `msg`, not a byte offset + * @param msg - message words + * @param rounds - round count to execute + * @param v0 - state word 0 + * @param v1 - state word 1 + * @param v2 - state word 2 + * @param v3 - state word 3 + * @param v4 - state word 4 + * @param v5 - state word 5 + * @param v6 - state word 6 + * @param v7 - state word 7 + * @param v8 - state word 8 + * @param v9 - state word 9 + * @param v10 - state word 10 + * @param v11 - state word 11 + * @param v12 - state word 12 + * @param v13 - state word 13 + * @param v14 - state word 14 + * @param v15 - state word 15 + * @returns Updated compression state words. + * @example + * Run the BLAKE2 compression core on zeroed state and message words. + * ```ts + * import { compress } from '@noble/hashes/blake2.js'; + * const state = compress( + * new Uint8Array(16), + * 0, + * new Uint32Array(16), + * 1, + * 0, 0, 0, 0, 0, 0, 0, 0, + * 0, 0, 0, 0, 0, 0, 0, 0 + * ); + * state.v0; + * ``` + */ +// prettier-ignore +export function compress(s: TArg, offset: number, msg: TArg, rounds: number, + v0: number, v1: number, v2: number, v3: number, v4: number, v5: number, v6: number, v7: number, + v8: number, v9: number, v10: number, v11: number, v12: number, v13: number, v14: number, v15: number, +): _Num16 { + let j = 0; + for (let i = 0; i < rounds; i++) { + ({ a: v0, b: v4, c: v8, d: v12 } = G1s(v0, v4, v8, v12, msg[offset + s[j++]])); + ({ a: v0, b: v4, c: v8, d: v12 } = G2s(v0, v4, v8, v12, msg[offset + s[j++]])); + ({ a: v1, b: v5, c: v9, d: v13 } = G1s(v1, v5, v9, v13, msg[offset + s[j++]])); + ({ a: v1, b: v5, c: v9, d: v13 } = G2s(v1, v5, v9, v13, msg[offset + s[j++]])); + ({ a: v2, b: v6, c: v10, d: v14 } = G1s(v2, v6, v10, v14, msg[offset + s[j++]])); + ({ a: v2, b: v6, c: v10, d: v14 } = G2s(v2, v6, v10, v14, msg[offset + s[j++]])); + ({ a: v3, b: v7, c: v11, d: v15 } = G1s(v3, v7, v11, v15, msg[offset + s[j++]])); + ({ a: v3, b: v7, c: v11, d: v15 } = G2s(v3, v7, v11, v15, msg[offset + s[j++]])); + + ({ a: v0, b: v5, c: v10, d: v15 } = G1s(v0, v5, v10, v15, msg[offset + s[j++]])); + ({ a: v0, b: v5, c: v10, d: v15 } = G2s(v0, v5, v10, v15, msg[offset + s[j++]])); + ({ a: v1, b: v6, c: v11, d: v12 } = G1s(v1, v6, v11, v12, msg[offset + s[j++]])); + ({ a: v1, b: v6, c: v11, d: v12 } = G2s(v1, v6, v11, v12, msg[offset + s[j++]])); + ({ a: v2, b: v7, c: v8, d: v13 } = G1s(v2, v7, v8, v13, msg[offset + s[j++]])); + ({ a: v2, b: v7, c: v8, d: v13 } = G2s(v2, v7, v8, v13, msg[offset + s[j++]])); + ({ a: v3, b: v4, c: v9, d: v14 } = G1s(v3, v4, v9, v14, msg[offset + s[j++]])); + ({ a: v3, b: v4, c: v9, d: v14 } = G2s(v3, v4, v9, v14, msg[offset + s[j++]])); + } + return { v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 }; +} + +// Blake2s reuses the SHA-256 IV words as-is. +const B2S_IV = /* @__PURE__ */ SHA256_IV.slice(); + +/** Internal blake2s hash class. */ +export class _BLAKE2s extends _BLAKE2<_BLAKE2s> { + // Internal state, same as SHA-256 + private v0 = B2S_IV[0] | 0; + private v1 = B2S_IV[1] | 0; + private v2 = B2S_IV[2] | 0; + private v3 = B2S_IV[3] | 0; + private v4 = B2S_IV[4] | 0; + private v5 = B2S_IV[5] | 0; + private v6 = B2S_IV[6] | 0; + private v7 = B2S_IV[7] | 0; + + constructor(opts: Blake2Opts = {}) { + const olen = opts.dkLen === undefined ? 32 : opts.dkLen; + super(64, olen); + checkBlake2Opts(olen, opts, 32, 8, 8); + let { key, personalization, salt } = opts; + let keyLength = 0; + if (key !== undefined) { + abytes(key, undefined, 'key'); + keyLength = key.length; + } + // RFC 7693 §2.5: xor `p[0] = 0x0101kknn` directly into `h[0]`, since + // BLAKE2s stores each state word as one `u32`. + this.v0 ^= this.outputLen | (keyLength << 8) | (0x01 << 16) | (0x01 << 24); + if (salt !== undefined) { + abytes(salt, undefined, 'salt'); + const slt = u32(salt as Uint8Array); + this.v4 ^= swap8IfBE(slt[0]); + this.v5 ^= swap8IfBE(slt[1]); + } + if (personalization !== undefined) { + abytes(personalization, undefined, 'personalization'); + const pers = u32(personalization as Uint8Array); + this.v6 ^= swap8IfBE(pers[0]); + this.v7 ^= swap8IfBE(pers[1]); + } + if (key !== undefined) { + // Pad to blockLen and update + const tmp = new Uint8Array(this.blockLen); + tmp.set(key); + this.update(tmp); + } + } + protected get(): [number, number, number, number, number, number, number, number] { + const { v0, v1, v2, v3, v4, v5, v6, v7 } = this; + return [v0, v1, v2, v3, v4, v5, v6, v7]; + } + // prettier-ignore + protected set( + v0: number, v1: number, v2: number, v3: number, v4: number, v5: number, v6: number, v7: number + ): void { + this.v0 = v0 | 0; + this.v1 = v1 | 0; + this.v2 = v2 | 0; + this.v3 = v3 | 0; + this.v4 = v4 | 0; + this.v5 = v5 | 0; + this.v6 = v6 | 0; + this.v7 = v7 | 0; + } + protected compress(msg: Uint32Array, offset: number, isLast: boolean): void { + const { h, l } = u64.fromBig(BigInt(this.length)); + // Seed v8..v15 from the IV, xor the low/high 32-bit byte counter into + // v12/v13, and invert v14 on the final block. + // prettier-ignore + const { v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 } = + compress( + BSIGMA, offset, msg, 10, + this.v0, this.v1, this.v2, this.v3, this.v4, this.v5, this.v6, this.v7, + B2S_IV[0], B2S_IV[1], B2S_IV[2], B2S_IV[3], l ^ B2S_IV[4], h ^ B2S_IV[5], isLast ? ~B2S_IV[6] : B2S_IV[6], B2S_IV[7] + ); + this.v0 ^= v0 ^ v8; + this.v1 ^= v1 ^ v9; + this.v2 ^= v2 ^ v10; + this.v3 ^= v3 ^ v11; + this.v4 ^= v4 ^ v12; + this.v5 ^= v5 ^ v13; + this.v6 ^= v6 ^ v14; + this.v7 ^= v7 ^ v15; + } + destroy(): void { + this.destroyed = true; + clean(this.buffer32); + this.set(0, 0, 0, 0, 0, 0, 0, 0); + } +} + +/** + * Blake2s hash function. Focuses on 8-bit to 32-bit platforms. 1.5x faster than blake2b in JS. + * @param msg - message that would be hashed + * @param opts - Optional output, MAC, salt, and personalization settings. + * `dkLen` must be 1..32 bytes; `salt` and `personalization`, if present, + * must be 8 bytes each. See {@link Blake2Opts}. + * @returns Digest bytes. + * @example + * Hash a message with Blake2s. + * ```ts + * blake2s(new Uint8Array([97, 98, 99])); + * ``` + */ +export const blake2s: TRet> = /* @__PURE__ */ createHasher( + (opts) => new _BLAKE2s(opts) +); diff --git a/node_modules/@noble/hashes/src/blake3.ts b/node_modules/@noble/hashes/src/blake3.ts new file mode 100644 index 0000000..bb96a5a --- /dev/null +++ b/node_modules/@noble/hashes/src/blake3.ts @@ -0,0 +1,317 @@ +/** + * Blake3 fast hash is Blake2 with reduced security (round count). Can also be used as MAC & KDF. + * + * It is advertised as "the fastest cryptographic hash". However, it isn't true in JS. + * Why is this so slow? While it must be 6x faster than blake2b, perf diff is only 20%: + * + * * There is only 30% reduction in number of rounds from blake2s + * * Speed-up comes from tree structure, which is parallelized using SIMD & threading. + * These features are not present in JS, so we only get overhead from trees. + * * Parallelization only happens on 1024-byte chunks: there is no benefit for small inputs. + * * It is still possible to make it faster using: a) loop unrolling b) web workers c) wasm + * @module + */ +import { SHA256_IV } from './_md.ts'; +import { fromBig } from './_u64.ts'; +import { _BLAKE2, compress } from './blake2.ts'; +// prettier-ignore +import { + abytes, aexists, anumber, aoutput, + clean, + copyBytes, + createHasher, swap32IfBE, + u32, u8, + type CHashXOF, + type HashXOF, + type TArg, + type TRet +} from './utils.ts'; + +// Constructor-time mode flags (`KEYED_HASH`, `DERIVE_*`) plus per-node tree +// flags (`CHUNK_*`, `PARENT`, `ROOT`). +const B3_Flags = { + CHUNK_START: 0b1, + CHUNK_END: 0b10, + PARENT: 0b100, + ROOT: 0b1000, + KEYED_HASH: 0b10000, + DERIVE_KEY_CONTEXT: 0b100000, + DERIVE_KEY_MATERIAL: 0b1000000, +} as const; + +// Default BLAKE3 IV, cloned from the shared BLAKE2s / SHA-256 IV basis. +const B3_IV = /* @__PURE__ */ SHA256_IV.slice(); + +// Seven 16-word rounds of BLAKE3 message schedule, generated by repeatedly +// permuting the identity row. +const B3_SIGMA: TRet = /* @__PURE__ */ (() => { + const Id = Array.from({ length: 16 }, (_, i) => i); + const permute = (arr: number[]) => + [2, 6, 3, 10, 7, 0, 4, 13, 1, 11, 12, 5, 9, 14, 15, 8].map((i) => arr[i]); + const res: number[] = []; + for (let i = 0, v = Id; i < 7; i++, v = permute(v)) res.push(...v); + return Uint8Array.from(res); +})(); + +/** + * Ensure to use EITHER `key` OR `context`, not both. + * + * * `key`: 32-byte MAC key. + * * `context`: caller-encoded KDF context bytes. If your protocol defines a + * string context, encode it before passing it here. + * A good default format for the original context string is + * "[application] [commit timestamp] [purpose]". + */ +export type Blake3Opts = { + /** Desired digest length in bytes. The BLAKE3 spec allows 0..2^64-1 bytes of output. */ + dkLen?: number; + /** Optional 32-byte MAC key. */ + key?: Uint8Array; + /** Optional KDF context bytes. */ + context?: Uint8Array; +}; + +/** Blake3 hash. Can be used as MAC and KDF with caller-encoded context bytes. */ +export class _BLAKE3 extends _BLAKE2<_BLAKE3> implements HashXOF<_BLAKE3> { + readonly canXOF = true; + private chunkPos = 0; // Position of current block in chunk + // How many chunks we already have; exact while this stays within + // JS's safe-integer range. + private chunksDone = 0; + private flags = 0 | 0; + private IV: Uint32Array; + private state: Uint32Array; + private stack: Uint32Array[] = []; + // Output + private posOut = 0; + private bufferOut32 = new Uint32Array(16); + private bufferOut: Uint8Array; + // Index of output chunk; exact while this stays within JS's + // safe-integer range. + private chunkOut = 0; + private enableXOF = true; + + constructor(opts: Blake3Opts = {}, flags = 0) { + super(64, opts.dkLen === undefined ? 32 : opts.dkLen); + const { key, context } = opts; + const hasContext = context !== undefined; + if (key !== undefined) { + if (hasContext) throw new Error('Only "key" or "context" can be specified at same time'); + abytes(key, 32, 'key'); + const k = copyBytes(key); + this.IV = u32(k); + swap32IfBE(this.IV); + this.flags = flags | B3_Flags.KEYED_HASH; + } else if (hasContext) { + abytes(context, undefined, 'context'); + const ctx = context; + const contextKey = new _BLAKE3({ dkLen: 32 }, B3_Flags.DERIVE_KEY_CONTEXT) + .update(ctx) + .digest(); + this.IV = u32(contextKey); + swap32IfBE(this.IV); + this.flags = flags | B3_Flags.DERIVE_KEY_MATERIAL; + } else { + this.IV = B3_IV.slice(); + this.flags = flags; + } + this.state = this.IV.slice(); + this.bufferOut = u8(this.bufferOut32); + } + // _BLAKE2's scalar-state hooks are unused here: BLAKE3 keeps its tree/XOF state in arrays and + // copies it directly in _cloneInto(). + protected get(): [] { + return []; + } + protected set(): void {} + // Truncated chunk/parent compression: seed v8..v15 as IV[0..3], t0, t1, + // block length, and flags, then keep only the first 8 output words. + private b2Compress(counter: number, flags: number, buf: Uint32Array, bufPos: number = 0) { + const { state: s, pos } = this; + const { h, l } = fromBig(BigInt(counter), true); + // prettier-ignore + const { v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 } = + compress( + B3_SIGMA, bufPos, buf, 7, + s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], + B3_IV[0], B3_IV[1], B3_IV[2], B3_IV[3], h, l, pos, flags + ); + s[0] = v0 ^ v8; + s[1] = v1 ^ v9; + s[2] = v2 ^ v10; + s[3] = v3 ^ v11; + s[4] = v4 ^ v12; + s[5] = v5 ^ v13; + s[6] = v6 ^ v14; + s[7] = v7 ^ v15; + } + protected compress(buf: Uint32Array, bufPos: number = 0, isLast: boolean = false): void { + // Compress last block + let flags = this.flags; + if (!this.chunkPos) flags |= B3_Flags.CHUNK_START; + if (this.chunkPos === 15 || isLast) flags |= B3_Flags.CHUNK_END; + if (!isLast) this.pos = this.blockLen; + this.b2Compress(this.chunksDone, flags, buf, bufPos); + this.chunkPos += 1; + // If current block is last in chunk (16 blocks), then compress chunks + if (this.chunkPos === 16 || isLast) { + let chunk = this.state; + this.state = this.IV.slice(); + // If not the last one, compress only when there are trailing zeros in chunk counter + // Chunks are used as a binary tree where the current stack is the path. + // Zero means the current leaf is finished and can be compressed. + // 1 (001) - leaf not finished (just push current chunk to stack) + // 2 (010) - leaf finished at depth=1 (merge with last elm on stack and push back) + // 3 (011) - last leaf not finished + // 4 (100) - leafs finished at depth=1 and depth=2 + for (let last, chunks = this.chunksDone + 1; isLast || !(chunks & 1); chunks >>= 1) { + if (!(last = this.stack.pop())) break; + this.buffer32.set(last, 0); + this.buffer32.set(chunk, 8); + this.pos = this.blockLen; + this.b2Compress(0, this.flags | B3_Flags.PARENT, this.buffer32, 0); + chunk = this.state; + this.state = this.IV.slice(); + } + this.chunksDone++; + this.chunkPos = 0; + this.stack.push(chunk); + } + this.pos = 0; + } + _cloneInto(to?: _BLAKE3): _BLAKE3 { + to = super._cloneInto(to) as _BLAKE3; + const { IV, flags, state, chunkPos, posOut, chunkOut, stack, chunksDone } = this; + to.state.set(state.slice()); + // Clone each CV stack entry by value so extending or destroying the clone + // cannot alias the source tree state. + to.stack = stack.map((i) => Uint32Array.from(i)); + to.IV.set(IV); + to.flags = flags; + to.chunkPos = chunkPos; + to.chunksDone = chunksDone; + to.posOut = posOut; + to.chunkOut = chunkOut; + to.enableXOF = this.enableXOF; + to.bufferOut32.set(this.bufferOut32); + return to; + } + destroy(): void { + this.destroyed = true; + clean(this.state, this.buffer32, this.IV, this.bufferOut32); + clean(...this.stack); + } + // Root/XOF compression: rerun the same ROOT inputs with incrementing output + // counter `t` and materialize all 16 output words. + // Same as b2Compress, but doesn't modify state and returns 16 u32 array (instead of 8) + private b2CompressOut() { + const { state: s, pos, flags, buffer32, bufferOut32: out32 } = this; + const { h, l } = fromBig(BigInt(this.chunkOut++)); + swap32IfBE(buffer32); + // prettier-ignore + const { v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 } = + compress( + B3_SIGMA, 0, buffer32, 7, + s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], + B3_IV[0], B3_IV[1], B3_IV[2], B3_IV[3], l, h, pos, flags + ); + out32[0] = v0 ^ v8; + out32[1] = v1 ^ v9; + out32[2] = v2 ^ v10; + out32[3] = v3 ^ v11; + out32[4] = v4 ^ v12; + out32[5] = v5 ^ v13; + out32[6] = v6 ^ v14; + out32[7] = v7 ^ v15; + out32[8] = s[0] ^ v8; + out32[9] = s[1] ^ v9; + out32[10] = s[2] ^ v10; + out32[11] = s[3] ^ v11; + out32[12] = s[4] ^ v12; + out32[13] = s[5] ^ v13; + out32[14] = s[6] ^ v14; + out32[15] = s[7] ^ v15; + swap32IfBE(buffer32); + swap32IfBE(out32); + this.posOut = 0; + } + protected finish(): void { + if (this.finished) return; + this.finished = true; + // Padding + clean(this.buffer.subarray(this.pos)); + // Process last chunk + let flags = this.flags | B3_Flags.ROOT; + if (this.stack.length) { + // Finalize the current chunk first, then rerun the last parent + // compression as ROOT with t = 0 and b = 64. + flags |= B3_Flags.PARENT; + swap32IfBE(this.buffer32); + this.compress(this.buffer32, 0, true); + swap32IfBE(this.buffer32); + this.chunksDone = 0; + this.pos = this.blockLen; + } else { + flags |= (!this.chunkPos ? B3_Flags.CHUNK_START : 0) | B3_Flags.CHUNK_END; + } + this.flags = flags; + this.b2CompressOut(); + } + private writeInto(out: TArg): TRet { + aexists(this, false); + abytes(out); + this.finish(); + const { blockLen, bufferOut } = this; + for (let pos = 0, len = out.length; pos < len; ) { + if (this.posOut >= blockLen) this.b2CompressOut(); + const take = Math.min(blockLen - this.posOut, len - pos); + out.set(bufferOut.subarray(this.posOut, this.posOut + take), pos); + this.posOut += take; + pos += take; + } + return out as TRet; + } + xofInto(out: TArg): TRet { + if (!this.enableXOF) throw new Error('XOF is not possible after digest call'); + return this.writeInto(out); + } + xof(bytes: number): TRet { + anumber(bytes); + return this.xofInto(new Uint8Array(bytes)); + } + digestInto(out: TArg): void { + aoutput(out, this); + if (this.finished) throw new Error('digest() was already called'); + this.enableXOF = false; + // `aoutput(...)` allows oversized buffers; digestInto() must fill only the configured digest. + this.writeInto(out.subarray(0, this.outputLen)); + this.destroy(); + } + digest(): TRet { + const out = new Uint8Array(this.outputLen); + this.digestInto(out); + return out as TRet; + } +} + +/** + * BLAKE3 hash function. Can be used as MAC and KDF. + * @param msg - message that would be hashed + * @param opts - Optional output, MAC, or KDF configuration. `key` must be + * exactly 32 bytes, `context` is caller-encoded bytes, and `dkLen` can be + * 0..2^64-1 via the XOF-backed output path. See {@link Blake3Opts}. + * @returns Digest bytes. + * @example + * Hash, MAC, or derive key material with BLAKE3. + * ```ts + * import { blake3 } from '@noble/hashes/blake3.js'; + * import { utf8ToBytes } from '@noble/hashes/utils.js'; + * const data = new Uint8Array(32); + * const hash = blake3(data); + * const mac = blake3(data, { key: new Uint8Array(32) }); + * const kdf = blake3(data, { context: utf8ToBytes('application name') }); + * ``` + */ +export const blake3: TRet> = /* @__PURE__ */ createHasher( + (opts = {}) => new _BLAKE3(opts) +); diff --git a/node_modules/@noble/hashes/src/eskdf.ts b/node_modules/@noble/hashes/src/eskdf.ts new file mode 100644 index 0000000..08d50cd --- /dev/null +++ b/node_modules/@noble/hashes/src/eskdf.ts @@ -0,0 +1,259 @@ +/** + * Experimental KDF for AES. + * @module + */ +import { hkdf } from './hkdf.ts'; +import { pbkdf2 as _pbkdf2 } from './pbkdf2.ts'; +import { scrypt as _scrypt } from './scrypt.ts'; +import { sha256 } from './sha2.ts'; +import { + abytes, + bytesToHex, + clean, + createView, + hexToBytes, + kdfInputToBytes, + type TArg, + type TRet, +} from './utils.ts'; + +// A tiny KDF for various applications like AES key-gen. +// Uses HKDF in a non-standard way, so it's not "KDF-secure", only "PRF-secure". +// Which is good enough: assume sha2-256 retained preimage resistance. + +// Fixed ESKDF scrypt work factor: interactive-latency target with about 512 MiB RAM per derivation. +const SCRYPT_FACTOR = /* @__PURE__ */ (() => 2 ** 19)(); +// Fixed ESKDF PBKDF2 work factor: CPU-only companion branch in the same rough +// interactive-latency range. +const PBKDF2_FACTOR = /* @__PURE__ */ (() => 2 ** 17)(); + +/** + * Scrypt KDF with the fixed ESKDF policy tuple `{ N: 2^19, r: 8, p: 1, dkLen: 32 }`. + * @param password - user password string, UTF-8 encoded before entering RFC 7914 + * @param salt - unique salt string, UTF-8 encoded before entering RFC 7914 + * @returns Derived 32-byte key. + * @example + * Derive the 32-byte scrypt key used by ESKDF. + * ```ts + * scrypt('password123', 'user@example.com'); + * ``` + */ +export function scrypt(password: string, salt: string): TRet { + return _scrypt(password, salt, { N: SCRYPT_FACTOR, r: 8, p: 1, dkLen: 32 }); +} + +/** + * PBKDF2-HMAC-SHA256 with the fixed ESKDF policy tuple `{ sha256, c: 2^17, dkLen: 32 }`. + * @param password - user password string, UTF-8 encoded before entering PBKDF2-HMAC-SHA-256 + * @param salt - unique salt string, UTF-8 encoded before entering PBKDF2-HMAC-SHA-256 + * @returns Derived 32-byte key. + * @example + * Derive the 32-byte PBKDF2 key used by ESKDF. + * ```ts + * pbkdf2('password123', 'user@example.com'); + * ``` + */ +export function pbkdf2(password: string, salt: string): TRet { + return _pbkdf2(sha256, password, salt, { c: PBKDF2_FACTOR, dkLen: 32 }); +} + +// Combines two 32-byte byte arrays into a fresh 32-byte result without aliasing either input. +function xor32(a: TArg, b: TArg): TRet { + abytes(a, 32); + abytes(b, 32); + const arr = new Uint8Array(32); + for (let i = 0; i < 32; i++) { + arr[i] = a[i] ^ b[i]; + } + return arr as TRet; +} + +// All local string length checks are in JS UTF-16 code units, not UTF-8 bytes. +function strHasLength(str: string, min: number, max: number): boolean { + return typeof str === 'string' && str.length >= min && str.length <= max; +} + +/** + * Derives main seed. Takes a lot of time; prefer the higher-level `eskdf(...)` + * flow unless you specifically need the raw main seed. + * Derives the main seed by xor'ing two branches: + * the scrypt branch uses a `0x01` separator byte on username/password, + * and the PBKDF2 branch uses `0x02`. + * Username and password strings are encoded by the underlying KDFs after the + * local separator bytes are appended. + * @param username - account identifier used as public salt + * @param password - user password string + * @returns Main 32-byte seed for the account. + * @throws If the username or password length is invalid. {@link Error} + * @example + * Derive the main ESKDF seed from username and password. + * ```ts + * deriveMainSeed('example-user', 'example-password'); + * ``` + */ +export function deriveMainSeed(username: string, password: string): TRet { + if (!strHasLength(username, 8, 255)) throw new Error('invalid username'); + if (!strHasLength(password, 8, 255)) throw new Error('invalid password'); + // Keep the protocol separators as the literal bytes 0x01 / 0x02 even after minification. + // Embedding them as non-printable characters directly can be awkward across + // JS tooling and environments. + const codes = { _1: 1, _2: 2 }; + const sep = { s: String.fromCharCode(codes._1), p: String.fromCharCode(codes._2) }; + const scr = scrypt(password + sep.s, username + sep.s); + const pbk = pbkdf2(password + sep.p, username + sep.p); + const res = xor32(scr, pbk); + clean(scr, pbk); + return res; +} + +type AccountID = number | string; + +/** + * Converts protocol & accountId pair to HKDF params: + * `info` is UTF-8 protocol bytes, numeric ids become 4-byte BE `salt`, + * and string ids become UTF-8 `salt` bytes. + */ +function getSaltInfo(protocol: string, accountId: AccountID = 0) { + // Note that length here also repeats two lines below + // We do an additional length check here to reduce the scope of DoS attacks + if (!(strHasLength(protocol, 3, 15) && /^[a-z0-9]{3,15}$/.test(protocol))) { + throw new Error('invalid protocol'); + } + + // Exact-match only: substring matches like `assh` / `mentor` must not widen the public whitelist. + const allowsStr = /^(password\d{0,3}|ssh|tor|file)$/.test(protocol); + let salt: Uint8Array; // Assigned below: either 4-byte BE account bytes or UTF-8 account bytes. + if (typeof accountId === 'string') { + if (!allowsStr) throw new Error('accountId must be a number'); + if (!strHasLength(accountId, 1, 255)) + throw new Error('accountId must be string of length 1..255'); + salt = kdfInputToBytes(accountId); + } else if (Number.isSafeInteger(accountId)) { + if (accountId < 0 || accountId > Math.pow(2, 32) - 1) throw new Error('invalid accountId'); + // Convert to Big Endian Uint32 + salt = new Uint8Array(4); + createView(salt).setUint32(0, accountId, false); + } else { + throw new Error('accountId must be a number' + (allowsStr ? ' or string' : '')); + } + const info = kdfInputToBytes(protocol); + return { salt, info }; +} + +type OptsLength = { keyLength: number }; +type OptsMod = { modulus: bigint }; +type KeyOpts = undefined | OptsLength | OptsMod; + +// Local modulus-size helper, not a general bigint-byte-length primitive: +// `<= 128n` is rejected by ESKDF policy. +function countBytes(num: bigint): number { + if (typeof num !== 'bigint' || num <= BigInt(128)) throw new Error('invalid number'); + return Math.ceil(num.toString(2).length / 8); +} + +/** + * Parses keyLength and modulus options to extract length of result key. + * If modulus is used, adds 64 bits to it per the FIPS 186-5 Appendix A.3.1 / + * A.4.1 extra-bits guidance. + */ +function getKeyLength(options: KeyOpts): number { + if (!options || typeof options !== 'object') return 32; + const hasLen = 'keyLength' in options; + const hasMod = 'modulus' in options; + if (hasLen && hasMod) throw new Error('cannot combine keyLength and modulus options'); + if (!hasLen && !hasMod) throw new Error('must have either keyLength or modulus option'); + // FIPS 186-5 Appendix A.3.1 / A.4.1 calls for at least 64 extra bits. + const l = hasMod ? countBytes(options.modulus) + 8 : options.keyLength; + if (!(typeof l === 'number' && l >= 16 && l <= 8192)) throw new Error('invalid keyLength'); + return l; +} + +/** + * Converts key to bigint and divides it by modulus. Big Endian. + * Adapts FIPS 186-5 Appendix A.4.1: `getKeyLength()` already requested the + * extra 64-bit margin, and this step maps the result into `1..modulus-1`. + */ +function modReduceKey(key: TArg, modulus: bigint): TRet { + const _1 = BigInt(1); + const num = BigInt('0x' + bytesToHex(key)); // check for ui8a, then bytesToNumber() + const res = (num % (modulus - _1)) + _1; // Remove 0 from output + if (res < _1) throw new Error('expected positive number'); // Guard against bad values + // Strip the extra 64-bit margin that `getKeyLength()` requested + // for bias reduction. + const len = key.length - 8; + const hex = res.toString(16).padStart(len * 2, '0'); // numberToHex() + const bytes = hexToBytes(hex); + if (bytes.length !== len) throw new Error('invalid length of result key'); + return bytes; +} + +/** Not using classes because constructor cannot be async. */ +export interface ESKDF { + /** + * Derives a child key. Child key will not be associated with any + * other child key because of properties of underlying KDF. + * + * @param protocol - 3-15 character protocol name + * @param accountId - numeric account identifier, or a string id for + * `password\d{0,3}`, `ssh`, `tor`, or `file` + * @param options - Optional child-key shaping parameters. See {@link KeyOpts}. + * @returns Derived child key bytes. + */ + deriveChildKey: (protocol: string, accountId: AccountID, options?: KeyOpts) => TRet; + /** Deletes the main seed from the ESKDF instance. */ + expire: () => void; + /** + * Human-readable fingerprint: first 6 bytes of + * `deriveChildKey('fingerprint', 0)`, formatted as uppercase + * colon-separated hex. + */ + fingerprint: string; +} + +/** + * ESKDF + * @param username - username, email, or identifier, min: 8 characters, should have enough entropy + * @param password - password, min: 8 characters, should have enough entropy + * @returns Frozen API that derives child keys and exposes the account fingerprint. + * @throws If the username or password length is invalid. {@link Error} + * @example + * Derive account-specific child keys from the main ESKDF seed. + * ```ts + * const kdf = await eskdf('example-university', 'beginning-new-example'); + * const key = kdf.deriveChildKey('aes', 0); + * const fingerprint = kdf.fingerprint; + * kdf.expire(); + * ``` + */ +export async function eskdf(username: string, password: string): Promise> { + // We are using closure + object instead of class because + // we want to make `seed` non-accessible for any external function. + let seed: Uint8Array | undefined = deriveMainSeed(username, password); + + function deriveCK( + protocol: string, + accountId: AccountID = 0, + options?: KeyOpts + ): TRet { + // Reject expired instances before deriving any HKDF inputs from the closure-held seed. + abytes(seed!, 32); + const { salt, info } = getSaltInfo(protocol, accountId); // validate protocol & accountId + // Validate option shape and coarse length bounds; + // `hkdf()` still rejects non-integer lengths. + const keyLength = getKeyLength(options); + const key = hkdf(sha256, seed!, salt, info, keyLength); + // Modulus has already been validated + return options && 'modulus' in options ? modReduceKey(key, options.modulus) : key; + } + function expire() { + // Overwrite the closure-held seed before dropping the reference. + if (seed) seed.fill(1); + seed = undefined; + } + // prettier-ignore + const fingerprint = Array.from(deriveCK('fingerprint', 0)) + .slice(0, 6) + .map((char) => char.toString(16).padStart(2, '0').toUpperCase()) + .join(':'); + return Object.freeze({ deriveChildKey: deriveCK, expire, fingerprint }); +} diff --git a/node_modules/@noble/hashes/src/hkdf.ts b/node_modules/@noble/hashes/src/hkdf.ts new file mode 100644 index 0000000..1adbc7e --- /dev/null +++ b/node_modules/@noble/hashes/src/hkdf.ts @@ -0,0 +1,133 @@ +/** + * HKDF (RFC 5869): extract + expand in one step. + * See {@link https://soatok.blog/2021/11/17/understanding-hkdf/}. + * @module + */ +import { hmac } from './hmac.ts'; +import { abytes, ahash, anumber, type CHash, clean, type TArg, type TRet } from './utils.ts'; + +/** + * HKDF-extract from spec. Less important part. `HKDF-Extract(IKM, salt) -> PRK` + * Arguments position differs from spec (IKM is first one, since it is not optional) + * Local validation only checks `hash`; `ikm` / `salt` byte validation is delegated to `hmac()`. + * @param hash - hash function that would be used (e.g. sha256) + * @param ikm - input keying material, the initial key + * @param salt - optional salt value (a non-secret random value) + * @returns Pseudorandom key derived from input keying material. + * @example + * Run the HKDF extract step. + * ```ts + * import { extract } from '@noble/hashes/hkdf.js'; + * import { sha256 } from '@noble/hashes/sha2.js'; + * extract(sha256, new Uint8Array([1, 2, 3]), new Uint8Array([4, 5, 6])); + * ``` + */ +export function extract( + hash: TArg, + ikm: TArg, + salt?: TArg +): TRet { + ahash(hash); + // NOTE: some libraries treat zero-length array as 'not provided'; + // we don't, since we have undefined as 'not provided' + // https://github.com/RustCrypto/KDFs/issues/15 + if (salt === undefined) salt = new Uint8Array(hash.outputLen); + return hmac(hash, salt, ikm); +} + +// Shared mutable scratch byte for the RFC 5869 block counter `N`. +// Safe to reuse because `expand()` is synchronous and resets it with `clean(...)` before returning. +const HKDF_COUNTER = /* @__PURE__ */ Uint8Array.of(0); +// Shared RFC 5869 empty string for both `info === undefined` and the first-block `T(0)` input. +const EMPTY_BUFFER = /* @__PURE__ */ Uint8Array.of(); + +/** + * HKDF-expand from the spec. The most important part. `HKDF-Expand(PRK, info, L) -> OKM` + * @param hash - hash function that would be used (e.g. sha256) + * @param prk - a pseudorandom key of at least HashLen octets + * (usually, the output from the extract step) + * @param info - optional context and application specific information (can be a zero-length string) + * @param length - length of output keying material in bytes. + * RFC 5869 §2.3 allows `0..255*HashLen`, so `0` returns an empty OKM. + * @returns Output keying material with the requested length. + * @throws If the requested output length exceeds the HKDF limit + * for the selected hash. {@link Error} + * @example + * Run the HKDF expand step. + * ```ts + * import { expand } from '@noble/hashes/hkdf.js'; + * import { sha256 } from '@noble/hashes/sha2.js'; + * expand(sha256, new Uint8Array(32), new Uint8Array([1, 2, 3]), 16); + * ``` + */ +export function expand( + hash: TArg, + prk: TArg, + info?: TArg, + length: number = 32 +): TRet { + ahash(hash); + anumber(length, 'length'); + abytes(prk, undefined, 'prk'); + const olen = hash.outputLen; + // RFC 5869 §2.3: PRK is "a pseudorandom key of at least HashLen octets". + if (prk.length < olen) throw new Error('"prk" must be at least HashLen octets'); + // RFC 5869 §2.3 only bounds `L` by `<= 255*HashLen`; `L=0` is valid and yields empty OKM. + if (length > 255 * olen) throw new Error('Length must be <= 255*HashLen'); + const blocks = Math.ceil(length / olen); + if (info === undefined) info = EMPTY_BUFFER; + else abytes(info, undefined, 'info'); + // first L(ength) octets of T + const okm = new Uint8Array(blocks * olen); + // Re-use HMAC instance between blocks + const HMAC = hmac.create(hash, prk); + const HMACTmp = HMAC._cloneInto(); + const T = new Uint8Array(HMAC.outputLen); + for (let counter = 0; counter < blocks; counter++) { + HKDF_COUNTER[0] = counter + 1; + // T(0) = empty string (zero length) + // T(N) = HMAC-Hash(PRK, T(N-1) | info | N) + HMACTmp.update(counter === 0 ? EMPTY_BUFFER : T) + .update(info) + .update(HKDF_COUNTER) + .digestInto(T); + okm.set(T, olen * counter); + HMAC._cloneInto(HMACTmp); + } + HMAC.destroy(); + HMACTmp.destroy(); + clean(T, HKDF_COUNTER); + return okm.slice(0, length) as TRet; +} + +/** + * HKDF (RFC 5869): derive keys from an initial input. + * Combines hkdf_extract + hkdf_expand in one step + * @param hash - hash function that would be used (e.g. sha256) + * @param ikm - input keying material, the initial key + * @param salt - optional salt value (a non-secret random value) + * @param info - optional context and application specific information bytes + * @param length - length of output keying material in bytes. + * RFC 5869 §2.3 allows `0..255*HashLen`, so `0` returns an empty OKM. + * @returns Output keying material derived from the input key. + * @throws If the requested output length exceeds the HKDF limit + * for the selected hash. {@link Error} + * @example + * HKDF (RFC 5869): derive keys from an initial input. + * ```ts + * import { hkdf } from '@noble/hashes/hkdf.js'; + * import { sha256 } from '@noble/hashes/sha2.js'; + * import { randomBytes, utf8ToBytes } from '@noble/hashes/utils.js'; + * const inputKey = randomBytes(32); + * const salt = randomBytes(32); + * const info = utf8ToBytes('application-key'); + * const okm = hkdf(sha256, inputKey, salt, info, 32); + * ``` + */ +export const hkdf = ( + hash: TArg, + ikm: TArg, + salt: TArg, + info: TArg, + length: number +): TRet => expand(hash, extract(hash, ikm, salt), info, length); diff --git a/node_modules/@noble/hashes/src/hmac.ts b/node_modules/@noble/hashes/src/hmac.ts new file mode 100644 index 0000000..b914ebf --- /dev/null +++ b/node_modules/@noble/hashes/src/hmac.ts @@ -0,0 +1,126 @@ +/** + * HMAC: RFC2104 message authentication code. + * @module + */ +import { + abytes, + aexists, + ahash, + aoutput, + clean, + type CHash, + type Hash, + type TArg, + type TRet, +} from './utils.ts'; + +/** + * Internal class for HMAC. + * Accepts any byte key, although RFC 2104 §3 recommends keys at least + * `HashLen` bytes long. + */ +export class _HMAC> implements Hash<_HMAC> { + oHash: T; + iHash: T; + blockLen: number; + outputLen: number; + canXOF = false; + private finished = false; + private destroyed = false; + + constructor(hash: TArg, key: TArg) { + ahash(hash); + abytes(key, undefined, 'key'); + this.iHash = hash.create() as T; + if (typeof this.iHash.update !== 'function') + throw new Error('Expected instance of class which extends utils.Hash'); + this.blockLen = this.iHash.blockLen; + this.outputLen = this.iHash.outputLen; + const blockLen = this.blockLen; + const pad = new Uint8Array(blockLen); + // blockLen can be bigger than outputLen + pad.set(key.length > blockLen ? hash.create().update(key).digest() : key); + for (let i = 0; i < pad.length; i++) pad[i] ^= 0x36; + this.iHash.update(pad); + // By doing update (processing of the first block) of the outer hash here, + // we can re-use it between multiple calls via clone. + this.oHash = hash.create() as T; + // Undo internal XOR && apply outer XOR + for (let i = 0; i < pad.length; i++) pad[i] ^= 0x36 ^ 0x5c; + this.oHash.update(pad); + clean(pad); + } + update(buf: TArg): this { + aexists(this); + this.iHash.update(buf); + return this; + } + digestInto(out: TArg): void { + aexists(this); + aoutput(out, this); + this.finished = true; + const buf = out.subarray(0, this.outputLen); + // Reuse the first outputLen bytes for the inner digest; the outer hash consumes them before + // overwriting that same prefix with the final tag, leaving any oversized tail untouched. + this.iHash.digestInto(buf); + this.oHash.update(buf); + this.oHash.digestInto(buf); + this.destroy(); + } + digest(): TRet { + const out = new Uint8Array(this.oHash.outputLen); + this.digestInto(out); + return out as TRet; + } + _cloneInto(to?: _HMAC): _HMAC { + // Create new instance without calling constructor since the key + // is already in state and we don't know it. + to ||= Object.create(Object.getPrototypeOf(this), {}); + const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this; + to = to as this; + to.finished = finished; + to.destroyed = destroyed; + to.blockLen = blockLen; + to.outputLen = outputLen; + to.oHash = oHash._cloneInto(to.oHash); + to.iHash = iHash._cloneInto(to.iHash); + return to; + } + clone(): _HMAC { + return this._cloneInto(); + } + destroy(): void { + this.destroyed = true; + this.oHash.destroy(); + this.iHash.destroy(); + } +} + +/** + * HMAC: RFC2104 message authentication code. + * @param hash - function that would be used e.g. sha256 + * @param key - authentication key bytes + * @param message - message bytes to authenticate + * @returns Authentication tag bytes. + * @example + * Compute an RFC 2104 HMAC. + * ```ts + * import { hmac } from '@noble/hashes/hmac.js'; + * import { sha256 } from '@noble/hashes/sha2.js'; + * const mac = hmac(sha256, new Uint8Array([1, 2, 3]), new Uint8Array([4, 5, 6])); + * ``` + */ +type HmacFn = { + (hash: TArg, key: TArg, message: TArg): TRet; + create(hash: TArg, key: TArg): TRet<_HMAC>; +}; +export const hmac: TRet = /* @__PURE__ */ (() => { + const hmac_ = (( + hash: TArg, + key: TArg, + message: TArg + ): TRet => new _HMAC(hash, key).update(message).digest()) as TRet; + hmac_.create = (hash: TArg, key: TArg): TRet<_HMAC> => + new _HMAC(hash, key) as TRet<_HMAC>; + return hmac_; +})(); diff --git a/node_modules/@noble/hashes/src/index.ts b/node_modules/@noble/hashes/src/index.ts new file mode 100644 index 0000000..c6a9c23 --- /dev/null +++ b/node_modules/@noble/hashes/src/index.ts @@ -0,0 +1,33 @@ +/** + * Audited & minimal JS implementation of hash functions, MACs, and KDFs. + * Check out individual modules. + * @module + * @example +```js +import { + sha256, sha384, sha512, sha224, sha512_224, sha512_256 +} from '@noble/hashes/sha2.js'; +import { + sha3_224, sha3_256, sha3_384, sha3_512, + keccak_224, keccak_256, keccak_384, keccak_512, + shake128, shake256 +} from '@noble/hashes/sha3.js'; +import { + cshake128, cshake256, + turboshake128, turboshake256, + kt128, kt256, + kmac128, kmac256, + tuplehash256, parallelhash256, + keccakprg +} from '@noble/hashes/sha3-addons.js'; +import { blake3 } from '@noble/hashes/blake3.js'; +import { blake2b, blake2s } from '@noble/hashes/blake2.js'; +import { hmac } from '@noble/hashes/hmac.js'; +import { hkdf } from '@noble/hashes/hkdf.js'; +import { pbkdf2, pbkdf2Async } from '@noble/hashes/pbkdf2.js'; +import { scrypt, scryptAsync } from '@noble/hashes/scrypt.js'; +import { md5, ripemd160, sha1 } from '@noble/hashes/legacy.js'; +import * as utils from '@noble/hashes/utils.js'; +``` + */ +throw new Error('root module cannot be imported: import submodules instead. Check out README'); diff --git a/node_modules/@noble/hashes/src/legacy.ts b/node_modules/@noble/hashes/src/legacy.ts new file mode 100644 index 0000000..0e185fb --- /dev/null +++ b/node_modules/@noble/hashes/src/legacy.ts @@ -0,0 +1,339 @@ +/** + +SHA1 (RFC 3174), MD5 (RFC 1321), and RIPEMD160 legacy, weak hash functions. +RFC 2286 only covers HMAC-RIPEMD160 wrapper material and test vectors, +not the base RIPEMD-160 compression spec. +Don't use them in a new protocol. What "weak" means: + +- Collisions can be made with 2^18 effort in MD5, 2^60 in SHA1, 2^80 in RIPEMD160. +- No practical pre-image attacks (only theoretical, 2^123.4) +- HMAC seems kinda ok: https://www.rfc-editor.org/rfc/rfc6151 + * @module + */ +import { Chi, HashMD, Maj } from './_md.ts'; +import { type CHash, clean, createHasher, rotl, type TRet } from './utils.ts'; + +/** Initial SHA-1 state from RFC 3174 §6.1. */ +const SHA1_IV = /* @__PURE__ */ Uint32Array.from([ + 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0, +]); + +// Reusable 80-word SHA-1 message schedule buffer. +const SHA1_W = /* @__PURE__ */ new Uint32Array(80); + +/** Internal SHA1 legacy hash class. */ +export class _SHA1 extends HashMD<_SHA1> { + private A = SHA1_IV[0] | 0; + private B = SHA1_IV[1] | 0; + private C = SHA1_IV[2] | 0; + private D = SHA1_IV[3] | 0; + private E = SHA1_IV[4] | 0; + + constructor() { + super(64, 20, 8, false); + } + protected get(): [number, number, number, number, number] { + const { A, B, C, D, E } = this; + return [A, B, C, D, E]; + } + protected set(A: number, B: number, C: number, D: number, E: number): void { + this.A = A | 0; + this.B = B | 0; + this.C = C | 0; + this.D = D | 0; + this.E = E | 0; + } + protected process(view: DataView, offset: number): void { + for (let i = 0; i < 16; i++, offset += 4) SHA1_W[i] = view.getUint32(offset, false); + for (let i = 16; i < 80; i++) + SHA1_W[i] = rotl(SHA1_W[i - 3] ^ SHA1_W[i - 8] ^ SHA1_W[i - 14] ^ SHA1_W[i - 16], 1); + // Compression function main loop, 80 rounds + let { A, B, C, D, E } = this; + for (let i = 0; i < 80; i++) { + let F, K; + if (i < 20) { + F = Chi(B, C, D); + K = 0x5a827999; + } else if (i < 40) { + F = B ^ C ^ D; + K = 0x6ed9eba1; + } else if (i < 60) { + F = Maj(B, C, D); + K = 0x8f1bbcdc; + } else { + F = B ^ C ^ D; + K = 0xca62c1d6; + } + const T = (rotl(A, 5) + F + E + K + SHA1_W[i]) | 0; + E = D; + D = C; + C = rotl(B, 30); + B = A; + A = T; + } + // Add the compressed chunk to the current hash value + A = (A + this.A) | 0; + B = (B + this.B) | 0; + C = (C + this.C) | 0; + D = (D + this.D) | 0; + E = (E + this.E) | 0; + this.set(A, B, C, D, E); + } + protected roundClean(): void { + clean(SHA1_W); + } + destroy(): void { + // HashMD callers route post-destroy usability through `destroyed`; zeroizing alone still leaves + // update()/digest() callable on reused instances. + this.destroyed = true; + this.set(0, 0, 0, 0, 0); + clean(this.buffer); + } +} + +/** + * SHA1 (RFC 3174) legacy hash function. It was cryptographically broken. + * @param msg - message bytes to hash + * @returns Digest bytes. + * @example + * Hash a message with SHA1. + * ```ts + * sha1(new Uint8Array([97, 98, 99])); + * ``` + */ +export const sha1: TRet = /* @__PURE__ */ createHasher(() => new _SHA1()); + +/** RFC 1321 `T[i]` uses `floor(2^32 * abs(sin(i)))`; this is the shared `2^32` scale factor. */ +const p32 = /* @__PURE__ */ Math.pow(2, 32); +/** RFC 1321 `T[1..64]` table. */ +const K = /* @__PURE__ */ Array.from({ length: 64 }, (_, i) => + Math.floor(p32 * Math.abs(Math.sin(i + 1))) +); + +/** MD5 initial state from RFC 1321, stored as 4 u32 words. */ +const MD5_IV = /* @__PURE__ */ SHA1_IV.slice(0, 4); + +// Reusable 16-word MD5 message block buffer. +const MD5_W = /* @__PURE__ */ new Uint32Array(16); +/** Internal MD5 legacy hash class. */ +export class _MD5 extends HashMD<_MD5> { + private A = MD5_IV[0] | 0; + private B = MD5_IV[1] | 0; + private C = MD5_IV[2] | 0; + private D = MD5_IV[3] | 0; + + constructor() { + super(64, 16, 8, true); + } + protected get(): [number, number, number, number] { + const { A, B, C, D } = this; + return [A, B, C, D]; + } + protected set(A: number, B: number, C: number, D: number): void { + this.A = A | 0; + this.B = B | 0; + this.C = C | 0; + this.D = D | 0; + } + protected process(view: DataView, offset: number): void { + for (let i = 0; i < 16; i++, offset += 4) MD5_W[i] = view.getUint32(offset, true); + // Compression function main loop, 64 rounds + let { A, B, C, D } = this; + for (let i = 0; i < 64; i++) { + let F, g, s; + if (i < 16) { + F = Chi(B, C, D); + g = i; + s = [7, 12, 17, 22]; + } else if (i < 32) { + // RFC 1321 round 2 uses G(B,C,D) = (B & D) | (C & ~D), which is `Chi(D, B, C)`. + F = Chi(D, B, C); + g = (5 * i + 1) % 16; + s = [5, 9, 14, 20]; + } else if (i < 48) { + F = B ^ C ^ D; + g = (3 * i + 5) % 16; + s = [4, 11, 16, 23]; + } else { + F = C ^ (B | ~D); + g = (7 * i) % 16; + s = [6, 10, 15, 21]; + } + F = F + A + K[i] + MD5_W[g]; + A = D; + D = C; + C = B; + B = B + rotl(F, s[i % 4]); + } + // Add the compressed chunk to the current hash value + A = (A + this.A) | 0; + B = (B + this.B) | 0; + C = (C + this.C) | 0; + D = (D + this.D) | 0; + this.set(A, B, C, D); + } + protected roundClean(): void { + clean(MD5_W); + } + destroy(): void { + // HashMD callers route post-destroy usability through `destroyed`; zeroizing alone still leaves + // update()/digest() callable on reused instances. + this.destroyed = true; + this.set(0, 0, 0, 0); + clean(this.buffer); + } +} + +/** + * MD5 (RFC 1321) legacy hash function. It was cryptographically broken. + * MD5 architecture is similar to SHA1, with some differences: + * - Reduced output length: 16 bytes (128 bit) instead of 20 + * - 64 rounds, instead of 80 + * - Little-endian: could be faster, but will require more code + * - Non-linear index selection: huge speed-up for unroll + * - Per round constants: more memory accesses, additional speed-up for unroll + * @param msg - message bytes to hash + * @returns Digest bytes. + * @example + * Hash a message with MD5. + * ```ts + * md5(new Uint8Array([97, 98, 99])); + * ``` + */ +export const md5: TRet = /* @__PURE__ */ createHasher(() => new _MD5()); + +// RIPEMD-160 + +// Permutation repeatedly applied to derive the later RIPEMD-160 message-order tables. +const Rho160 = /* @__PURE__ */ Uint8Array.from([ + 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, +]); +const Id160 = /* @__PURE__ */ (() => Uint8Array.from(new Array(16).fill(0).map((_, i) => i)))(); +const Pi160 = /* @__PURE__ */ (() => Id160.map((i) => (9 * i + 5) % 16))(); +// Five left/right message-word orderings for the RIPEMD-160 dual-lane rounds. +const idxLR = /* @__PURE__ */ (() => { + const L = [Id160]; + const R = [Pi160]; + const res = [L, R]; + for (let i = 0; i < 4; i++) for (let j of res) j.push(j[i].map((k) => Rho160[k])); + return res; +})(); +const idxL = /* @__PURE__ */ (() => idxLR[0])(); +const idxR = /* @__PURE__ */ (() => idxLR[1])(); +// const [idxL, idxR] = idxLR; + +// Base per-group shift table before the left/right message-order permutations are applied. +const shifts160 = /* @__PURE__ */ [ + [11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8], + [12, 13, 11, 15, 6, 9, 9, 7, 12, 15, 11, 13, 7, 8, 7, 7], + [13, 15, 14, 11, 7, 7, 6, 8, 13, 14, 13, 12, 5, 5, 6, 9], + [14, 11, 12, 14, 8, 6, 5, 5, 15, 12, 15, 14, 9, 9, 8, 6], + [15, 12, 13, 13, 9, 5, 8, 6, 14, 11, 12, 11, 8, 6, 5, 5], +].map((i) => Uint8Array.from(i)); +const shiftsL160 = /* @__PURE__ */ idxL.map((idx, i) => idx.map((j) => shifts160[i][j])); +const shiftsR160 = /* @__PURE__ */ idxR.map((idx, i) => idx.map((j) => shifts160[i][j])); +// Five left-lane additive constants for RIPEMD-160. +const Kl160 = /* @__PURE__ */ Uint32Array.from([ + 0x00000000, 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xa953fd4e, +]); +// Five right-lane additive constants for RIPEMD-160. +const Kr160 = /* @__PURE__ */ Uint32Array.from([ + 0x50a28be6, 0x5c4dd124, 0x6d703ef3, 0x7a6d76e9, 0x00000000, +]); +// Called `f()` in the spec; valid `group` values are 0..4, and out-of-range +// inputs currently fall through to the group-4 branch. +function ripemd_f(group: number, x: number, y: number, z: number): number { + if (group === 0) return x ^ y ^ z; + if (group === 1) return (x & y) | (~x & z); + if (group === 2) return (x | ~y) ^ z; + if (group === 3) return (x & z) | (y & ~z); + return x ^ (y | ~z); +} +// Reusable 16-word RIPEMD-160 message block buffer. +const BUF_160 = /* @__PURE__ */ new Uint32Array(16); +/** + * Internal RIPEMD-160 legacy hash class. + * RFC 2286 only adds HMAC-RIPEMD160 material, not the core hash specification. + */ +export class _RIPEMD160 extends HashMD<_RIPEMD160> { + private h0 = 0x67452301 | 0; + private h1 = 0xefcdab89 | 0; + private h2 = 0x98badcfe | 0; + private h3 = 0x10325476 | 0; + private h4 = 0xc3d2e1f0 | 0; + + constructor() { + super(64, 20, 8, true); + } + protected get(): [number, number, number, number, number] { + const { h0, h1, h2, h3, h4 } = this; + return [h0, h1, h2, h3, h4]; + } + protected set(h0: number, h1: number, h2: number, h3: number, h4: number): void { + this.h0 = h0 | 0; + this.h1 = h1 | 0; + this.h2 = h2 | 0; + this.h3 = h3 | 0; + this.h4 = h4 | 0; + } + protected process(view: DataView, offset: number): void { + for (let i = 0; i < 16; i++, offset += 4) BUF_160[i] = view.getUint32(offset, true); + // prettier-ignore + let al = this.h0 | 0, ar = al, + bl = this.h1 | 0, br = bl, + cl = this.h2 | 0, cr = cl, + dl = this.h3 | 0, dr = dl, + el = this.h4 | 0, er = el; + + // Instead of iterating 0 to 80, we split it into 5 groups + // And use the groups in constants, functions, etc. Much simpler + for (let group = 0; group < 5; group++) { + const rGroup = 4 - group; + const hbl = Kl160[group], hbr = Kr160[group]; // prettier-ignore + const rl = idxL[group], rr = idxR[group]; // prettier-ignore + const sl = shiftsL160[group], sr = shiftsR160[group]; // prettier-ignore + for (let i = 0; i < 16; i++) { + const tl = (rotl(al + ripemd_f(group, bl, cl, dl) + BUF_160[rl[i]] + hbl, sl[i]) + el) | 0; + al = el, el = dl, dl = rotl(cl, 10) | 0, cl = bl, bl = tl; // prettier-ignore + } + // 2 loops are 10% faster + for (let i = 0; i < 16; i++) { + const tr = (rotl(ar + ripemd_f(rGroup, br, cr, dr) + BUF_160[rr[i]] + hbr, sr[i]) + er) | 0; + ar = er, er = dr, dr = rotl(cr, 10) | 0, cr = br, br = tr; // prettier-ignore + } + } + // Add the compressed chunk to the current hash value + // Final recombination cross-adds the left/right lane accumulators into the next h0..h4 order. + this.set( + (this.h1 + cl + dr) | 0, + (this.h2 + dl + er) | 0, + (this.h3 + el + ar) | 0, + (this.h4 + al + br) | 0, + (this.h0 + bl + cr) | 0 + ); + } + protected roundClean(): void { + clean(BUF_160); + } + destroy(): void { + this.destroyed = true; + clean(this.buffer); + this.set(0, 0, 0, 0, 0); + } +} + +/** + * RIPEMD-160 - a legacy hash function from 1990s. + * RFC 2286 only covers HMAC-RIPEMD160 test material; the links below point + * at the base RIPEMD-160 references. + * * {@link https://homes.esat.kuleuven.be/~bosselae/ripemd160.html} + * * {@link https://homes.esat.kuleuven.be/~bosselae/ripemd160/pdf/AB-9601/AB-9601.pdf} + * @param msg - message bytes to hash + * @returns Digest bytes. + * @example + * Hash a message with RIPEMD-160. + * ```ts + * ripemd160(new Uint8Array([97, 98, 99])); + * ``` + */ +export const ripemd160: TRet = /* @__PURE__ */ createHasher(() => new _RIPEMD160()); diff --git a/node_modules/@noble/hashes/src/pbkdf2.ts b/node_modules/@noble/hashes/src/pbkdf2.ts new file mode 100644 index 0000000..ea7cda6 --- /dev/null +++ b/node_modules/@noble/hashes/src/pbkdf2.ts @@ -0,0 +1,175 @@ +/** + * PBKDF (RFC 2898). Can be used to create a key from password and salt. + * @module + */ +import { hmac } from './hmac.ts'; +// prettier-ignore +import { + ahash, anumber, + asyncLoop, checkOpts, clean, createView, kdfInputToBytes, + type CHash, + type Hash, + type KDFInput, + type TArg, + type TRet +} from './utils.ts'; + +/** + * PBKDF2 options: + * * c: iterations, should probably be higher than 100_000 + * * dkLen: desired length of derived key in bytes, must be `>= 1` per RFC 8018 §5.2 + * * asyncTick: max time in ms for which async function can block execution + */ +export type Pbkdf2Opt = { + /** Iteration count. Higher values increase CPU cost. */ + c: number; + /** Desired derived key length in bytes, must be `>= 1` per RFC 8018 §5.2. */ + dkLen?: number; + /** Max scheduler block time in milliseconds for the async variant. */ + asyncTick?: number; +}; +// Common start and end for sync/async functions +function pbkdf2Init( + hash: TArg, + _password: TArg, + _salt: TArg, + _opts: TArg +) { + ahash(hash); + const opts = checkOpts({ dkLen: 32, asyncTick: 10 }, _opts); + const { c, dkLen, asyncTick } = opts; + anumber(c, 'c'); + anumber(dkLen, 'dkLen'); + anumber(asyncTick, 'asyncTick'); + if (c < 1) throw new Error('iterations (c) must be >= 1'); + // RFC 8018 §5.2 defines `dkLen` as "a positive integer". + if (dkLen < 1) throw new Error('"dkLen" must be >= 1'); + // RFC 8018 §5.2 step 1 requires rejecting oversize `dkLen` + // before allocating the destination buffer. + if (dkLen > (2 ** 32 - 1) * hash.outputLen) throw new Error('derived key too long'); + const password = kdfInputToBytes(_password, 'password'); + const salt = kdfInputToBytes(_salt, 'salt'); + // DK = PBKDF2(PRF, Password, Salt, c, dkLen); + const DK = new Uint8Array(dkLen); + // U1 = PRF(Password, Salt + INT_32_BE(i)) + const PRF = hmac.create(hash, password); + // Cache PRF(P, S || ...) prefix state so each block only appends INT_32_BE(i). + const PRFSalt = PRF._cloneInto().update(salt); + return { c, dkLen, asyncTick, DK, PRF, PRFSalt }; +} + +function pbkdf2Output>( + PRF: TArg>, + PRFSalt: TArg>, + DK: TArg, + prfW: TArg | undefined>, + u: TArg +): TRet { + // Shared sync/async cleanup point: wipe transient PRF state + // while preserving the derived key buffer. + PRF.destroy(); + PRFSalt.destroy(); + if (prfW) prfW.destroy(); + clean(u); + return DK as TRet; +} + +/** + * PBKDF2-HMAC: RFC 8018 key derivation function. + * @param hash - hash function that would be used e.g. sha256 + * @param password - password from which a derived key is generated; + * JS string inputs are UTF-8 encoded first + * @param salt - cryptographic salt; JS string inputs are UTF-8 encoded first + * @param opts - PBKDF2 work factor and output settings. `dkLen`, if provided, + * must be `>= 1` per RFC 8018 §5.2. See {@link Pbkdf2Opt}. + * @returns Derived key bytes. + * @throws If the PBKDF2 iteration count or derived-key settings are invalid. {@link Error} + * @example + * PBKDF2-HMAC: RFC 2898 key derivation function. + * ```ts + * import { pbkdf2 } from '@noble/hashes/pbkdf2.js'; + * import { sha256 } from '@noble/hashes/sha2.js'; + * const key = pbkdf2(sha256, 'password', 'salt', { dkLen: 32, c: Math.pow(2, 18) }); + * ``` + */ +export function pbkdf2( + hash: TArg, + password: TArg, + salt: TArg, + opts: TArg +): TRet { + const { c, dkLen, DK, PRF, PRFSalt } = pbkdf2Init(hash, password, salt, opts); + let prfW: any; // Working copy + const arr = new Uint8Array(4); + const view = createView(arr); + const u = new Uint8Array(PRF.outputLen); + // DK = T1 + T2 + ⋯ + Tdklen/hlen + for (let ti = 1, pos = 0; pos < dkLen; ti++, pos += PRF.outputLen) { + // Ti = F(Password, Salt, c, i) + // The last Ti view can be shorter than hLen, which applies + // RFC 8018 §5.2 step 4's T_l<0..r-1> truncation without extra copies. + const Ti = DK.subarray(pos, pos + PRF.outputLen); + view.setInt32(0, ti, false); + // F(Password, Salt, c, i) = U1 ^ U2 ^ ⋯ ^ Uc + // U1 = PRF(Password, Salt + INT_32_BE(i)) + (prfW = PRFSalt._cloneInto(prfW)).update(arr).digestInto(u); + Ti.set(u.subarray(0, Ti.length)); + for (let ui = 1; ui < c; ui++) { + // Uc = PRF(Password, Uc−1) + PRF._cloneInto(prfW).update(u).digestInto(u); + for (let i = 0; i < Ti.length; i++) Ti[i] ^= u[i]; + } + } + return pbkdf2Output(PRF, PRFSalt, DK, prfW, u); +} + +/** + * PBKDF2-HMAC: RFC 8018 key derivation function. Async version. + * @param hash - hash function that would be used e.g. sha256 + * @param password - password from which a derived key is generated; + * JS string inputs are UTF-8 encoded first + * @param salt - cryptographic salt; JS string inputs are UTF-8 encoded first + * @param opts - PBKDF2 work factor and output settings. `dkLen`, if provided, + * must be `>= 1` per RFC 8018 §5.2. `asyncTick` is only a local + * scheduler-yield knob for this JS wrapper, not part of RFC 8018. + * See {@link Pbkdf2Opt}. + * @returns Promise resolving to derived key bytes. + * @throws If the PBKDF2 iteration count or derived-key settings are invalid. {@link Error} + * @example + * PBKDF2-HMAC: RFC 2898 key derivation function. + * ```ts + * import { pbkdf2Async } from '@noble/hashes/pbkdf2.js'; + * import { sha256 } from '@noble/hashes/sha2.js'; + * const key = await pbkdf2Async(sha256, 'password', 'salt', { dkLen: 32, c: 500_000 }); + * ``` + */ +export async function pbkdf2Async( + hash: TArg, + password: TArg, + salt: TArg, + opts: TArg +): Promise> { + const { c, dkLen, asyncTick, DK, PRF, PRFSalt } = pbkdf2Init(hash, password, salt, opts); + let prfW: any; // Working copy + const arr = new Uint8Array(4); + const view = createView(arr); + const u = new Uint8Array(PRF.outputLen); + // DK = T1 + T2 + ⋯ + Tdklen/hlen + for (let ti = 1, pos = 0; pos < dkLen; ti++, pos += PRF.outputLen) { + // Ti = F(Password, Salt, c, i) + // The last Ti view can be shorter than hLen, which applies + // RFC 8018 §5.2 step 4's T_l<0..r-1> truncation without extra copies. + const Ti = DK.subarray(pos, pos + PRF.outputLen); + view.setInt32(0, ti, false); + // F(Password, Salt, c, i) = U1 ^ U2 ^ ⋯ ^ Uc + // U1 = PRF(Password, Salt + INT_32_BE(i)) + (prfW = PRFSalt._cloneInto(prfW)).update(arr).digestInto(u); + Ti.set(u.subarray(0, Ti.length)); + await asyncLoop(c - 1, asyncTick, () => { + // Uc = PRF(Password, Uc−1) + PRF._cloneInto(prfW).update(u).digestInto(u); + for (let i = 0; i < Ti.length; i++) Ti[i] ^= u[i]; + }); + } + return pbkdf2Output(PRF, PRFSalt, DK, prfW, u); +} diff --git a/node_modules/@noble/hashes/src/scrypt.ts b/node_modules/@noble/hashes/src/scrypt.ts new file mode 100644 index 0000000..a68c890 --- /dev/null +++ b/node_modules/@noble/hashes/src/scrypt.ts @@ -0,0 +1,315 @@ +/** + * RFC 7914 Scrypt KDF. Can be used to create a key from password and salt. + * @module + */ +import { pbkdf2 } from './pbkdf2.ts'; +import { sha256 } from './sha2.ts'; +// prettier-ignore +import { + anumber, asyncLoop, + checkOpts, clean, + rotl, + swap32IfBE, + u32, + type KDFInput, + type TArg, + type TRet +} from './utils.ts'; + +// The main Scrypt loop: uses Salsa extensively. +// Six versions of the function were tried, this is the fastest one. +// RFC 7914 §3 / §4 step 2 applies Salsa20/8 to one 16-word (64-byte) block +// after xor'ing two such blocks. +// The local `y*` snapshot keeps the xor input stable even when `out` aliases `prev` or `input`. +// prettier-ignore +function XorAndSalsa( + prev: TArg, + pi: number, + input: TArg, + ii: number, + out: TArg, + oi: number +) { + // Based on https://cr.yp.to/salsa20.html and RFC 7914's Salsa20/8 core. + // Xor blocks + let y00 = prev[pi++] ^ input[ii++], y01 = prev[pi++] ^ input[ii++]; + let y02 = prev[pi++] ^ input[ii++], y03 = prev[pi++] ^ input[ii++]; + let y04 = prev[pi++] ^ input[ii++], y05 = prev[pi++] ^ input[ii++]; + let y06 = prev[pi++] ^ input[ii++], y07 = prev[pi++] ^ input[ii++]; + let y08 = prev[pi++] ^ input[ii++], y09 = prev[pi++] ^ input[ii++]; + let y10 = prev[pi++] ^ input[ii++], y11 = prev[pi++] ^ input[ii++]; + let y12 = prev[pi++] ^ input[ii++], y13 = prev[pi++] ^ input[ii++]; + let y14 = prev[pi++] ^ input[ii++], y15 = prev[pi++] ^ input[ii++]; + // Save state to temporary variables (salsa) + let x00 = y00, x01 = y01, x02 = y02, x03 = y03, + x04 = y04, x05 = y05, x06 = y06, x07 = y07, + x08 = y08, x09 = y09, x10 = y10, x11 = y11, + x12 = y12, x13 = y13, x14 = y14, x15 = y15; + // Main loop (salsa) + for (let i = 0; i < 8; i += 2) { + x04 ^= rotl(x00 + x12 | 0, 7); x08 ^= rotl(x04 + x00 | 0, 9); + x12 ^= rotl(x08 + x04 | 0, 13); x00 ^= rotl(x12 + x08 | 0, 18); + x09 ^= rotl(x05 + x01 | 0, 7); x13 ^= rotl(x09 + x05 | 0, 9); + x01 ^= rotl(x13 + x09 | 0, 13); x05 ^= rotl(x01 + x13 | 0, 18); + x14 ^= rotl(x10 + x06 | 0, 7); x02 ^= rotl(x14 + x10 | 0, 9); + x06 ^= rotl(x02 + x14 | 0, 13); x10 ^= rotl(x06 + x02 | 0, 18); + x03 ^= rotl(x15 + x11 | 0, 7); x07 ^= rotl(x03 + x15 | 0, 9); + x11 ^= rotl(x07 + x03 | 0, 13); x15 ^= rotl(x11 + x07 | 0, 18); + x01 ^= rotl(x00 + x03 | 0, 7); x02 ^= rotl(x01 + x00 | 0, 9); + x03 ^= rotl(x02 + x01 | 0, 13); x00 ^= rotl(x03 + x02 | 0, 18); + x06 ^= rotl(x05 + x04 | 0, 7); x07 ^= rotl(x06 + x05 | 0, 9); + x04 ^= rotl(x07 + x06 | 0, 13); x05 ^= rotl(x04 + x07 | 0, 18); + x11 ^= rotl(x10 + x09 | 0, 7); x08 ^= rotl(x11 + x10 | 0, 9); + x09 ^= rotl(x08 + x11 | 0, 13); x10 ^= rotl(x09 + x08 | 0, 18); + x12 ^= rotl(x15 + x14 | 0, 7); x13 ^= rotl(x12 + x15 | 0, 9); + x14 ^= rotl(x13 + x12 | 0, 13); x15 ^= rotl(x14 + x13 | 0, 18); + } + // Write output (salsa) + out[oi++] = (y00 + x00) | 0; out[oi++] = (y01 + x01) | 0; + out[oi++] = (y02 + x02) | 0; out[oi++] = (y03 + x03) | 0; + out[oi++] = (y04 + x04) | 0; out[oi++] = (y05 + x05) | 0; + out[oi++] = (y06 + x06) | 0; out[oi++] = (y07 + x07) | 0; + out[oi++] = (y08 + x08) | 0; out[oi++] = (y09 + x09) | 0; + out[oi++] = (y10 + x10) | 0; out[oi++] = (y11 + x11) | 0; + out[oi++] = (y12 + x12) | 0; out[oi++] = (y13 + x13) | 0; + out[oi++] = (y14 + x14) | 0; out[oi++] = (y15 + x15) | 0; +} + +function BlockMix( + input: TArg, + ii: number, + out: TArg, + oi: number, + r: number +) { + // The block B is `r` 128-byte chunks, i.e. `2r` 16-word (64-byte) Salsa blocks. + let head = oi + 0; + let tail = oi + 16 * r; + for (let i = 0; i < 16; i++) out[tail + i] = input[ii + (2 * r - 1) * 16 + i]; // X ← B[2r−1] + for (let i = 0; i < r; i++, head += 16, ii += 16) { + // RFC 7914 §4 step 3 outputs `Y[0], Y[2], ...` first, then `Y[1], Y[3], ...`; + // `head` and `tail` lay out those even/odd halves in place. + XorAndSalsa(out, tail, input, ii, out, head); // head[i] = Salsa(blockIn[2*i] ^ tail[i-1]) + if (i > 0) tail += 16; // First iteration overwrites tmp value in tail + // tail[i] = Salsa(blockIn[2*i+1] ^ head[i]) + XorAndSalsa(out, head, input, (ii += 16), out, tail); + } +} + +/** + * Scrypt options: + * - `N` is cpu/mem work factor (power of 2 e.g. `2**18`) + * - `r` is block size (8 is common), fine-tunes sequential memory read size and performance + * - `p` is parallelization factor (1 is common) + * - `dkLen` is output key length in bytes e.g. 32, and must be `>= 1` per RFC 7914 §2. + * - `asyncTick` - (default: 10) max time in ms for which async function can block execution + * - `maxmem` - (default: `1024 ** 3 + 1024` aka 1GB+1KB). A limit that the app could use for scrypt + * - `onProgress` - callback function that would be executed for progress report + */ +export type ScryptOpts = { + /** CPU and memory work factor. Must be a power of two. */ + N: number; + /** Block size parameter. */ + r: number; + /** Parallelization factor. */ + p: number; + /** Desired derived key length in bytes, must be `>= 1` per RFC 7914 §2. */ + dkLen?: number; + /** Max scheduler block time in milliseconds for the async variant. */ + asyncTick?: number; + /** Maximum temporary memory budget in bytes. */ + maxmem?: number; + /** + * Optional progress callback invoked during long-running derivations. + * param progress - completion fraction in the `0..1` range + */ + onProgress?: (progress: number) => void; +}; + +// Common prologue and epilogue for sync/async functions +function scryptInit(password: TArg, salt: TArg, _opts?: TArg) { + // Maxmem - 1GB+1KB by default + const opts = checkOpts( + { + dkLen: 32, + asyncTick: 10, + maxmem: 1024 ** 3 + 1024, + }, + _opts + ); + const { N, r, p, dkLen, asyncTick, maxmem, onProgress } = opts; + anumber(N, 'N'); + anumber(r, 'r'); + anumber(p, 'p'); + anumber(dkLen, 'dkLen'); + anumber(asyncTick, 'asyncTick'); + anumber(maxmem, 'maxmem'); + if (onProgress !== undefined && typeof onProgress !== 'function') + throw new Error('progressCb must be a function'); + const blockSize = 128 * r; + const blockSize32 = blockSize / 4; + + // Max N is 2^32 (Integrify is 32-bit). + // Real limit can be 2^22: some JS engines limit Uint8Array to 4GB. + // Spec check `N >= 2^(blockSize / 8)` is not done for compat with popular libs, + // which used incorrect r: 1, p: 8. Also, the check seems to be a spec error: + // https://www.rfc-editor.org/errata_search.php?rfc=7914 + const pow32 = Math.pow(2, 32); + if (N <= 1 || (N & (N - 1)) !== 0 || N > pow32) + throw new Error('"N" expected a power of 2, and 2^1 <= N <= 2^32'); + if (p < 1 || p > ((pow32 - 1) * 32) / blockSize) + throw new Error('"p" expected integer 1..((2^32 - 1) * 32) / (128 * r)'); + // RFC 7914 §2 defines `dkLen` as a positive integer. + if (dkLen < 1 || dkLen > (pow32 - 1) * 32) + throw new Error('"dkLen" expected integer 1..(2^32 - 1) * 32'); + // Include the shared `tmp` scratch block so `maxmem` matches noble's actual temporary allocation. + // Node requires more headroom here, so this accounting is intentionally noble-specific. + const memUsed = blockSize * (N + p + 1); + if (memUsed > maxmem) + throw new Error( + '"maxmem" limit was hit: memUsed(128*r*(N+p+1))=' + memUsed + ', maxmem=' + maxmem + ); + // [B0...Bp−1] ← PBKDF2HMAC-SHA256(Passphrase, Salt, 1, blockSize*ParallelizationFactor) + // Since it has only one iteration there is no reason to use async variant + const B = pbkdf2(sha256, password, salt, { c: 1, dkLen: blockSize * p }); + const B32 = u32(B); + // Re-used between parallel iterations. Array(iterations) of B + const V = u32(new Uint8Array(blockSize * N)); + const tmp = u32(new Uint8Array(blockSize)); + let blockMixCb = () => {}; + if (onProgress) { + const totalBlockMix = 2 * N * p; + // Invoke callback if progress changes from 10.01 to 10.02 + // Allows to draw smooth progress bar on up to 8K screen + const callbackPer = Math.max(Math.floor(totalBlockMix / 10000), 1); + let blockMixCnt = 0; + blockMixCb = () => { + blockMixCnt++; + if (onProgress && (!(blockMixCnt % callbackPer) || blockMixCnt === totalBlockMix)) + onProgress(blockMixCnt / totalBlockMix); + }; + } + return { N, r, p, dkLen, blockSize32, V, B32, B, tmp, blockMixCb, asyncTick }; +} + +function scryptOutput( + password: TArg, + dkLen: number, + B: TArg, + V: TArg, + tmp: TArg +): TRet { + // Shared final PBKDF2-and-cleanup step: keep the derived key, wipe the scrypt workspace. + const res = pbkdf2(sha256, password, B, { c: 1, dkLen }); + clean(B, V, tmp); + return res; +} + +/** + * Scrypt KDF from RFC 7914. See {@link ScryptOpts}. + * @param password - password or key material to derive from; + * JS string inputs are UTF-8 encoded first + * @param salt - unique salt bytes or string; JS string inputs are UTF-8 encoded first + * @param opts - Scrypt cost and memory parameters. `dkLen`, if provided, + * must be `>= 1` per RFC 7914 §2. See {@link ScryptOpts}. + * @returns Derived key bytes. + * @throws If the Scrypt cost, memory, or callback options are invalid. {@link Error} + * @example + * Derive a key with scrypt. + * ```ts + * scrypt('password', 'salt', { N: 2**18, r: 8, p: 1, dkLen: 32 }); + * ``` + */ +export function scrypt( + password: TArg, + salt: TArg, + opts: TArg +): TRet { + const { N, r, p, dkLen, blockSize32, V, B32, B, tmp, blockMixCb } = scryptInit( + password, + salt, + opts + ); + swap32IfBE(B32); + for (let pi = 0; pi < p; pi++) { + const Pi = blockSize32 * pi; + for (let i = 0; i < blockSize32; i++) V[i] = B32[Pi + i]; // V[0] = B[i] + for (let i = 0, pos = 0; i < N - 1; i++) { + BlockMix(V, pos, V, (pos += blockSize32), r); // V[i] = BlockMix(V[i-1]); + blockMixCb(); + } + BlockMix(V, (N - 1) * blockSize32, B32, Pi, r); // Process last element + blockMixCb(); + for (let i = 0; i < N; i++) { + // First u32 of the last 64-byte block (u32 is LE) + // RFC 7914 Integerify(X) uses the whole last 64-byte block, but mod N + // only depends on the low word here because N is a power of two and + // this implementation caps N at 2^32. + // & (N - 1) is % N as N is a power of 2, N & (N - 1) = 0 is checked + // above; >>> 0 for unsigned, input fits in u32. + const j = (B32[Pi + blockSize32 - 16] & (N - 1)) >>> 0; // j = Integrify(X) % iterations + // tmp = B ^ V[j] + for (let k = 0; k < blockSize32; k++) tmp[k] = B32[Pi + k] ^ V[j * blockSize32 + k]; + BlockMix(tmp, 0, B32, Pi, r); // B = BlockMix(B ^ V[j]) + blockMixCb(); + } + } + swap32IfBE(B32); + return scryptOutput(password, dkLen, B, V, tmp); +} + +/** + * Scrypt KDF from RFC 7914. Async version. See {@link ScryptOpts}. + * @param password - password or key material to derive from; + * JS string inputs are UTF-8 encoded first + * @param salt - unique salt bytes or string; JS string inputs are UTF-8 encoded first + * @param opts - Scrypt cost and memory parameters. `dkLen`, if provided, + * must be `>= 1` per RFC 7914 §2. `asyncTick` is only a local + * scheduler-yield control for this JS wrapper, not part of RFC 7914. + * See {@link ScryptOpts}. + * @returns Promise resolving to derived key bytes. + * @throws If the Scrypt cost, memory, or callback options are invalid. {@link Error} + * @example + * Derive a key with scrypt asynchronously. + * ```ts + * await scryptAsync('password', 'salt', { N: 2**18, r: 8, p: 1, dkLen: 32 }); + * ``` + */ +export async function scryptAsync( + password: TArg, + salt: TArg, + opts: TArg +): Promise> { + const { N, r, p, dkLen, blockSize32, V, B32, B, tmp, blockMixCb, asyncTick } = scryptInit( + password, + salt, + opts + ); + swap32IfBE(B32); + for (let pi = 0; pi < p; pi++) { + const Pi = blockSize32 * pi; + for (let i = 0; i < blockSize32; i++) V[i] = B32[Pi + i]; // V[0] = B[i] + let pos = 0; + await asyncLoop(N - 1, asyncTick, () => { + BlockMix(V, pos, V, (pos += blockSize32), r); // V[i] = BlockMix(V[i-1]); + blockMixCb(); + }); + BlockMix(V, (N - 1) * blockSize32, B32, Pi, r); // Process last element + blockMixCb(); + await asyncLoop(N, asyncTick, () => { + // First u32 of the last 64-byte block (u32 is LE) + // RFC 7914 Integerify(X) uses the whole last 64-byte block, but mod N + // only depends on the low word here because N is a power of two and + // this implementation caps N at 2^32. + // & (N - 1) is % N as N is a power of 2, N & (N - 1) = 0 is checked + // above; >>> 0 for unsigned, input fits in u32. + const j = (B32[Pi + blockSize32 - 16] & (N - 1)) >>> 0; // j = Integrify(X) % iterations + // tmp = B ^ V[j] + for (let k = 0; k < blockSize32; k++) tmp[k] = B32[Pi + k] ^ V[j * blockSize32 + k]; + BlockMix(tmp, 0, B32, Pi, r); // B = BlockMix(B ^ V[j]) + blockMixCb(); + }); + } + swap32IfBE(B32); + return scryptOutput(password, dkLen, B, V, tmp); +} diff --git a/node_modules/@noble/hashes/src/sha2.ts b/node_modules/@noble/hashes/src/sha2.ts new file mode 100644 index 0000000..2ff7e65 --- /dev/null +++ b/node_modules/@noble/hashes/src/sha2.ts @@ -0,0 +1,530 @@ +/** + * SHA2 hash function. A.k.a. sha256, sha384, sha512, sha512_224, sha512_256. + * SHA256 is the fastest hash implementable in JS, even faster than Blake3. + * Check out {@link https://www.rfc-editor.org/rfc/rfc4634 | RFC 4634} and + * {@link https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf | FIPS 180-4}. + * @module + */ +import { Chi, HashMD, Maj, SHA224_IV, SHA256_IV, SHA384_IV, SHA512_IV } from './_md.ts'; +import * as u64 from './_u64.ts'; +import { type CHash, clean, createHasher, oidNist, rotr, type TRet } from './utils.ts'; + +/** + * SHA-224 / SHA-256 round constants from RFC 6234 §5.1: the first 32 bits + * of the cube roots of the first 64 primes (2..311). + */ +// prettier-ignore +const SHA256_K = /* @__PURE__ */ Uint32Array.from([ + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 +]); + +/** Reusable SHA-224 / SHA-256 message schedule buffer `W_t` from RFC 6234 §6.2 step 1. */ +const SHA256_W = /* @__PURE__ */ new Uint32Array(64); + +/** Internal SHA-224 / SHA-256 compression engine from RFC 6234 §6.2. */ +abstract class SHA2_32B> extends HashMD { + // We cannot use array here since array allows indexing by variable + // which means optimizer/compiler cannot use registers. + protected abstract A: number; + protected abstract B: number; + protected abstract C: number; + protected abstract D: number; + protected abstract E: number; + protected abstract F: number; + protected abstract G: number; + protected abstract H: number; + + constructor(outputLen: number) { + super(64, outputLen, 8, false); + } + protected get(): [number, number, number, number, number, number, number, number] { + const { A, B, C, D, E, F, G, H } = this; + return [A, B, C, D, E, F, G, H]; + } + // prettier-ignore + protected set( + A: number, B: number, C: number, D: number, E: number, F: number, G: number, H: number + ): void { + this.A = A | 0; + this.B = B | 0; + this.C = C | 0; + this.D = D | 0; + this.E = E | 0; + this.F = F | 0; + this.G = G | 0; + this.H = H | 0; + } + protected process(view: DataView, offset: number): void { + // Extend the first 16 words into the remaining 48 words w[16..63] of the message schedule array + for (let i = 0; i < 16; i++, offset += 4) SHA256_W[i] = view.getUint32(offset, false); + for (let i = 16; i < 64; i++) { + const W15 = SHA256_W[i - 15]; + const W2 = SHA256_W[i - 2]; + const s0 = rotr(W15, 7) ^ rotr(W15, 18) ^ (W15 >>> 3); + const s1 = rotr(W2, 17) ^ rotr(W2, 19) ^ (W2 >>> 10); + SHA256_W[i] = (s1 + SHA256_W[i - 7] + s0 + SHA256_W[i - 16]) | 0; + } + // Compression function main loop, 64 rounds + let { A, B, C, D, E, F, G, H } = this; + for (let i = 0; i < 64; i++) { + const sigma1 = rotr(E, 6) ^ rotr(E, 11) ^ rotr(E, 25); + const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0; + const sigma0 = rotr(A, 2) ^ rotr(A, 13) ^ rotr(A, 22); + const T2 = (sigma0 + Maj(A, B, C)) | 0; + H = G; + G = F; + F = E; + E = (D + T1) | 0; + D = C; + C = B; + B = A; + A = (T1 + T2) | 0; + } + // Add the compressed chunk to the current hash value + A = (A + this.A) | 0; + B = (B + this.B) | 0; + C = (C + this.C) | 0; + D = (D + this.D) | 0; + E = (E + this.E) | 0; + F = (F + this.F) | 0; + G = (G + this.G) | 0; + H = (H + this.H) | 0; + this.set(A, B, C, D, E, F, G, H); + } + protected roundClean(): void { + clean(SHA256_W); + } + destroy(): void { + // HashMD callers route post-destroy usability through `destroyed`; zeroizing alone still leaves + // update()/digest() callable on reused instances. + this.destroyed = true; + this.set(0, 0, 0, 0, 0, 0, 0, 0); + clean(this.buffer); + } +} + +/** Internal SHA-256 hash class grounded in RFC 6234 §6.2. */ +export class _SHA256 extends SHA2_32B<_SHA256> { + // We cannot use array here since array allows indexing by variable + // which means optimizer/compiler cannot use registers. + protected A: number = SHA256_IV[0] | 0; + protected B: number = SHA256_IV[1] | 0; + protected C: number = SHA256_IV[2] | 0; + protected D: number = SHA256_IV[3] | 0; + protected E: number = SHA256_IV[4] | 0; + protected F: number = SHA256_IV[5] | 0; + protected G: number = SHA256_IV[6] | 0; + protected H: number = SHA256_IV[7] | 0; + constructor() { + super(32); + } +} + +/** Internal SHA-224 hash class grounded in RFC 6234 §6.2 and §8.5. */ +export class _SHA224 extends SHA2_32B<_SHA224> { + protected A: number = SHA224_IV[0] | 0; + protected B: number = SHA224_IV[1] | 0; + protected C: number = SHA224_IV[2] | 0; + protected D: number = SHA224_IV[3] | 0; + protected E: number = SHA224_IV[4] | 0; + protected F: number = SHA224_IV[5] | 0; + protected G: number = SHA224_IV[6] | 0; + protected H: number = SHA224_IV[7] | 0; + constructor() { + super(28); + } +} + +// SHA2-512 is slower than sha256 in js because u64 operations are slow. + +// SHA-384 / SHA-512 round constants from RFC 6234 §5.2: +// 80 full 64-bit words split into high/low halves. +// prettier-ignore +const K512 = /* @__PURE__ */ (() => u64.split([ + '0x428a2f98d728ae22', '0x7137449123ef65cd', '0xb5c0fbcfec4d3b2f', '0xe9b5dba58189dbbc', + '0x3956c25bf348b538', '0x59f111f1b605d019', '0x923f82a4af194f9b', '0xab1c5ed5da6d8118', + '0xd807aa98a3030242', '0x12835b0145706fbe', '0x243185be4ee4b28c', '0x550c7dc3d5ffb4e2', + '0x72be5d74f27b896f', '0x80deb1fe3b1696b1', '0x9bdc06a725c71235', '0xc19bf174cf692694', + '0xe49b69c19ef14ad2', '0xefbe4786384f25e3', '0x0fc19dc68b8cd5b5', '0x240ca1cc77ac9c65', + '0x2de92c6f592b0275', '0x4a7484aa6ea6e483', '0x5cb0a9dcbd41fbd4', '0x76f988da831153b5', + '0x983e5152ee66dfab', '0xa831c66d2db43210', '0xb00327c898fb213f', '0xbf597fc7beef0ee4', + '0xc6e00bf33da88fc2', '0xd5a79147930aa725', '0x06ca6351e003826f', '0x142929670a0e6e70', + '0x27b70a8546d22ffc', '0x2e1b21385c26c926', '0x4d2c6dfc5ac42aed', '0x53380d139d95b3df', + '0x650a73548baf63de', '0x766a0abb3c77b2a8', '0x81c2c92e47edaee6', '0x92722c851482353b', + '0xa2bfe8a14cf10364', '0xa81a664bbc423001', '0xc24b8b70d0f89791', '0xc76c51a30654be30', + '0xd192e819d6ef5218', '0xd69906245565a910', '0xf40e35855771202a', '0x106aa07032bbd1b8', + '0x19a4c116b8d2d0c8', '0x1e376c085141ab53', '0x2748774cdf8eeb99', '0x34b0bcb5e19b48a8', + '0x391c0cb3c5c95a63', '0x4ed8aa4ae3418acb', '0x5b9cca4f7763e373', '0x682e6ff3d6b2b8a3', + '0x748f82ee5defb2fc', '0x78a5636f43172f60', '0x84c87814a1f0ab72', '0x8cc702081a6439ec', + '0x90befffa23631e28', '0xa4506cebde82bde9', '0xbef9a3f7b2c67915', '0xc67178f2e372532b', + '0xca273eceea26619c', '0xd186b8c721c0c207', '0xeada7dd6cde0eb1e', '0xf57d4f7fee6ed178', + '0x06f067aa72176fba', '0x0a637dc5a2c898a6', '0x113f9804bef90dae', '0x1b710b35131c471b', + '0x28db77f523047d84', '0x32caab7b40c72493', '0x3c9ebe0a15c9bebc', '0x431d67c49c100d4c', + '0x4cc5d4becb3e42b6', '0x597f299cfc657e2a', '0x5fcb6fab3ad6faec', '0x6c44198c4a475817' +].map(n => BigInt(n))))(); +const SHA512_Kh = /* @__PURE__ */ (() => K512[0])(); +const SHA512_Kl = /* @__PURE__ */ (() => K512[1])(); + +// Reusable high-half schedule buffer for the RFC 6234 §6.4 64-bit `W_t` words. +const SHA512_W_H = /* @__PURE__ */ new Uint32Array(80); +// Reusable low-half schedule buffer for the RFC 6234 §6.4 64-bit `W_t` words. +const SHA512_W_L = /* @__PURE__ */ new Uint32Array(80); + +/** Internal SHA-384 / SHA-512 compression engine from RFC 6234 §6.4. */ +abstract class SHA2_64B> extends HashMD { + // We cannot use array here since array allows indexing by variable + // which means optimizer/compiler cannot use registers. + // h -- high 32 bits, l -- low 32 bits + protected abstract Ah: number; + protected abstract Al: number; + protected abstract Bh: number; + protected abstract Bl: number; + protected abstract Ch: number; + protected abstract Cl: number; + protected abstract Dh: number; + protected abstract Dl: number; + protected abstract Eh: number; + protected abstract El: number; + protected abstract Fh: number; + protected abstract Fl: number; + protected abstract Gh: number; + protected abstract Gl: number; + protected abstract Hh: number; + protected abstract Hl: number; + + constructor(outputLen: number) { + super(128, outputLen, 16, false); + } + // prettier-ignore + protected get(): [ + number, number, number, number, number, number, number, number, + number, number, number, number, number, number, number, number + ] { + const { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this; + return [Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl]; + } + // prettier-ignore + protected set( + Ah: number, Al: number, Bh: number, Bl: number, Ch: number, Cl: number, Dh: number, Dl: number, + Eh: number, El: number, Fh: number, Fl: number, Gh: number, Gl: number, Hh: number, Hl: number + ): void { + this.Ah = Ah | 0; + this.Al = Al | 0; + this.Bh = Bh | 0; + this.Bl = Bl | 0; + this.Ch = Ch | 0; + this.Cl = Cl | 0; + this.Dh = Dh | 0; + this.Dl = Dl | 0; + this.Eh = Eh | 0; + this.El = El | 0; + this.Fh = Fh | 0; + this.Fl = Fl | 0; + this.Gh = Gh | 0; + this.Gl = Gl | 0; + this.Hh = Hh | 0; + this.Hl = Hl | 0; + } + protected process(view: DataView, offset: number): void { + // Extend the first 16 words into the remaining 64 words w[16..79] of the message schedule array + for (let i = 0; i < 16; i++, offset += 4) { + SHA512_W_H[i] = view.getUint32(offset); + SHA512_W_L[i] = view.getUint32((offset += 4)); + } + for (let i = 16; i < 80; i++) { + // s0 := (w[i-15] rightrotate 1) xor (w[i-15] rightrotate 8) xor (w[i-15] rightshift 7) + const W15h = SHA512_W_H[i - 15] | 0; + const W15l = SHA512_W_L[i - 15] | 0; + const s0h = u64.rotrSH(W15h, W15l, 1) ^ u64.rotrSH(W15h, W15l, 8) ^ u64.shrSH(W15h, W15l, 7); + const s0l = u64.rotrSL(W15h, W15l, 1) ^ u64.rotrSL(W15h, W15l, 8) ^ u64.shrSL(W15h, W15l, 7); + // s1 := (w[i-2] rightrotate 19) xor (w[i-2] rightrotate 61) xor (w[i-2] rightshift 6) + const W2h = SHA512_W_H[i - 2] | 0; + const W2l = SHA512_W_L[i - 2] | 0; + const s1h = u64.rotrSH(W2h, W2l, 19) ^ u64.rotrBH(W2h, W2l, 61) ^ u64.shrSH(W2h, W2l, 6); + const s1l = u64.rotrSL(W2h, W2l, 19) ^ u64.rotrBL(W2h, W2l, 61) ^ u64.shrSL(W2h, W2l, 6); + // SHA512_W[i] = s0 + s1 + SHA512_W[i - 7] + SHA512_W[i - 16]; + const SUMl = u64.add4L(s0l, s1l, SHA512_W_L[i - 7], SHA512_W_L[i - 16]); + const SUMh = u64.add4H(SUMl, s0h, s1h, SHA512_W_H[i - 7], SHA512_W_H[i - 16]); + SHA512_W_H[i] = SUMh | 0; + SHA512_W_L[i] = SUMl | 0; + } + let { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this; + // Compression function main loop, 80 rounds + for (let i = 0; i < 80; i++) { + // S1 := (e rightrotate 14) xor (e rightrotate 18) xor (e rightrotate 41) + const sigma1h = u64.rotrSH(Eh, El, 14) ^ u64.rotrSH(Eh, El, 18) ^ u64.rotrBH(Eh, El, 41); + const sigma1l = u64.rotrSL(Eh, El, 14) ^ u64.rotrSL(Eh, El, 18) ^ u64.rotrBL(Eh, El, 41); + //const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0; + const CHIh = (Eh & Fh) ^ (~Eh & Gh); + const CHIl = (El & Fl) ^ (~El & Gl); + // T1 = H + sigma1 + Chi(E, F, G) + SHA512_K[i] + SHA512_W[i] + // prettier-ignore + const T1ll = u64.add5L(Hl, sigma1l, CHIl, SHA512_Kl[i], SHA512_W_L[i]); + const T1h = u64.add5H(T1ll, Hh, sigma1h, CHIh, SHA512_Kh[i], SHA512_W_H[i]); + const T1l = T1ll | 0; + // S0 := (a rightrotate 28) xor (a rightrotate 34) xor (a rightrotate 39) + const sigma0h = u64.rotrSH(Ah, Al, 28) ^ u64.rotrBH(Ah, Al, 34) ^ u64.rotrBH(Ah, Al, 39); + const sigma0l = u64.rotrSL(Ah, Al, 28) ^ u64.rotrBL(Ah, Al, 34) ^ u64.rotrBL(Ah, Al, 39); + const MAJh = (Ah & Bh) ^ (Ah & Ch) ^ (Bh & Ch); + const MAJl = (Al & Bl) ^ (Al & Cl) ^ (Bl & Cl); + Hh = Gh | 0; + Hl = Gl | 0; + Gh = Fh | 0; + Gl = Fl | 0; + Fh = Eh | 0; + Fl = El | 0; + ({ h: Eh, l: El } = u64.add(Dh | 0, Dl | 0, T1h | 0, T1l | 0)); + Dh = Ch | 0; + Dl = Cl | 0; + Ch = Bh | 0; + Cl = Bl | 0; + Bh = Ah | 0; + Bl = Al | 0; + const All = u64.add3L(T1l, sigma0l, MAJl); + Ah = u64.add3H(All, T1h, sigma0h, MAJh); + Al = All | 0; + } + // Add the compressed chunk to the current hash value + ({ h: Ah, l: Al } = u64.add(this.Ah | 0, this.Al | 0, Ah | 0, Al | 0)); + ({ h: Bh, l: Bl } = u64.add(this.Bh | 0, this.Bl | 0, Bh | 0, Bl | 0)); + ({ h: Ch, l: Cl } = u64.add(this.Ch | 0, this.Cl | 0, Ch | 0, Cl | 0)); + ({ h: Dh, l: Dl } = u64.add(this.Dh | 0, this.Dl | 0, Dh | 0, Dl | 0)); + ({ h: Eh, l: El } = u64.add(this.Eh | 0, this.El | 0, Eh | 0, El | 0)); + ({ h: Fh, l: Fl } = u64.add(this.Fh | 0, this.Fl | 0, Fh | 0, Fl | 0)); + ({ h: Gh, l: Gl } = u64.add(this.Gh | 0, this.Gl | 0, Gh | 0, Gl | 0)); + ({ h: Hh, l: Hl } = u64.add(this.Hh | 0, this.Hl | 0, Hh | 0, Hl | 0)); + this.set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl); + } + protected roundClean(): void { + clean(SHA512_W_H, SHA512_W_L); + } + destroy(): void { + // HashMD callers route post-destroy usability through `destroyed`; zeroizing alone still leaves + // update()/digest() callable on reused instances. + this.destroyed = true; + clean(this.buffer); + this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + } +} + +/** Internal SHA-512 hash class grounded in RFC 6234 §6.3 and §6.4. */ +export class _SHA512 extends SHA2_64B<_SHA512> { + protected Ah: number = SHA512_IV[0] | 0; + protected Al: number = SHA512_IV[1] | 0; + protected Bh: number = SHA512_IV[2] | 0; + protected Bl: number = SHA512_IV[3] | 0; + protected Ch: number = SHA512_IV[4] | 0; + protected Cl: number = SHA512_IV[5] | 0; + protected Dh: number = SHA512_IV[6] | 0; + protected Dl: number = SHA512_IV[7] | 0; + protected Eh: number = SHA512_IV[8] | 0; + protected El: number = SHA512_IV[9] | 0; + protected Fh: number = SHA512_IV[10] | 0; + protected Fl: number = SHA512_IV[11] | 0; + protected Gh: number = SHA512_IV[12] | 0; + protected Gl: number = SHA512_IV[13] | 0; + protected Hh: number = SHA512_IV[14] | 0; + protected Hl: number = SHA512_IV[15] | 0; + + constructor() { + super(64); + } +} + +/** Internal SHA-384 hash class grounded in RFC 6234 §6.3 and §6.4. */ +export class _SHA384 extends SHA2_64B<_SHA384> { + protected Ah: number = SHA384_IV[0] | 0; + protected Al: number = SHA384_IV[1] | 0; + protected Bh: number = SHA384_IV[2] | 0; + protected Bl: number = SHA384_IV[3] | 0; + protected Ch: number = SHA384_IV[4] | 0; + protected Cl: number = SHA384_IV[5] | 0; + protected Dh: number = SHA384_IV[6] | 0; + protected Dl: number = SHA384_IV[7] | 0; + protected Eh: number = SHA384_IV[8] | 0; + protected El: number = SHA384_IV[9] | 0; + protected Fh: number = SHA384_IV[10] | 0; + protected Fl: number = SHA384_IV[11] | 0; + protected Gh: number = SHA384_IV[12] | 0; + protected Gl: number = SHA384_IV[13] | 0; + protected Hh: number = SHA384_IV[14] | 0; + protected Hl: number = SHA384_IV[15] | 0; + + constructor() { + super(48); + } +} + +/** + * Truncated SHA512/256 and SHA512/224. + * SHA512_IV is XORed with 0xa5a5a5a5a5a5a5a5, then used as "intermediary" IV of SHA512/t. + * Then t hashes string to produce result IV. + * See the repo-side derivation recipe in `test/misc/sha2-gen-iv.js`. + * These IV literals are checked against that script rather than a dedicated + * local RFC section. + */ + +/** SHA-512/224 IV derived by the SHA-512/t recipe in `test/misc/sha2-gen-iv.js` and + * stored as sixteen big-endian 32-bit halves. */ +const T224_IV = /* @__PURE__ */ Uint32Array.from([ + 0x8c3d37c8, 0x19544da2, 0x73e19966, 0x89dcd4d6, 0x1dfab7ae, 0x32ff9c82, 0x679dd514, 0x582f9fcf, + 0x0f6d2b69, 0x7bd44da8, 0x77e36f73, 0x04c48942, 0x3f9d85a8, 0x6a1d36c8, 0x1112e6ad, 0x91d692a1, +]); + +/** SHA-512/256 IV derived by the SHA-512/t recipe in `test/misc/sha2-gen-iv.js` and + * stored as sixteen big-endian 32-bit halves. */ +const T256_IV = /* @__PURE__ */ Uint32Array.from([ + 0x22312194, 0xfc2bf72c, 0x9f555fa3, 0xc84c64c2, 0x2393b86b, 0x6f53b151, 0x96387719, 0x5940eabd, + 0x96283ee2, 0xa88effe3, 0xbe5e1e25, 0x53863992, 0x2b0199fc, 0x2c85b8aa, 0x0eb72ddc, 0x81c52ca2, +]); + +/** Internal SHA-512/224 hash class using the derived `T224_IV` and the shared + * RFC 6234 §6.4 compression engine. */ +export class _SHA512_224 extends SHA2_64B<_SHA512_224> { + protected Ah: number = T224_IV[0] | 0; + protected Al: number = T224_IV[1] | 0; + protected Bh: number = T224_IV[2] | 0; + protected Bl: number = T224_IV[3] | 0; + protected Ch: number = T224_IV[4] | 0; + protected Cl: number = T224_IV[5] | 0; + protected Dh: number = T224_IV[6] | 0; + protected Dl: number = T224_IV[7] | 0; + protected Eh: number = T224_IV[8] | 0; + protected El: number = T224_IV[9] | 0; + protected Fh: number = T224_IV[10] | 0; + protected Fl: number = T224_IV[11] | 0; + protected Gh: number = T224_IV[12] | 0; + protected Gl: number = T224_IV[13] | 0; + protected Hh: number = T224_IV[14] | 0; + protected Hl: number = T224_IV[15] | 0; + + constructor() { + super(28); + } +} + +/** Internal SHA-512/256 hash class using the derived `T256_IV` and the shared + * RFC 6234 §6.4 compression engine. */ +export class _SHA512_256 extends SHA2_64B<_SHA512_256> { + protected Ah: number = T256_IV[0] | 0; + protected Al: number = T256_IV[1] | 0; + protected Bh: number = T256_IV[2] | 0; + protected Bl: number = T256_IV[3] | 0; + protected Ch: number = T256_IV[4] | 0; + protected Cl: number = T256_IV[5] | 0; + protected Dh: number = T256_IV[6] | 0; + protected Dl: number = T256_IV[7] | 0; + protected Eh: number = T256_IV[8] | 0; + protected El: number = T256_IV[9] | 0; + protected Fh: number = T256_IV[10] | 0; + protected Fl: number = T256_IV[11] | 0; + protected Gh: number = T256_IV[12] | 0; + protected Gl: number = T256_IV[13] | 0; + protected Hh: number = T256_IV[14] | 0; + protected Hl: number = T256_IV[15] | 0; + + constructor() { + super(32); + } +} + +/** + * SHA2-256 hash function from RFC 4634. In JS it's the fastest: even faster than Blake3. Some info: + * + * - Trying 2^128 hashes would get 50% chance of collision, using birthday attack. + * - BTC network is doing 2^70 hashes/sec (2^95 hashes/year) as per 2025. + * - Each sha256 hash is executing 2^18 bit operations. + * - Good 2024 ASICs can do 200Th/sec with 3500 watts of power, corresponding to 2^36 hashes/joule. + * @param msg - message bytes to hash + * @returns Digest bytes. + * @example + * Hash a message with SHA2-256. + * ```ts + * sha256(new Uint8Array([97, 98, 99])); + * ``` + */ +export const sha256: TRet> = /* @__PURE__ */ createHasher( + () => new _SHA256(), + /* @__PURE__ */ oidNist(0x01) +); +/** + * SHA2-224 hash function from RFC 4634. + * @param msg - message bytes to hash + * @returns Digest bytes. + * @example + * Hash a message with SHA2-224. + * ```ts + * sha224(new Uint8Array([97, 98, 99])); + * ``` + */ +export const sha224: TRet> = /* @__PURE__ */ createHasher( + () => new _SHA224(), + /* @__PURE__ */ oidNist(0x04) +); + +/** + * SHA2-512 hash function from RFC 4634. + * @param msg - message bytes to hash + * @returns Digest bytes. + * @example + * Hash a message with SHA2-512. + * ```ts + * sha512(new Uint8Array([97, 98, 99])); + * ``` + */ +export const sha512: TRet> = /* @__PURE__ */ createHasher( + () => new _SHA512(), + /* @__PURE__ */ oidNist(0x03) +); +/** + * SHA2-384 hash function from RFC 4634. + * @param msg - message bytes to hash + * @returns Digest bytes. + * @example + * Hash a message with SHA2-384. + * ```ts + * sha384(new Uint8Array([97, 98, 99])); + * ``` + */ +export const sha384: TRet> = /* @__PURE__ */ createHasher( + () => new _SHA384(), + /* @__PURE__ */ oidNist(0x02) +); + +/** + * SHA2-512/256 "truncated" hash function, with improved resistance to length extension attacks. + * See the paper on {@link https://eprint.iacr.org/2010/548.pdf | truncated SHA512}. + * @param msg - message bytes to hash + * @returns Digest bytes. + * @example + * Hash a message with SHA2-512/256. + * ```ts + * sha512_256(new Uint8Array([97, 98, 99])); + * ``` + */ +export const sha512_256: TRet> = /* @__PURE__ */ createHasher( + () => new _SHA512_256(), + /* @__PURE__ */ oidNist(0x06) +); +/** + * SHA2-512/224 "truncated" hash function, with improved resistance to length extension attacks. + * See the paper on {@link https://eprint.iacr.org/2010/548.pdf | truncated SHA512}. + * @param msg - message bytes to hash + * @returns Digest bytes. + * @example + * Hash a message with SHA2-512/224. + * ```ts + * sha512_224(new Uint8Array([97, 98, 99])); + * ``` + */ +export const sha512_224: TRet> = /* @__PURE__ */ createHasher( + () => new _SHA512_224(), + /* @__PURE__ */ oidNist(0x05) +); diff --git a/node_modules/@noble/hashes/src/sha3-addons.ts b/node_modules/@noble/hashes/src/sha3-addons.ts new file mode 100644 index 0000000..a50a2ac --- /dev/null +++ b/node_modules/@noble/hashes/src/sha3-addons.ts @@ -0,0 +1,983 @@ +/** + * SHA3 (keccak) addons. + * + * * cSHAKE, KMAC, TupleHash, ParallelHash + XOF variants from + * {@link https://csrc.nist.gov/pubs/sp/800/185/final | NIST SP 800-185} + * * KangarooTwelve 🦘 and TurboSHAKE - reduced-round keccak from + * {@link https://datatracker.ietf.org/doc/rfc9861/ | RFC 9861} + * * KeccakPRG: Pseudo-random generator based on Keccak + * ({@link https://keccak.team/files/CSF-0.1.pdf | pdf}) + * @module + */ +import { Keccak, type ShakeOpts } from './sha3.ts'; +import { + abytes, + aexists, + anumber, + type CHash, + type CHashXOF, + clean, + copyBytes, + createHasher, + type Hash, + type HashXOF, + type KDFInput, + kdfInputToBytes, + type PRG, + type TArg, + type TRet, + u32, +} from './utils.ts'; + +// cSHAKE && KMAC (NIST SP800-185) +const _8n = /* @__PURE__ */ BigInt(8); +const _ffn = /* @__PURE__ */ BigInt(0xff); + +// It is safe to use bigints here, since they used only for length encoding (not actual data). +// We use bigints in sha256 for lengths too. +// Callers are still expected to supply SP 800-185-valid lengths +// (`0 <= x < 2^2040`); this helper does not enforce that bound. +function leftEncode(n: number | bigint): TRet { + n = BigInt(n); + const res = [Number(n & _ffn)]; + n >>= _8n; + for (; n > 0; n >>= _8n) res.unshift(Number(n & _ffn)); + res.unshift(res.length); + return new Uint8Array(res) as TRet; +} + +// Same caller contract as `leftEncode(...)`: lengths must already satisfy SP 800-185 §2.3.1. +function rightEncode(n: number | bigint): TRet { + n = BigInt(n); + const res = [Number(n & _ffn)]; + n >>= _8n; + for (; n > 0; n >>= _8n) res.unshift(Number(n & _ffn)); + res.push(res.length); + return new Uint8Array(res) as TRet; +} + +// `dkLen` validation is deferred to the downstream Keccak constructor. +function chooseLen(opts: ShakeOpts, outputLen: number): number { + return opts.dkLen === undefined ? outputLen : opts.dkLen; +} + +const abytesOrZero = (buf?: TArg, title = '') => { + if (buf === undefined) return EMPTY_BUFFER; + abytes(buf, undefined, title); + return buf; +}; +// NOTE: second modulo is necessary since we don't need to add padding if the +// current element takes a whole block. +// Callers only pass the fixed positive Keccak rates here (`168` or `136`); +// `block <= 0` is not validated locally. +const getPadding = (len: number, block: number) => new Uint8Array((block - (len % block)) % block); +/** Options for cSHAKE and related SP 800-185 functions. */ +export type cShakeOpts = ShakeOpts & { + /** Optional personalization string mixed into domain separation. */ + personalization?: Uint8Array; + /** + * Optional NIST function-name string used for domain separation. + * SP 800-185 reserves this for standardized function names; applications + * should generally stick to `personalization`. + */ + NISTfn?: KDFInput; +}; + +// Personalization +function cshakePers(hash: TArg, opts: TArg = {}): TRet { + const h = hash as unknown as Keccak; + if (!opts || (opts.personalization === undefined && opts.NISTfn === undefined)) + return h as TRet; + // Encode and pad inplace to avoid unneccesary memory copies/slices so we + // don't need to zero them later. + // bytepad(encode_string(N) || encode_string(S), rate), where `rate` is the + // current cSHAKE/KMAC/TupleHash/ParallelHash block length. + const blockLenBytes = leftEncode(h.blockLen); + const fn = opts.NISTfn === undefined ? EMPTY_BUFFER : kdfInputToBytes(opts.NISTfn); + const fnLen = leftEncode(_8n * BigInt(fn.length)); // length in bits + const pers = abytesOrZero(opts.personalization, 'personalization'); + const persLen = leftEncode(_8n * BigInt(pers.length)); // length in bits + if (!fn.length && !pers.length) return h as TRet; + // SP 800-185 cSHAKE appends `00` instead of SHAKE's `1111`; in this Keccak implementation + // that changes the delimited suffix byte from `0x1f` to `0x04` once N or S is non-empty. + h.suffix = 0x04; + h.update(blockLenBytes).update(fnLen).update(fn).update(persLen).update(pers); + let totalLen = blockLenBytes.length + fnLen.length + fn.length + persLen.length + pers.length; + h.update(getPadding(totalLen, h.blockLen)); + return h as TRet; +} + +const gencShake = ( + suffix: number, + blockLen: number, + outputLen: number +): TRet> => + createHasher( + (opts: TArg = {}) => + cshakePers( + new Keccak(blockLen, suffix, chooseLen(opts, outputLen), true) as unknown as TArg, + opts + ) as Keccak + ); + +/** TupleHash callable interface. */ +export type ITupleHash = { + /** + * Hashes an ordered tuple of byte arrays. + * @param messages - Ordered byte-array tuple to hash. + * @param opts - TupleHash output and personalization options. See {@link cShakeOpts}. + * @returns Digest bytes. + */ + (messages: TArg, opts?: TArg): TRet; + /** + * Creates an incremental TupleHash state. + * @param opts - TupleHash output and personalization options. See {@link cShakeOpts}. + * @returns Stateful TupleHash instance. + */ + create(opts?: cShakeOpts): _TupleHash; +}; +/** + * 128-bit NIST cSHAKE XOF. + * @param msg - message bytes to hash + * @param opts - Optional output, personalization, and NIST function-name + * settings. When both `NISTfn` and `personalization` are empty, + * SP 800-185 defines this as plain SHAKE128. Defaults to 16 output bytes + * when `dkLen` is omitted. See {@link cShakeOpts}. + * @returns Digest bytes. + * @example + * Hash a message with cSHAKE128. + * ```ts + * cshake128(new Uint8Array([1, 2, 3]), { dkLen: 32 }); + * ``` + */ +export const cshake128: TRet> = /* @__PURE__ */ gencShake( + 0x1f, + 168, + 16 +); +/** + * 256-bit NIST cSHAKE XOF. + * @param msg - message bytes to hash + * @param opts - Optional output, personalization, and NIST function-name + * settings. When both `NISTfn` and `personalization` are empty, + * SP 800-185 defines this as plain SHAKE256. Defaults to 32 output bytes + * when `dkLen` is omitted. See {@link cShakeOpts}. + * @returns Digest bytes. + * @example + * Hash a message with cSHAKE256. + * ```ts + * cshake256(new Uint8Array([1, 2, 3]), { dkLen: 64 }); + * ``` + */ +export const cshake256: TRet> = /* @__PURE__ */ gencShake( + 0x1f, + 136, + 32 +); + +/** + * Internal KMAC class. + * SP 800-185 §8.4.1 still recommends keys at least as long as the target + * security strength. + */ +export class _KMAC extends Keccak implements HashXOF<_KMAC> { + constructor( + blockLen: number, + outputLen: number, + enableXOF: boolean, + key: TArg, + opts: TArg = {} + ) { + super(blockLen, 0x1f, outputLen, enableXOF); + // Preload T = bytepad(encode_string("KMAC") || encode_string(S), rate); later updates append + // newX = bytepad(encode_string(K), rate) || X and `finish()` appends right_encode(L or 0). + cshakePers(this as unknown as TArg, { + NISTfn: 'KMAC', + personalization: opts.personalization, + }); + abytes(key, undefined, 'key'); + // 1. newX = bytepad(encode_string(K), rate) || X || right_encode(L), + // with `rate = this.blockLen`. + const blockLenBytes = leftEncode(this.blockLen); + const keyLen = leftEncode(_8n * BigInt(key.length)); + this.update(blockLenBytes).update(keyLen).update(key); + const totalLen = blockLenBytes.length + keyLen.length + key.length; + this.update(getPadding(totalLen, this.blockLen)); + } + protected finish(): void { + // SP 800-185 uses right_encode(L) for fixed-length KMAC and right_encode(0) for KMACXOF. + // outputLen in bits + if (!this.finished) this.update(rightEncode(this.enableXOF ? 0 : _8n * BigInt(this.outputLen))); + super.finish(); + } + _cloneInto(to?: _KMAC): _KMAC { + // Create new instance without calling constructor since the key + // is already in state and we don't know it. + // Force "to" to be instance of KMAC instead of Sha3. + if (!to) { + to = Object.create(Object.getPrototypeOf(this), {}) as _KMAC; + to.state = this.state.slice(); + to.blockLen = this.blockLen; + to.state32 = u32(to.state); + } + return super._cloneInto(to) as _KMAC; + } + clone(): _KMAC { + return this._cloneInto(); + } +} + +function genKmac(blockLen: number, outputLen: number, xof = false): TRet { + // One-shot XOF wrappers still finalize via `.digest()` because `_KMAC` + // already bakes the requested output length into the state. + const kmac = ( + key: TArg, + message: TArg, + opts?: TArg + ): TRet => kmac.create(key, opts).update(message).digest(); + kmac.create = (key: TArg, opts: TArg = {}) => + new _KMAC(blockLen, chooseLen(opts, outputLen), xof, key, opts); + return kmac as TRet; +} + +/** KMAC callable interface. */ +export type IKMAC = { + /** + * Computes a keyed KMAC digest for one message. + * @param key - Secret key bytes. + * @param message - Message bytes to authenticate. + * @param opts - KMAC output and personalization options. See {@link KangarooOpts}. + * @returns Authentication tag bytes. + */ + (key: TArg, message: TArg, opts?: TArg): TRet; + /** + * Creates an incremental KMAC state. + * @param key - Secret key bytes. + * @param opts - KMAC output and personalization options. See {@link cShakeOpts}. + * @returns Stateful KMAC instance. + */ + create(key: TArg, opts?: TArg): _KMAC; +}; +/** + * 128-bit Keccak MAC. + * @param key - MAC key bytes + * @param message - message bytes to authenticate + * @param opts - Optional output and personalization settings. Defaults to + * 16 output bytes when `dkLen` is omitted. See {@link cShakeOpts}. + * @returns Authentication tag bytes. + * @example + * Authenticate a message with KMAC128. + * ```ts + * kmac128(new Uint8Array([1, 2, 3]), new Uint8Array([4, 5, 6])); + * ``` + */ +export const kmac128: TRet = /* @__PURE__ */ genKmac(168, 16); +/** + * 256-bit Keccak MAC. + * @param key - MAC key bytes + * @param message - message bytes to authenticate + * @param opts - Optional output and personalization settings. Defaults to + * 32 output bytes when `dkLen` is omitted. See {@link cShakeOpts}. + * @returns Authentication tag bytes. + * @example + * Authenticate a message with KMAC256. + * ```ts + * kmac256(new Uint8Array([1, 2, 3]), new Uint8Array([4, 5, 6])); + * ``` + */ +export const kmac256: TRet = /* @__PURE__ */ genKmac(136, 32); +/** + * 128-bit Keccak-MAC XOF. + * @param key - MAC key bytes + * @param message - message bytes to authenticate + * @param opts - Optional output and personalization settings. Defaults to + * 16 output bytes when `dkLen` is omitted. See {@link cShakeOpts}. + * @returns Authentication tag bytes. + * @example + * Authenticate a message with KMAC128 XOF output. + * ```ts + * kmac128xof(new Uint8Array([1, 2, 3]), new Uint8Array([4, 5, 6]), { dkLen: 32 }); + * ``` + */ +export const kmac128xof: TRet = /* @__PURE__ */ genKmac(168, 16, true); +/** + * 256-bit Keccak-MAC XOF. + * @param key - MAC key bytes + * @param message - message bytes to authenticate + * @param opts - Optional output and personalization settings. Defaults to + * 32 output bytes when `dkLen` is omitted. See {@link cShakeOpts}. + * @returns Authentication tag bytes. + * @example + * Authenticate a message with KMAC256 XOF output. + * ```ts + * kmac256xof(new Uint8Array([1, 2, 3]), new Uint8Array([4, 5, 6]), { dkLen: 64 }); + * ``` + */ +export const kmac256xof: TRet = /* @__PURE__ */ genKmac(136, 32, true); + +/** + * Internal TupleHash class for byte-array tuple elements. + * This implementation relies on SP 800-185's byte-oriented encoding form + * rather than arbitrary bit strings. + */ +export class _TupleHash extends Keccak implements HashXOF<_TupleHash> { + constructor( + blockLen: number, + outputLen: number, + enableXOF: boolean, + opts: TArg = {} + ) { + super(blockLen, 0x1f, outputLen, enableXOF); + cshakePers(this as unknown as TArg, { + NISTfn: 'TupleHash', + personalization: opts.personalization, + }); + // Change update after cshake processed + this.update = (data: TArg) => { + abytes(data); + // SP 800-185 encodes each tuple element as + // encode_string(X[i]) = left_encode(len(X[i])) || X[i]. + super.update(leftEncode(_8n * BigInt(data.length))); + super.update(data); + return this; + }; + } + protected finish(): void { + // SP 800-185 uses right_encode(L) for fixed-length TupleHash + // and right_encode(0) for TupleHashXOF. + if (!this.finished) + // outputLen in bits + super.update(rightEncode(this.enableXOF ? 0 : _8n * BigInt(this.outputLen))); + super.finish(); + } + _cloneInto(to?: _TupleHash): _TupleHash { + to ||= new _TupleHash(this.blockLen, this.outputLen, this.enableXOF); + return super._cloneInto(to) as _TupleHash; + } + clone(): _TupleHash { + return this._cloneInto(); + } +} + +function genTuple(blockLen: number, outputLen: number, xof = false): TRet { + // One-shot XOF wrappers still use `.digest()` because `_TupleHash` stores + // the requested output length in the state itself. + const tuple = (messages: TArg, opts?: TArg): TRet => { + const h = tuple.create(opts); + if (!Array.isArray(messages)) throw new Error('expected array of messages'); + for (const msg of messages) h.update(msg); + return h.digest(); + }; + tuple.create = (opts: TArg = {}) => + new _TupleHash(blockLen, chooseLen(opts, outputLen), xof, opts); + return tuple as TRet; +} + +/** + * 128-bit TupleHASH. `tuple(['ab', 'cd']) != tuple(['a', 'bcd'])`. + * @param messages - ordered byte-array tuple + * @param opts - Optional output and personalization settings. Defaults to + * 16 output bytes when `dkLen` is omitted. See {@link cShakeOpts}. + * @returns Digest bytes. + * @example + * Hash a tuple of byte arrays with TupleHash128. + * ```ts + * tuplehash128([new Uint8Array([1]), new Uint8Array([2])]); + * ``` + */ +export const tuplehash128: TRet = /* @__PURE__ */ genTuple(168, 16); +/** + * 256-bit TupleHASH. `tuple(['ab', 'cd']) != tuple(['a', 'bcd'])`. + * @param messages - ordered byte-array tuple + * @param opts - Optional output and personalization settings. Defaults to + * 32 output bytes when `dkLen` is omitted. See {@link cShakeOpts}. + * @returns Digest bytes. + * @example + * Hash a tuple of byte arrays with TupleHash256. + * ```ts + * tuplehash256([new Uint8Array([1]), new Uint8Array([2])]); + * ``` + */ +export const tuplehash256: TRet = /* @__PURE__ */ genTuple(136, 32); +/** + * 128-bit TupleHASH XOF. + * @param messages - ordered byte-array tuple + * @param opts - Optional output and personalization settings. Defaults to + * 16 output bytes when `dkLen` is omitted. See {@link cShakeOpts}. + * @returns Digest bytes. + * @example + * Hash a tuple of byte arrays with TupleHash128 XOF output. + * ```ts + * tuplehash128xof([new Uint8Array([1]), new Uint8Array([2])], { dkLen: 32 }); + * ``` + */ +export const tuplehash128xof: TRet = /* @__PURE__ */ genTuple(168, 16, true); +/** + * 256-bit TupleHASH XOF. + * @param messages - ordered byte-array tuple + * @param opts - Optional output and personalization settings. Defaults to + * 32 output bytes when `dkLen` is omitted. See {@link cShakeOpts}. + * @returns Digest bytes. + * @example + * Hash a tuple of byte arrays with TupleHash256 XOF output. + * ```ts + * tuplehash256xof([new Uint8Array([1]), new Uint8Array([2])], { dkLen: 64 }); + * ``` + */ +export const tuplehash256xof: TRet = /* @__PURE__ */ genTuple(136, 32, true); + +// Same as K12/M14, but without speedup for inputs less 8kb, +// reduced number of rounds and simpler. +type ParallelOpts = KangarooOpts & { blockLen?: number }; + +/** Internal Parallel Keccak Hash class. */ +export class _ParallelHash extends Keccak implements HashXOF<_ParallelHash> { + private leafHash?: Hash; + protected leafCons: () => Hash; + private chunkPos = 0; // Position of current block in chunk + private chunksDone = 0; // How many chunks we already have + private chunkLen: number; + constructor( + blockLen: number, + outputLen: number, + leafCons: () => Hash, + enableXOF: boolean, + opts: TArg = {} + ) { + super(blockLen, 0x1f, outputLen, enableXOF); + cshakePers(this as unknown as TArg, { + NISTfn: 'ParallelHash', + personalization: opts.personalization, + }); + this.leafCons = leafCons; + let { blockLen: B = 8 } = opts; + anumber(B); + // blockLen=0 makes take=0 in update(), so pos never advances and the hash hangs. + if (B < 1) throw new Error('"blockLen" must be >= 1, got ' + B); + this.chunkLen = B; + // SP 800-185 initializes z = left_encode(B); each completed chunk appends + // one fixed-size cSHAKE leaf digest before finish() adds right_encode(n) + // and right_encode(L or 0). + super.update(leftEncode(B)); + // Change update after cshake processed + this.update = (data: TArg) => { + abytes(data); + const { chunkLen, leafCons } = this; + for (let pos = 0, len = data.length; pos < len; ) { + if (this.chunkPos == chunkLen || !this.leafHash) { + if (this.leafHash) { + super.update(this.leafHash.digest()); + this.chunksDone++; + } + this.leafHash = leafCons(); + this.chunkPos = 0; + } + const take = Math.min(chunkLen - this.chunkPos, len - pos); + this.leafHash.update(data.subarray(pos, pos + take)); + this.chunkPos += take; + pos += take; + } + return this; + }; + } + protected finish(): void { + if (this.finished) return; + if (this.leafHash) { + super.update(this.leafHash.digest()); + this.chunksDone++; + } + // SP 800-185 finishes ParallelHash as + // z || right_encode(n) || right_encode(L); XOF mode replaces + // right_encode(L) with right_encode(0). + super.update(rightEncode(this.chunksDone)); + // outputLen in bits + super.update(rightEncode(this.enableXOF ? 0 : _8n * BigInt(this.outputLen))); + super.finish(); + } + _cloneInto(to?: _ParallelHash): _ParallelHash { + to ||= new _ParallelHash(this.blockLen, this.outputLen, this.leafCons, this.enableXOF); + to.leafCons = this.leafCons; + // Reused destinations can carry a stale partial leaf + // when the source is still on the root sponge. + if (this.leafHash) to.leafHash = this.leafHash._cloneInto(to.leafHash as Keccak); + else if (to.leafHash) { + to.leafHash.destroy(); + to.leafHash = undefined; + } + to.chunkPos = this.chunkPos; + to.chunkLen = this.chunkLen; + to.chunksDone = this.chunksDone; + return super._cloneInto(to) as _ParallelHash; + } + destroy(): void { + super.destroy.call(this); + if (this.leafHash) this.leafHash.destroy(); + } + clone(): _ParallelHash { + return this._cloneInto(); + } +} + +function genPrl( + blockLen: number, + outputLen: number, + leaf: ReturnType, + xof = false +): TRet> { + const parallel = (message: TArg, opts?: TArg): TRet => + parallel.create(opts).update(message).digest(); + parallel.create = (opts: TArg = {}) => + new _ParallelHash( + blockLen, + chooseLen(opts, outputLen), + // SP 800-185 fixes leaf digests at 256 bits for ParallelHash128 and + // 512 bits for ParallelHash256; only the final cSHAKE output uses the + // caller-selected dkLen. + () => leaf.create({ dkLen: 2 * outputLen }), + xof, + opts + ); + parallel.outputLen = outputLen; + parallel.blockLen = blockLen; + parallel.canXOF = xof; + return parallel as TRet>; +} + +/** + * 128-bit ParallelHash. In JS, it is not parallel. + * @param msg - message bytes to hash + * @param opts - Optional output, personalization, and chunking settings. + * Defaults to 16 output bytes when `dkLen` is omitted. + * See {@link ParallelOpts}. + * @returns Digest bytes. + * @example + * Hash a message with ParallelHash128. + * ```ts + * parallelhash128(new Uint8Array([1, 2, 3])); + * ``` + */ +export const parallelhash128: TRet> = /* @__PURE__ */ genPrl( + 168, + 16, + cshake128 +); +/** + * 256-bit ParallelHash. In JS, it is not parallel. + * @param msg - message bytes to hash + * @param opts - Optional output, personalization, and chunking settings. + * Defaults to 32 output bytes when `dkLen` is omitted. + * See {@link ParallelOpts}. + * @returns Digest bytes. + * @example + * Hash a message with ParallelHash256. + * ```ts + * parallelhash256(new Uint8Array([1, 2, 3])); + * ``` + */ +export const parallelhash256: TRet> = /* @__PURE__ */ genPrl( + 136, + 32, + cshake256 +); +/** + * 128-bit ParallelHash XOF. In JS, it is not parallel. + * @param msg - message bytes to hash + * @param opts - Optional output, personalization, and chunking settings. + * Defaults to 16 output bytes when `dkLen` is omitted. + * See {@link ParallelOpts}. + * @returns Digest bytes. + * @example + * Hash a message with ParallelHash128 XOF output. + * ```ts + * parallelhash128xof(new Uint8Array([1, 2, 3]), { dkLen: 32 }); + * ``` + */ +export const parallelhash128xof: TRet> = /* @__PURE__ */ genPrl( + 168, + 16, + cshake128, + true +); +/** + * 256-bit ParallelHash XOF. In JS, it is not parallel. + * @param msg - message bytes to hash + * @param opts - Optional output, personalization, and chunking settings. + * Defaults to 32 output bytes when `dkLen` is omitted. + * See {@link ParallelOpts}. + * @returns Digest bytes. + * @example + * Hash a message with ParallelHash256 XOF output. + * ```ts + * parallelhash256xof(new Uint8Array([1, 2, 3]), { dkLen: 64 }); + * ``` + */ +export const parallelhash256xof: TRet> = /* @__PURE__ */ genPrl( + 136, + 32, + cshake256, + true +); + +/** + * TurboSHAKE options. + * `D` is the domain separation byte; RFC 9861 defines output length `L` + * as a positive integer. + */ +export type TurboshakeOpts = ShakeOpts & { + /** Optional domain separation byte in the `0x01..0x7f` range. */ + D?: number; +}; + +const genTurbo = (blockLen: number, outputLen: number) => + createHasher((opts: TArg = {}) => { + const D = opts.D === undefined ? 0x1f : opts.D; + // RFC 9861 §2.1 fixes the default `D = 0x1f`; §2.2 defines the 12-round + // TurboSHAKE family selected here. + if (!Number.isSafeInteger(D) || D < 0x01 || D > 0x7f) + throw new Error('"D" (domain separation byte) must be 0x01..0x7f, got: ' + D); + const dkLen = opts.dkLen === undefined ? outputLen : opts.dkLen; + // RFC 9861 §§2.1-2.2 define output length L as a positive integer. + if (dkLen < 1) throw new Error('"dkLen" must be >= 1'); + return new Keccak(blockLen, D, dkLen, true, 12); + }); + +/** + * TurboSHAKE 128-bit: reduced 12-round keccak. + * Should've been a simple "shake with 12 rounds", but we got a whole new + * spec about Turbo SHAKE Pro MAX. + * @param msg - message bytes to hash + * @param opts - Optional output-length and domain-separation settings. + * RFC 9861 §2.1 defaults `D` to `0x1f`. Defaults to 32 output bytes when + * `dkLen` is omitted. See {@link TurboshakeOpts}. + * @returns Digest bytes. + * @example + * Hash a message with TurboSHAKE128. + * ```ts + * turboshake128(new Uint8Array([1, 2, 3]), { dkLen: 32 }); + * ``` + */ +export const turboshake128: TRet> = /* @__PURE__ */ genTurbo( + 168, + 32 +); +/** + * TurboSHAKE 256-bit: reduced 12-round keccak. + * @param msg - message bytes to hash + * @param opts - Optional output-length and domain-separation settings. + * RFC 9861 §2.1 defaults `D` to `0x1f`. Defaults to 64 output bytes when + * `dkLen` is omitted. See {@link TurboshakeOpts}. + * @returns Digest bytes. + * @example + * Hash a message with TurboSHAKE256. + * ```ts + * turboshake256(new Uint8Array([1, 2, 3]), { dkLen: 64 }); + * ``` + */ +export const turboshake256: TRet> = /* @__PURE__ */ genTurbo( + 136, + 64 +); + +// Same as NIST rightEncode, but returns `[0]` for the zero string. +// Callers still need to keep `x < 256^255` per RFC 9861 §3.3. +function rightEncodeK12(n: number | bigint): TRet { + n = BigInt(n); + const res: number[] = []; + for (; n > 0; n >>= _8n) res.unshift(Number(n & _ffn)); + res.push(res.length); + return Uint8Array.from(res); +} + +/** K12 options. */ +export type KangarooOpts = { + /** + * Desired digest length in bytes. + * RFC 9861 §3 defines output length `L` as a positive integer. + */ + dkLen?: number; + /** + * Optional personalization string mixed into the sponge state. + * Stateful K12 instances keep an internal copy so caller buffers can be + * wiped independently. + */ + personalization?: Uint8Array; +}; +const EMPTY_BUFFER = /* @__PURE__ */ Uint8Array.of(); + +/** Internal K12 hash class. */ +export class _KangarooTwelve extends Keccak implements HashXOF<_KangarooTwelve> { + readonly chunkLen = 8192; + private leafHash?: Keccak; + protected leafLen: number; + private personalization: Uint8Array; + private chunkPos = 0; // Position of current block in chunk + private chunksDone = 0; // How many chunks we already have + constructor( + blockLen: number, + leafLen: number, + outputLen: number, + rounds: number, + opts: TArg + ) { + super(blockLen, 0x07, outputLen, true, rounds); + // RFC 9861 §3 defines output length L as a positive integer. + if (outputLen < 1) throw new Error('"dkLen" must be >= 1'); + this.leafLen = leafLen; + this.personalization = + opts.personalization === undefined + ? EMPTY_BUFFER + : copyBytes(abytes(opts.personalization, undefined, 'personalization')); + } + update(data: TArg): this { + abytes(data); + const { chunkLen, blockLen, leafLen, rounds } = this; + for (let pos = 0, len = data.length; pos < len; ) { + if (this.chunkPos == chunkLen) { + if (this.leafHash) super.update(this.leafHash.digest()); + else { + // RFC 9861 §3.2 switches from SingleNode (`07`) to FinalNode (`06`) + // once S exceeds 8192 bytes and prefixes S_0 with + // `03 00 00 00 00 00 00 00`. + this.suffix = 0x06; // Its safe to change suffix here since its used only in digest() + super.update(Uint8Array.from([3, 0, 0, 0, 0, 0, 0, 0])); + } + // Secondary chunks S_1..S_(n-1) become fixed-length + // CV_i = TurboSHAKE*(S_i, `0B`, 32|64) chaining values. + this.leafHash = new Keccak(blockLen, 0x0b, leafLen, false, rounds); + this.chunksDone++; + this.chunkPos = 0; + } + const take = Math.min(chunkLen - this.chunkPos, len - pos); + const chunk = data.subarray(pos, pos + take); + if (this.leafHash) this.leafHash.update(chunk); + else super.update(chunk); + this.chunkPos += take; + pos += take; + } + return this; + } + protected finish(): void { + if (this.finished) return; + const { personalization } = this; + // RFC 9861 §3.2 forms S = M || C || length_encode(|C|) before any tree hashing logic. + this.update(personalization).update(rightEncodeK12(personalization.length)); + // Leaf hash + if (this.leafHash) { + // Multi-chunk K12 appends + // CV_1..CV_(n-1) || length_encode(n-1) || `FF FF` + // before the final TurboSHAKE call. + super.update(this.leafHash.digest()); + super.update(rightEncodeK12(this.chunksDone)); + super.update(Uint8Array.from([0xff, 0xff])); + } + super.finish.call(this); + } + destroy(): void { + super.destroy.call(this); + if (this.leafHash) this.leafHash.destroy(); + // Personalization is copied on create/clone, so destroy can wipe it + // without touching caller input. + if (this.personalization !== EMPTY_BUFFER) clean(this.personalization); + this.personalization = EMPTY_BUFFER; + } + _cloneInto(to?: _KangarooTwelve): _KangarooTwelve { + const { blockLen, leafLen, leafHash, outputLen, rounds } = this; + const personalization = + this.personalization === EMPTY_BUFFER ? EMPTY_BUFFER : copyBytes(this.personalization); + // Personalization is absorbed only during finish(), so clones need the same pending value. + to ||= new _KangarooTwelve(blockLen, leafLen, outputLen, rounds, { + personalization, + }); + super._cloneInto(to); + // Reused destinations can carry a stale leaf from an older multi-chunk state. + if (leafHash) to.leafHash = leafHash._cloneInto(to.leafHash); + else if (to.leafHash) { + to.leafHash.destroy(); + to.leafHash = undefined; + } + // Snapshot the pending personalization so clone state does not alias caller-owned input. + to.personalization = personalization; + to.leafLen = this.leafLen; + to.chunkPos = this.chunkPos; + to.chunksDone = this.chunksDone; + return to; + } + clone(): _KangarooTwelve { + return this._cloneInto(); + } +} + +/** + * 128-bit KangarooTwelve (k12): reduced 12-round keccak. + * @param msg - message bytes to hash + * @param opts - Optional output and personalization settings. Defaults to + * 32 output bytes when `dkLen` is omitted. See {@link KangarooOpts}. + * @returns Digest bytes. + * @example + * Hash a message with KangarooTwelve-128. + * ```ts + * kt128(new Uint8Array([1, 2, 3])); + * ``` + */ +export const kt128: TRet> = /* @__PURE__ */ createHasher( + (opts: TArg = {}) => new _KangarooTwelve(168, 32, chooseLen(opts, 32), 12, opts) +); +/** + * 256-bit KangarooTwelve (k12): reduced 12-round keccak. + * @param msg - message bytes to hash + * @param opts - Optional output and personalization settings. Defaults to + * 64 output bytes when `dkLen` is omitted. See {@link KangarooOpts}. + * @returns Digest bytes. + * @example + * Hash a message with KangarooTwelve-256. + * ```ts + * kt256(new Uint8Array([1, 2, 3])); + * ``` + */ +export const kt256: TRet> = /* @__PURE__ */ createHasher( + (opts: TArg = {}) => new _KangarooTwelve(136, 64, chooseLen(opts, 64), 12, opts) +); + +// MarsupilamiFourteen (14-rounds) can be defined as: +// `new KangarooTwelve(136, 64, chooseLen(opts, 64), 14, opts)` + +/** KangarooTwelve-based MAC function type. */ +export type HopMAC = ( + key: TArg, + message: TArg, + personalization: TArg, + dkLen?: number +) => TRet; +const genHopMAC = + (hash: TArg>): TRet => + ( + key: TArg, + message: TArg, + personalization: TArg, + dkLen?: number + ) => { + const h = hash as unknown as CHash<_KangarooTwelve, KangarooOpts>; + return h(key, { personalization: h(message, { personalization }), dkLen }) as TRet; + }; + +/** + * 128-bit KangarooTwelve-based MAC. + * + * These untested (there is no test vectors or implementation available). Use at your own risk. + * HopMAC128(Key, M, C, L) = KT128(Key, KT128(M, C, 32), L) + * HopMAC256(Key, M, C, L) = KT256(Key, KT256(M, C, 64), L) + * The inner KangarooTwelve call always uses a fixed 32-byte digest here, + * regardless of the outer `dkLen`. + * @param key - MAC key bytes + * @param message - message bytes to authenticate + * @param personalization - personalization bytes mixed into the inner hash + * @param dkLen - optional output length in bytes + * @returns Authentication tag bytes. + * @example + * Authenticate a message with HopMAC128. + * ```ts + * HopMAC128(new Uint8Array([1]), new Uint8Array([2]), new Uint8Array([3]), 32); + * ``` + */ +export const HopMAC128: TRet = /* @__PURE__ */ genHopMAC(kt128); +/** + * 256-bit KangarooTwelve-based MAC. + * Like `HopMAC128`, there are no test vectors or known independent + * implementations available for cross-checking. + * @param key - MAC key bytes + * @param message - message bytes to authenticate + * @param personalization - personalization bytes mixed into the inner hash + * @param dkLen - optional output length in bytes. The inner KangarooTwelve + * call still uses a fixed 64-byte digest here, regardless of the outer + * `dkLen`. + * @returns Authentication tag bytes. + * @example + * Authenticate a message with HopMAC256. + * ```ts + * HopMAC256(new Uint8Array([1]), new Uint8Array([2]), new Uint8Array([3]), 64); + * ``` + */ +export const HopMAC256: TRet = /* @__PURE__ */ genHopMAC(kt256); + +/** + * More at + * {@link https://github.com/XKCP/XKCP/tree/master/lib/high/Keccak/PRG}. + * Accepted capacities must keep `rho = 1598 - capacity` byte-aligned, and + * `.clean()` later also requires `rate > 801`. + */ +export class _KeccakPRG extends Keccak implements PRG { + protected rate: number; + constructor(capacity: number) { + anumber(capacity); + const rate = 1600 - capacity; + const rho = rate - 2; + // Rho must be full bytes + if (capacity < 0 || capacity > 1600 - 10 || rho % 8) throw new Error('invalid capacity'); + // blockLen = rho in bytes + super(rho / 8, 0, 0, true); + this.rate = rate; + this.posOut = Math.floor((rate + 7) / 8); + } + protected keccak(): void { + // Duplex padding + this.state[this.pos] ^= 0x01; + this.state[this.blockLen] ^= 0x02; // Rho is full bytes + super.keccak(); + this.pos = 0; + this.posOut = 0; + } + update(data: TArg): this { + super.update(data); + this.posOut = this.blockLen; + return this; + } + protected finish(): void {} + digestInto(_out: TArg): void { + throw new Error('digest is not allowed, use .randomBytes() instead'); + } + addEntropy(seed: TArg): void { + this.update(seed); + } + randomBytes(length: number): TRet { + return this.xof(length); + } + clean(): void { + // clean() mutates live sponge state just like randomBytes(), + // so destroyed instances must reject it. + aexists(this, false); + if (this.rate < 1600 / 2 + 1) throw new Error('rate is too low to use .forget()'); + this.keccak(); + for (let i = 0; i < this.blockLen; i++) this.state[i] = 0; + this.pos = this.blockLen; + this.keccak(); + this.posOut = this.blockLen; + } + _cloneInto(to?: _KeccakPRG): _KeccakPRG { + const { rate } = this; + to ||= new _KeccakPRG(1600 - rate); + super._cloneInto(to); + to.rate = rate; + return to; + } + clone(): _KeccakPRG { + return this._cloneInto(); + } +} + +/** + * KeccakPRG: pseudo-random generator based on Keccak. + * See {@link https://keccak.team/files/CSF-0.1.pdf}. + * @param capacity - sponge capacity in bits. Accepted values are those that + * keep `rho = 1598 - capacity` byte-aligned; the default `254` is chosen + * because it satisfies that duplex layout while leaving a wide byte-aligned + * rate. + * @returns PRG instance backed by a Keccak sponge. + * @example + * Create a Keccak-based pseudorandom generator and read bytes from it. + * ```ts + * const prg = keccakprg(254); + * prg.randomBytes(8); + * ``` + */ +export const keccakprg = (capacity = 254): TRet<_KeccakPRG> => + new _KeccakPRG(capacity) as TRet<_KeccakPRG>; diff --git a/node_modules/@noble/hashes/src/sha3.ts b/node_modules/@noble/hashes/src/sha3.ts new file mode 100644 index 0000000..c81af06 --- /dev/null +++ b/node_modules/@noble/hashes/src/sha3.ts @@ -0,0 +1,485 @@ +/** + * SHA3 (keccak) hash function, based on a new "Sponge function" design. + * Different from older hashes, the internal state is bigger than output size. + * + * Check out + * {@link https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf | FIPS-202}, + * {@link https://keccak.team/keccak.html | Website}, and + * {@link https://crypto.stackexchange.com/q/15727 | the differences between + * SHA-3 and Keccak}. + * + * Check out `sha3-addons` module for cSHAKE, k12, and others. + * @module + */ +import { rotlBH, rotlBL, rotlSH, rotlSL, split } from './_u64.ts'; +// prettier-ignore +import { + abytes, aexists, anumber, aoutput, + clean, createHasher, + oidNist, + swap32IfBE, + u32, + type CHash, type CHashXOF, + type Hash, + type HashInfo, + type HashXOF, + type TArg, + type TRet +} from './utils.ts'; + +// No __PURE__ annotations in sha3 header: +// EVERYTHING is in fact used on every export. +// Various per round constants calculations +const _0n = BigInt(0); +const _1n = BigInt(1); +const _2n = BigInt(2); +const _7n = BigInt(7); +const _256n = BigInt(256); +// FIPS 202 Algorithm 5 rc(): when the outgoing bit is 1, the 8-bit LFSR xors +// taps 0, 4, 5, and 6, which compresses to the feedback mask `0x71`. +const _0x71n = BigInt(0x71); +const SHA3_PI: number[] = []; +const SHA3_ROTL: number[] = []; +const _SHA3_IOTA: bigint[] = []; // no pure annotation: var is always used +for (let round = 0, R = _1n, x = 1, y = 0; round < 24; round++) { + // Pi + [x, y] = [y, (2 * x + 3 * y) % 5]; + SHA3_PI.push(2 * (5 * y + x)); + // Rotational + SHA3_ROTL.push((((round + 1) * (round + 2)) / 2) % 64); + // Iota + let t = _0n; + for (let j = 0; j < 7; j++) { + R = ((R << _1n) ^ ((R >> _7n) * _0x71n)) % _256n; + if (R & _2n) t ^= _1n << ((_1n << BigInt(j)) - _1n); + } + _SHA3_IOTA.push(t); +} +const IOTAS = split(_SHA3_IOTA, true); +// `split(..., true)` keeps the local little-endian lane-word layout used by +// `state32`, so these `H` / `L` tables follow the file's first-word / +// second-word lane slots rather than `_u64.ts`'s usual high/low naming. +const SHA3_IOTA_H = IOTAS[0]; +const SHA3_IOTA_L = IOTAS[1]; + +// Left rotation (without 0, 32, 64) +const rotlH = (h: number, l: number, s: number) => (s > 32 ? rotlBH(h, l, s) : rotlSH(h, l, s)); +const rotlL = (h: number, l: number, s: number) => (s > 32 ? rotlBL(h, l, s) : rotlSL(h, l, s)); + +/** + * `keccakf1600` internal permutation, additionally allows adjusting the round count. + * @param s - 5x5 Keccak state encoded as 25 lanes split into 50 uint32 words + * in this file's local little-endian lane-word order + * @param rounds - number of rounds to execute + * @throws If `rounds` is outside the supported `1..24` range. {@link Error} + * @example + * Permute a Keccak state with the default 24 rounds. + * ```ts + * keccakP(new Uint32Array(50)); + * ``` + */ +export function keccakP(s: TArg, rounds: number = 24): void { + anumber(rounds, 'rounds'); + // This implementation precomputes only the standard Keccak-f[1600] 24-round Iota table. + if (rounds < 1 || rounds > 24) throw new Error('"rounds" expected integer 1..24'); + const B = new Uint32Array(5 * 2); + // NOTE: all indices are x2 since we store state as u32 instead of u64 (bigints to slow in js) + for (let round = 24 - rounds; round < 24; round++) { + // Theta θ + for (let x = 0; x < 10; x++) B[x] = s[x] ^ s[x + 10] ^ s[x + 20] ^ s[x + 30] ^ s[x + 40]; + for (let x = 0; x < 10; x += 2) { + const idx1 = (x + 8) % 10; + const idx0 = (x + 2) % 10; + const B0 = B[idx0]; + const B1 = B[idx0 + 1]; + const Th = rotlH(B0, B1, 1) ^ B[idx1]; + const Tl = rotlL(B0, B1, 1) ^ B[idx1 + 1]; + for (let y = 0; y < 50; y += 10) { + s[x + y] ^= Th; + s[x + y + 1] ^= Tl; + } + } + // Rho (ρ) and Pi (π) + let curH = s[2]; + let curL = s[3]; + for (let t = 0; t < 24; t++) { + const shift = SHA3_ROTL[t]; + const Th = rotlH(curH, curL, shift); + const Tl = rotlL(curH, curL, shift); + const PI = SHA3_PI[t]; + curH = s[PI]; + curL = s[PI + 1]; + s[PI] = Th; + s[PI + 1] = Tl; + } + // Chi (χ) + // Same as: + // for (let x = 0; x < 10; x++) B[x] = s[y + x]; + // for (let x = 0; x < 10; x++) s[y + x] ^= ~B[(x + 2) % 10] & B[(x + 4) % 10]; + for (let y = 0; y < 50; y += 10) { + const b0 = s[y], + b1 = s[y + 1], + b2 = s[y + 2], + b3 = s[y + 3]; + s[y] ^= ~s[y + 2] & s[y + 4]; + s[y + 1] ^= ~s[y + 3] & s[y + 5]; + s[y + 2] ^= ~s[y + 4] & s[y + 6]; + s[y + 3] ^= ~s[y + 5] & s[y + 7]; + s[y + 4] ^= ~s[y + 6] & s[y + 8]; + s[y + 5] ^= ~s[y + 7] & s[y + 9]; + s[y + 6] ^= ~s[y + 8] & b0; + s[y + 7] ^= ~s[y + 9] & b1; + s[y + 8] ^= ~b0 & b2; + s[y + 9] ^= ~b1 & b3; + } + // Iota (ι) + s[0] ^= SHA3_IOTA_H[round]; + s[1] ^= SHA3_IOTA_L[round]; + } + clean(B); +} + +/** + * Keccak sponge function. + * @param blockLen - absorb/squeeze rate in bytes + * @param suffix - domain separation suffix byte + * @param outputLen - default digest length in bytes. This base sponge only + * requires a non-negative integer; wrappers that need positive output + * lengths must enforce that themselves. + * @param enableXOF - whether XOF output is allowed + * @param rounds - number of Keccak-f rounds + * @example + * Build a sponge state, absorb bytes, then finalize a digest. + * ```ts + * const hash = new Keccak(136, 0x06, 32); + * hash.update(new Uint8Array([1, 2, 3])); + * hash.digest(); + * ``` + */ +export class Keccak implements Hash, HashXOF { + protected state: Uint8Array; + protected pos = 0; + protected posOut = 0; + protected finished = false; + protected state32: Uint32Array; + protected destroyed = false; + + public blockLen: number; + public suffix: number; + public outputLen: number; + public canXOF: boolean; + protected enableXOF = false; + protected rounds: number; + + // NOTE: we accept arguments in bytes instead of bits here. + constructor( + blockLen: number, + suffix: number, + outputLen: number, + enableXOF = false, + rounds: number = 24 + ) { + this.blockLen = blockLen; + this.suffix = suffix; + this.outputLen = outputLen; + this.enableXOF = enableXOF; + this.canXOF = enableXOF; + this.rounds = rounds; + // Can be passed from user as dkLen + anumber(outputLen, 'outputLen'); + // 1600 = 5x5 matrix of 64bit. 1600 bits === 200 bytes + // 0 < blockLen < 200 + if (!(0 < blockLen && blockLen < 200)) + throw new Error('only keccak-f1600 function is supported'); + this.state = new Uint8Array(200); + this.state32 = u32(this.state); + } + clone(): Keccak { + return this._cloneInto(); + } + protected keccak(): void { + swap32IfBE(this.state32); + keccakP(this.state32, this.rounds); + swap32IfBE(this.state32); + this.posOut = 0; + this.pos = 0; + } + update(data: TArg): this { + aexists(this); + abytes(data); + const { blockLen, state } = this; + const len = data.length; + for (let pos = 0; pos < len; ) { + const take = Math.min(blockLen - this.pos, len - pos); + for (let i = 0; i < take; i++) state[this.pos++] ^= data[pos++]; + if (this.pos === blockLen) this.keccak(); + } + return this; + } + protected finish(): void { + if (this.finished) return; + this.finished = true; + const { state, suffix, pos, blockLen } = this; + // FIPS 202 appends the SHA3/SHAKE domain-separation suffix before pad10*1. + // These byte values already include the first padding bit, while the + // final `0x80` below supplies the closing `1` bit in the last rate byte. + state[pos] ^= suffix; + // If that combined suffix lands in the last rate byte and already sets + // bit 7, absorb it first so the final pad10*1 bit can be xored into a + // fresh block. + if ((suffix & 0x80) !== 0 && pos === blockLen - 1) this.keccak(); + state[blockLen - 1] ^= 0x80; + this.keccak(); + } + protected writeInto(out: TArg): TRet { + aexists(this, false); + abytes(out); + this.finish(); + const bufferOut = this.state; + const { blockLen } = this; + for (let pos = 0, len = out.length; pos < len; ) { + if (this.posOut >= blockLen) this.keccak(); + const take = Math.min(blockLen - this.posOut, len - pos); + out.set(bufferOut.subarray(this.posOut, this.posOut + take), pos); + this.posOut += take; + pos += take; + } + return out as TRet; + } + xofInto(out: TArg): TRet { + // Plain SHA3/Keccak usage with XOF is probably a mistake, but this base + // class is also reused by SHAKE/cSHAKE/KMAC/TupleHash/ParallelHash/ + // TurboSHAKE/KangarooTwelve wrappers that intentionally enable XOF. + if (!this.enableXOF) throw new Error('XOF is not possible for this instance'); + return this.writeInto(out); + } + xof(bytes: number): TRet { + anumber(bytes); + return this.xofInto(new Uint8Array(bytes)); + } + digestInto(out: TArg): void { + aoutput(out, this); + if (this.finished) throw new Error('digest() was already called'); + // `aoutput(...)` allows oversized buffers; digestInto() must fill only the advertised digest. + this.writeInto(out.subarray(0, this.outputLen)); + this.destroy(); + } + digest(): TRet { + const out = new Uint8Array(this.outputLen); + this.digestInto(out); + return out as TRet; + } + destroy(): void { + this.destroyed = true; + clean(this.state); + } + _cloneInto(to?: Keccak): Keccak { + const { blockLen, suffix, outputLen, rounds, enableXOF } = this; + to ||= new Keccak(blockLen, suffix, outputLen, enableXOF, rounds); + // Reused destinations can come from a different rate/capacity variant, so clone must rewrite + // the sponge geometry as well as the state words. + to.blockLen = blockLen; + to.state32.set(this.state32); + to.pos = this.pos; + to.posOut = this.posOut; + to.finished = this.finished; + to.rounds = rounds; + // Suffix can change in cSHAKE + to.suffix = suffix; + to.outputLen = outputLen; + to.enableXOF = enableXOF; + // Clones must preserve the public capability bit too; `_KMAC` reuses this path and deep clone + // tests compare instance fields directly, so leaving `canXOF` behind makes the clone lie. + to.canXOF = this.canXOF; + to.destroyed = this.destroyed; + return to; + } +} + +const genKeccak = ( + suffix: number, + blockLen: number, + outputLen: number, + info: TArg = {} +) => createHasher(() => new Keccak(blockLen, suffix, outputLen), info); + +/** + * SHA3-224 hash function. + * @param msg - message bytes to hash + * @returns Digest bytes. + * @example + * Hash a message with SHA3-224. + * ```ts + * sha3_224(new Uint8Array([97, 98, 99])); + * ``` + */ +export const sha3_224: TRet = /* @__PURE__ */ genKeccak( + 0x06, + 144, + 28, + /* @__PURE__ */ oidNist(0x07) +); +/** + * SHA3-256 hash function. Different from keccak-256. + * @param msg - message bytes to hash + * @returns Digest bytes. + * @example + * Hash a message with SHA3-256. + * ```ts + * sha3_256(new Uint8Array([97, 98, 99])); + * ``` + */ +export const sha3_256: TRet = /* @__PURE__ */ genKeccak( + 0x06, + 136, + 32, + /* @__PURE__ */ oidNist(0x08) +); +/** + * SHA3-384 hash function. + * @param msg - message bytes to hash + * @returns Digest bytes. + * @example + * Hash a message with SHA3-384. + * ```ts + * sha3_384(new Uint8Array([97, 98, 99])); + * ``` + */ +export const sha3_384: TRet = /* @__PURE__ */ genKeccak( + 0x06, + 104, + 48, + /* @__PURE__ */ oidNist(0x09) +); +/** + * SHA3-512 hash function. + * @param msg - message bytes to hash + * @returns Digest bytes. + * @example + * Hash a message with SHA3-512. + * ```ts + * sha3_512(new Uint8Array([97, 98, 99])); + * ``` + */ +export const sha3_512: TRet = /* @__PURE__ */ genKeccak( + 0x06, + 72, + 64, + /* @__PURE__ */ oidNist(0x0a) +); + +/** + * Keccak-224 hash function. + * @param msg - message bytes to hash + * @returns Digest bytes. + * @example + * Hash a message with Keccak-224. + * ```ts + * keccak_224(new Uint8Array([97, 98, 99])); + * ``` + */ +export const keccak_224: TRet = /* @__PURE__ */ genKeccak(0x01, 144, 28); +/** + * Keccak-256 hash function. Different from SHA3-256. + * @param msg - message bytes to hash + * @returns Digest bytes. + * @example + * Hash a message with Keccak-256. + * ```ts + * keccak_256(new Uint8Array([97, 98, 99])); + * ``` + */ +export const keccak_256: TRet = /* @__PURE__ */ genKeccak(0x01, 136, 32); +/** + * Keccak-384 hash function. + * @param msg - message bytes to hash + * @returns Digest bytes. + * @example + * Hash a message with Keccak-384. + * ```ts + * keccak_384(new Uint8Array([97, 98, 99])); + * ``` + */ +export const keccak_384: TRet = /* @__PURE__ */ genKeccak(0x01, 104, 48); +/** + * Keccak-512 hash function. + * @param msg - message bytes to hash + * @returns Digest bytes. + * @example + * Hash a message with Keccak-512. + * ```ts + * keccak_512(new Uint8Array([97, 98, 99])); + * ``` + */ +export const keccak_512: TRet = /* @__PURE__ */ genKeccak(0x01, 72, 64); + +/** Options for SHAKE XOF. */ +export type ShakeOpts = { + /** Desired number of output bytes. */ + dkLen?: number; +}; + +const genShake = (suffix: number, blockLen: number, outputLen: number, info: TArg = {}) => + createHasher( + (opts: ShakeOpts = {}) => + new Keccak(blockLen, suffix, opts.dkLen === undefined ? outputLen : opts.dkLen, true), + info + ); + +/** + * SHAKE128 XOF with 128-bit security and a 16-byte default output. + * @param msg - message bytes to hash + * @param opts - Optional output-length override. See {@link ShakeOpts}. + * @returns Digest bytes. + * @example + * Hash a message with SHAKE128. + * ```ts + * shake128(new Uint8Array([97, 98, 99]), { dkLen: 32 }); + * ``` + */ +export const shake128: TRet> = + /* @__PURE__ */ + genShake(0x1f, 168, 16, /* @__PURE__ */ oidNist(0x0b)); +/** + * SHAKE256 XOF with 256-bit security and a 32-byte default output. + * @param msg - message bytes to hash + * @param opts - Optional output-length override. See {@link ShakeOpts}. + * @returns Digest bytes. + * @example + * Hash a message with SHAKE256. + * ```ts + * shake256(new Uint8Array([97, 98, 99]), { dkLen: 64 }); + * ``` + */ +export const shake256: TRet> = + /* @__PURE__ */ + genShake(0x1f, 136, 32, /* @__PURE__ */ oidNist(0x0c)); + +/** + * SHAKE128 XOF with 256-bit output (NIST version). + * @param msg - message bytes to hash + * @param opts - Optional output-length override. See {@link ShakeOpts}. + * @returns Digest bytes. + * @example + * Hash a message with SHAKE128 using a 32-byte default output. + * ```ts + * shake128_32(new Uint8Array([97, 98, 99]), { dkLen: 32 }); + * ``` + */ +export const shake128_32: TRet> = + /* @__PURE__ */ + genShake(0x1f, 168, 32, /* @__PURE__ */ oidNist(0x0b)); +/** + * SHAKE256 XOF with 512-bit output (NIST version). + * @param msg - message bytes to hash + * @param opts - Optional output-length override. See {@link ShakeOpts}. + * @returns Digest bytes. + * @example + * Hash a message with SHAKE256 using a 64-byte default output. + * ```ts + * shake256_64(new Uint8Array([97, 98, 99]), { dkLen: 64 }); + * ``` + */ +export const shake256_64: TRet> = + /* @__PURE__ */ + genShake(0x1f, 136, 64, /* @__PURE__ */ oidNist(0x0c)); diff --git a/node_modules/@noble/hashes/src/utils.ts b/node_modules/@noble/hashes/src/utils.ts new file mode 100644 index 0000000..961dab2 --- /dev/null +++ b/node_modules/@noble/hashes/src/utils.ts @@ -0,0 +1,848 @@ +/** + * Utilities for hex, bytes, CSPRNG. + * @module + */ +/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */ +/** + * Bytes API type helpers for old + new TypeScript. + * + * TS 5.6 has `Uint8Array`, while TS 5.9+ made it generic `Uint8Array`. + * We can't use specific return type, because TS 5.6 will error. + * We can't use generic return type, because most TS 5.9 software will expect specific type. + * + * Maps typed-array input leaves to broad forms. + * These are compatibility adapters, not ownership guarantees. + * + * - `TArg` keeps byte inputs broad. + * - `TRet` marks byte outputs for TS 5.6 and TS 5.9+ compatibility. + */ +export type TypedArg = T extends BigInt64Array + ? BigInt64Array + : T extends BigUint64Array + ? BigUint64Array + : T extends Float32Array + ? Float32Array + : T extends Float64Array + ? Float64Array + : T extends Int16Array + ? Int16Array + : T extends Int32Array + ? Int32Array + : T extends Int8Array + ? Int8Array + : T extends Uint16Array + ? Uint16Array + : T extends Uint32Array + ? Uint32Array + : T extends Uint8ClampedArray + ? Uint8ClampedArray + : T extends Uint8Array + ? Uint8Array + : never; +/** Maps typed-array output leaves to narrow TS-compatible forms. */ +export type TypedRet = T extends BigInt64Array + ? ReturnType + : T extends BigUint64Array + ? ReturnType + : T extends Float32Array + ? ReturnType + : T extends Float64Array + ? ReturnType + : T extends Int16Array + ? ReturnType + : T extends Int32Array + ? ReturnType + : T extends Int8Array + ? ReturnType + : T extends Uint16Array + ? ReturnType + : T extends Uint32Array + ? ReturnType + : T extends Uint8ClampedArray + ? ReturnType + : T extends Uint8Array + ? ReturnType + : never; +/** Recursively adapts byte-carrying API input types. See {@link TypedArg}. */ +export type TArg = + | T + | ([TypedArg] extends [never] + ? T extends (...args: infer A) => infer R + ? ((...args: { [K in keyof A]: TRet }) => TArg) & { + [K in keyof T]: T[K] extends (...args: any) => any ? T[K] : TArg; + } + : T extends [infer A, ...infer R] + ? [TArg, ...{ [K in keyof R]: TArg }] + : T extends readonly [infer A, ...infer R] + ? readonly [TArg, ...{ [K in keyof R]: TArg }] + : T extends (infer A)[] + ? TArg[] + : T extends readonly (infer A)[] + ? readonly TArg[] + : T extends Promise + ? Promise> + : T extends object + ? { [K in keyof T]: TArg } + : T + : TypedArg); +/** Recursively adapts byte-carrying API output types. See {@link TypedArg}. */ +export type TRet = T extends unknown + ? T & + ([TypedRet] extends [never] + ? T extends (...args: infer A) => infer R + ? ((...args: { [K in keyof A]: TArg }) => TRet) & { + [K in keyof T]: T[K] extends (...args: any) => any ? T[K] : TRet; + } + : T extends [infer A, ...infer R] + ? [TRet, ...{ [K in keyof R]: TRet }] + : T extends readonly [infer A, ...infer R] + ? readonly [TRet, ...{ [K in keyof R]: TRet }] + : T extends (infer A)[] + ? TRet[] + : T extends readonly (infer A)[] + ? readonly TRet[] + : T extends Promise + ? Promise> + : T extends object + ? { [K in keyof T]: TRet } + : T + : TypedRet) + : never; +/** + * Checks if something is Uint8Array. Be careful: nodejs Buffer will return true. + * @param a - value to test + * @returns `true` when the value is a Uint8Array-compatible view. + * @example + * Check whether a value is a Uint8Array-compatible view. + * ```ts + * isBytes(new Uint8Array([1, 2, 3])); + * ``` + */ +export function isBytes(a: unknown): a is Uint8Array { + // Plain `instanceof Uint8Array` is too strict for some Buffer / proxy / cross-realm cases. + // The fallback still requires a real ArrayBuffer view, so plain + // JSON-deserialized `{ constructor: ... }` spoofing is rejected, and + // `BYTES_PER_ELEMENT === 1` keeps the fallback on byte-oriented views. + return ( + a instanceof Uint8Array || + (ArrayBuffer.isView(a) && + a.constructor.name === 'Uint8Array' && + 'BYTES_PER_ELEMENT' in a && + a.BYTES_PER_ELEMENT === 1) + ); +} + +/** + * Asserts something is a non-negative integer. + * @param n - number to validate + * @param title - label included in thrown errors + * @throws On wrong argument types. {@link TypeError} + * @throws On wrong argument ranges or values. {@link RangeError} + * @example + * Validate a non-negative integer option. + * ```ts + * anumber(32, 'length'); + * ``` + */ +export function anumber(n: number, title: string = ''): void { + if (typeof n !== 'number') { + const prefix = title && `"${title}" `; + throw new TypeError(`${prefix}expected number, got ${typeof n}`); + } + if (!Number.isSafeInteger(n) || n < 0) { + const prefix = title && `"${title}" `; + throw new RangeError(`${prefix}expected integer >= 0, got ${n}`); + } +} + +/** + * Asserts something is Uint8Array. + * @param value - value to validate + * @param length - optional exact length constraint + * @param title - label included in thrown errors + * @returns The validated byte array. + * @throws On wrong argument types. {@link TypeError} + * @throws On wrong argument ranges or values. {@link RangeError} + * @example + * Validate that a value is a byte array. + * ```ts + * abytes(new Uint8Array([1, 2, 3])); + * ``` + */ +export function abytes( + value: TArg, + length?: number, + title: string = '' +): TRet { + const bytes = isBytes(value); + const len = value?.length; + const needsLen = length !== undefined; + if (!bytes || (needsLen && len !== length)) { + const prefix = title && `"${title}" `; + const ofLen = needsLen ? ` of length ${length}` : ''; + const got = bytes ? `length=${len}` : `type=${typeof value}`; + const message = prefix + 'expected Uint8Array' + ofLen + ', got ' + got; + if (!bytes) throw new TypeError(message); + throw new RangeError(message); + } + return value as TRet; +} + +/** + * Copies bytes into a fresh Uint8Array. + * Buffer-style slices can alias the same backing store, so callers that need ownership should copy. + * @param bytes - source bytes to clone + * @returns Freshly allocated copy of `bytes`. + * @throws On wrong argument types. {@link TypeError} + * @example + * Clone a byte array before mutating it. + * ```ts + * const copy = copyBytes(new Uint8Array([1, 2, 3])); + * ``` + */ +export function copyBytes(bytes: TArg): TRet { + // `Uint8Array.from(...)` would also accept arrays / other typed arrays. Keep this helper strict + // because callers use it at byte-validation boundaries before mutating the detached copy. + return Uint8Array.from(abytes(bytes)) as TRet; +} + +/** + * Asserts something is a wrapped hash constructor. + * @param h - hash constructor to validate + * @throws On wrong argument types or invalid hash wrapper shape. {@link TypeError} + * @throws On invalid hash metadata ranges or values. {@link RangeError} + * @throws If the hash metadata allows empty outputs or block sizes. {@link Error} + * @example + * Validate a callable hash wrapper. + * ```ts + * import { ahash } from '@noble/hashes/utils.js'; + * import { sha256 } from '@noble/hashes/sha2.js'; + * ahash(sha256); + * ``` + */ +export function ahash(h: TArg): void { + if (typeof h !== 'function' || typeof h.create !== 'function') + throw new TypeError('Hash must wrapped by utils.createHasher'); + anumber(h.outputLen); + anumber(h.blockLen); + // HMAC and KDF callers treat these as real byte lengths; allowing zero lets fake wrappers pass + // validation and can produce empty outputs instead of failing fast. + if (h.outputLen < 1) throw new Error('"outputLen" must be >= 1'); + if (h.blockLen < 1) throw new Error('"blockLen" must be >= 1'); +} + +/** + * Asserts a hash instance has not been destroyed or finished. + * @param instance - hash instance to validate + * @param checkFinished - whether to reject finalized instances + * @throws If the hash instance has already been destroyed or finalized. {@link Error} + * @example + * Validate that a hash instance is still usable. + * ```ts + * import { aexists } from '@noble/hashes/utils.js'; + * import { sha256 } from '@noble/hashes/sha2.js'; + * const hash = sha256.create(); + * aexists(hash); + * ``` + */ +export function aexists(instance: any, checkFinished = true): void { + if (instance.destroyed) throw new Error('Hash instance has been destroyed'); + if (checkFinished && instance.finished) throw new Error('Hash#digest() has already been called'); +} + +/** + * Asserts output is a sufficiently-sized byte array. + * @param out - destination buffer + * @param instance - hash instance providing output length + * Oversized buffers are allowed; downstream code only promises to fill the first `outputLen` bytes. + * @throws On wrong argument types. {@link TypeError} + * @throws On wrong argument ranges or values. {@link RangeError} + * @example + * Validate a caller-provided digest buffer. + * ```ts + * import { aoutput } from '@noble/hashes/utils.js'; + * import { sha256 } from '@noble/hashes/sha2.js'; + * const hash = sha256.create(); + * aoutput(new Uint8Array(hash.outputLen), hash); + * ``` + */ +export function aoutput(out: any, instance: any): void { + abytes(out, undefined, 'digestInto() output'); + const min = instance.outputLen; + if (out.length < min) { + throw new RangeError('"digestInto() output" expected to be of length >=' + min); + } +} + +/** Generic type encompassing 8/16/32-byte array views, but not 64-bit variants. */ +// prettier-ignore +export type TypedArray = Int8Array | Uint8ClampedArray | Uint8Array | + Uint16Array | Int16Array | Uint32Array | Int32Array; + +/** + * Casts a typed array view to Uint8Array. + * @param arr - source typed array + * @returns Uint8Array view over the same buffer. + * @example + * Reinterpret a typed array as bytes. + * ```ts + * u8(new Uint32Array([1, 2])); + * ``` + */ +export function u8(arr: TArg): TRet { + return new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength) as TRet; +} + +/** + * Casts a typed array view to Uint32Array. + * `arr.byteOffset` must already be 4-byte aligned or the platform + * Uint32Array constructor will throw. + * @param arr - source typed array + * @returns Uint32Array view over the same buffer. + * @example + * Reinterpret a byte array as 32-bit words. + * ```ts + * u32(new Uint8Array(8)); + * ``` + */ +export function u32(arr: TArg): TRet { + return new Uint32Array( + arr.buffer, + arr.byteOffset, + Math.floor(arr.byteLength / 4) + ) as TRet; +} + +/** + * Zeroizes typed arrays in place. Warning: JS provides no guarantees. + * @param arrays - arrays to overwrite with zeros + * @example + * Zeroize sensitive buffers in place. + * ```ts + * clean(new Uint8Array([1, 2, 3])); + * ``` + */ +export function clean(...arrays: TArg): void { + for (let i = 0; i < arrays.length; i++) { + arrays[i].fill(0); + } +} + +/** + * Creates a DataView for byte-level manipulation. + * @param arr - source typed array + * @returns DataView over the same buffer region. + * @example + * Create a DataView over an existing buffer. + * ```ts + * createView(new Uint8Array(4)); + * ``` + */ +export function createView(arr: TArg): DataView { + return new DataView(arr.buffer, arr.byteOffset, arr.byteLength); +} + +/** + * Rotate-right operation for uint32 values. + * @param word - source word + * @param shift - shift amount in bits + * @returns Rotated word. + * @example + * Rotate a 32-bit word to the right. + * ```ts + * rotr(0x12345678, 8); + * ``` + */ +export function rotr(word: number, shift: number): number { + return (word << (32 - shift)) | (word >>> shift); +} + +/** + * Rotate-left operation for uint32 values. + * @param word - source word + * @param shift - shift amount in bits + * @returns Rotated word. + * @example + * Rotate a 32-bit word to the left. + * ```ts + * rotl(0x12345678, 8); + * ``` + */ +export function rotl(word: number, shift: number): number { + return (word << shift) | ((word >>> (32 - shift)) >>> 0); +} + +/** Whether the current platform is little-endian. */ +export const isLE: boolean = /* @__PURE__ */ (() => + new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44)(); + +/** + * Byte-swap operation for uint32 values. + * @param word - source word + * @returns Word with reversed byte order. + * @example + * Reverse the byte order of a 32-bit word. + * ```ts + * byteSwap(0x11223344); + * ``` + */ +export function byteSwap(word: number): number { + return ( + ((word << 24) & 0xff000000) | + ((word << 8) & 0xff0000) | + ((word >>> 8) & 0xff00) | + ((word >>> 24) & 0xff) + ); +} +/** + * Conditionally byte-swaps one 32-bit word on big-endian platforms. + * @param n - source word + * @returns Original or byte-swapped word depending on platform endianness. + * @example + * Normalize a 32-bit word for host endianness. + * ```ts + * swap8IfBE(0x11223344); + * ``` + */ +export const swap8IfBE: (n: number) => number = isLE + ? (n: number) => n + : (n: number) => byteSwap(n) >>> 0; + +/** + * Byte-swaps every word of a Uint32Array in place. + * @param arr - array to mutate + * @returns The same array after mutation; callers pass live state arrays here. + * @example + * Reverse the byte order of every word in place. + * ```ts + * byteSwap32(new Uint32Array([0x11223344])); + * ``` + */ +export function byteSwap32(arr: TArg): TRet { + for (let i = 0; i < arr.length; i++) { + arr[i] = byteSwap(arr[i]); + } + return arr as TRet; +} + +/** + * Conditionally byte-swaps a Uint32Array on big-endian platforms. + * @param u - array to normalize for host endianness + * @returns Original or byte-swapped array depending on platform endianness. + * On big-endian runtimes this mutates `u` in place via `byteSwap32(...)`. + * @example + * Normalize a word array for host endianness. + * ```ts + * swap32IfBE(new Uint32Array([0x11223344])); + * ``` + */ +export const swap32IfBE: (u: TArg) => TRet = isLE + ? (u: TArg) => u as TRet + : byteSwap32; + +// Built-in hex conversion https://caniuse.com/mdn-javascript_builtins_uint8array_fromhex +const hasHexBuiltin: boolean = /* @__PURE__ */ (() => + // @ts-ignore + typeof Uint8Array.from([]).toHex === 'function' && typeof Uint8Array.fromHex === 'function')(); + +// Array where index 0xf0 (240) is mapped to string 'f0' +const hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => + i.toString(16).padStart(2, '0') +); + +/** + * Convert byte array to hex string. + * Uses the built-in function when available and assumes it matches the tested + * fallback semantics. + * @param bytes - bytes to encode + * @returns Lowercase hexadecimal string. + * @throws On wrong argument types. {@link TypeError} + * @example + * Convert bytes to lowercase hexadecimal. + * ```ts + * bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])); // 'cafe0123' + * ``` + */ +export function bytesToHex(bytes: TArg): string { + abytes(bytes); + // @ts-ignore + if (hasHexBuiltin) return bytes.toHex(); + // pre-caching improves the speed 6x + let hex = ''; + for (let i = 0; i < bytes.length; i++) { + hex += hexes[bytes[i]]; + } + return hex; +} + +// We use optimized technique to convert hex string to byte array +const asciis = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 } as const; +function asciiToBase16(ch: number): number | undefined { + if (ch >= asciis._0 && ch <= asciis._9) return ch - asciis._0; // '2' => 50-48 + if (ch >= asciis.A && ch <= asciis.F) return ch - (asciis.A - 10); // 'B' => 66-(65-10) + if (ch >= asciis.a && ch <= asciis.f) return ch - (asciis.a - 10); // 'b' => 98-(97-10) + return; +} + +/** + * Convert hex string to byte array. Uses built-in function, when available. + * @param hex - hexadecimal string to decode + * @returns Decoded bytes. + * @throws On wrong argument types. {@link TypeError} + * @throws On wrong argument ranges or values. {@link RangeError} + * @example + * Decode lowercase hexadecimal into bytes. + * ```ts + * hexToBytes('cafe0123'); // Uint8Array.from([0xca, 0xfe, 0x01, 0x23]) + * ``` + */ +export function hexToBytes(hex: string): TRet { + if (typeof hex !== 'string') throw new TypeError('hex string expected, got ' + typeof hex); + if (hasHexBuiltin) { + try { + return (Uint8Array as any).fromHex(hex); + } catch (error) { + if (error instanceof SyntaxError) throw new RangeError(error.message); + throw error; + } + } + const hl = hex.length; + const al = hl / 2; + if (hl % 2) throw new RangeError('hex string expected, got unpadded hex of length ' + hl); + const array = new Uint8Array(al); + for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) { + const n1 = asciiToBase16(hex.charCodeAt(hi)); + const n2 = asciiToBase16(hex.charCodeAt(hi + 1)); + if (n1 === undefined || n2 === undefined) { + const char = hex[hi] + hex[hi + 1]; + throw new RangeError( + 'hex string expected, got non-hex character "' + char + '" at index ' + hi + ); + } + array[ai] = n1 * 16 + n2; // multiply first octet, e.g. 'a3' => 10*16+3 => 160 + 3 => 163 + } + return array; +} + +/** + * There is no setImmediate in browser and setTimeout is slow. + * This yields to the Promise/microtask scheduler queue, not to timers or the + * full macrotask event loop. + * @example + * Yield to the next scheduler tick. + * ```ts + * await nextTick(); + * ``` + */ +export const nextTick = async (): Promise => {}; + +/** + * Returns control to the Promise/microtask scheduler every `tick` + * milliseconds to avoid blocking long loops. + * @param iters - number of loop iterations to run + * @param tick - maximum time slice in milliseconds + * @param cb - callback executed on each iteration + * @example + * Run a loop that periodically yields back to the event loop. + * ```ts + * await asyncLoop(2, 0, () => {}); + * ``` + */ +export async function asyncLoop( + iters: number, + tick: number, + cb: (i: number) => void +): Promise { + let ts = Date.now(); + for (let i = 0; i < iters; i++) { + cb(i); + // Date.now() is not monotonic, so in case if clock goes backwards we return return control too + const diff = Date.now() - ts; + if (diff >= 0 && diff < tick) continue; + await nextTick(); + ts += diff; + } +} + +// Global symbols, but ts doesn't see them: https://github.com/microsoft/TypeScript/issues/31535 +declare const TextEncoder: any; + +/** + * Converts string to bytes using UTF8 encoding. + * Built-in doesn't validate input to be string: we do the check. + * Non-ASCII details are delegated to the platform `TextEncoder`. + * @param str - string to encode + * @returns UTF-8 encoded bytes. + * @throws On wrong argument types. {@link TypeError} + * @example + * Encode a string as UTF-8 bytes. + * ```ts + * utf8ToBytes('abc'); // Uint8Array.from([97, 98, 99]) + * ``` + */ +export function utf8ToBytes(str: string): TRet { + if (typeof str !== 'string') throw new TypeError('string expected'); + return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809 +} + +/** KDFs can accept string or Uint8Array for user convenience. */ +export type KDFInput = string | Uint8Array; + +/** + * Helper for KDFs: consumes Uint8Array or string. + * String inputs are UTF-8 encoded; byte-array inputs stay aliased to the caller buffer. + * @param data - user-provided KDF input + * @param errorTitle - label included in thrown errors + * @returns Byte representation of the input. + * @throws On wrong argument types. {@link TypeError} + * @example + * Normalize KDF input to bytes. + * ```ts + * kdfInputToBytes('password'); + * ``` + */ +export function kdfInputToBytes(data: TArg, errorTitle = ''): TRet { + if (typeof data === 'string') return utf8ToBytes(data); + return abytes(data, undefined, errorTitle); +} + +/** + * Copies several Uint8Arrays into one. + * @param arrays - arrays to concatenate + * @returns Concatenated byte array. + * @throws On wrong argument types. {@link TypeError} + * @example + * Concatenate multiple byte arrays. + * ```ts + * concatBytes(new Uint8Array([1]), new Uint8Array([2])); + * ``` + */ +export function concatBytes(...arrays: TArg): TRet { + let sum = 0; + for (let i = 0; i < arrays.length; i++) { + const a = arrays[i]; + abytes(a); + sum += a.length; + } + const res = new Uint8Array(sum); + for (let i = 0, pad = 0; i < arrays.length; i++) { + const a = arrays[i]; + res.set(a, pad); + pad += a.length; + } + return res; +} + +type EmptyObj = {}; +/** + * Merges default options and passed options. + * @param defaults - base option object + * @param opts - user overrides + * @returns Merged option object. The merge mutates `defaults` in place. + * @throws On wrong argument types. {@link TypeError} + * @example + * Merge user overrides onto default options. + * ```ts + * checkOpts({ dkLen: 32 }, { asyncTick: 10 }); + * ``` + */ +export function checkOpts( + defaults: T1, + opts?: T2 +): T1 & T2 { + if (opts !== undefined && {}.toString.call(opts) !== '[object Object]') + throw new TypeError('options must be object or undefined'); + const merged = Object.assign(defaults, opts); + return merged as T1 & T2; +} + +/** Common interface for all hash instances. */ +export interface Hash { + /** Bytes processed per compression block. */ + blockLen: number; + /** Bytes produced by `digest()`. */ + outputLen: number; + /** Whether the instance supports XOF-style variable-length output via `xof()` / `xofInto()`. */ + canXOF: boolean; + /** + * Absorbs more message bytes into the running hash state. + * @param buf - message chunk to absorb + * @returns The same hash instance for chaining. + */ + update(buf: TArg): this; + /** + * Finalizes the hash into a caller-provided buffer. + * @param buf - destination buffer + * @returns Nothing. Implementations write into `buf` in place. + */ + digestInto(buf: TArg): void; + /** + * Finalizes the hash and returns a freshly allocated digest. + * @returns Digest bytes. + */ + digest(): TRet; + /** Wipes internal state and makes the instance unusable. */ + destroy(): void; + /** + * Copies the current hash state into an existing or new instance. + * @param to - Optional destination instance to reuse. + * @returns Cloned hash state. + */ + _cloneInto(to?: T): T; + /** + * Creates an independent copy of the current hash state. + * @returns Cloned hash instance. + */ + clone(): T; +} + +/** Pseudorandom generator interface. */ +export interface PRG { + /** + * Mixes more entropy into the generator state. + * @param seed - fresh entropy bytes + * @returns Nothing. Implementations update internal state in place. + */ + addEntropy(seed: TArg): void; + /** + * Generates pseudorandom output bytes. + * @param length - number of bytes to generate + * @returns Generated pseudorandom bytes. + */ + randomBytes(length: number): TRet; + /** Wipes generator state and makes the instance unusable. */ + clean(): void; +} + +/** + * XOF: streaming API to read digest in chunks. + * Same as 'squeeze' in keccak/k12 and 'seek' in blake3, but more generic name. + * When hash used in XOF mode it is up to user to call '.destroy' afterwards, since we cannot + * destroy state, next call can require more bytes. + */ +export type HashXOF> = Hash & { + /** + * Reads more bytes from the XOF stream. + * @param bytes - number of bytes to read + * @returns Requested digest bytes. + */ + xof(bytes: number): TRet; + /** + * Reads more bytes from the XOF stream into a caller-provided buffer. + * @param buf - destination buffer + * @returns Filled output buffer. + */ + xofInto(buf: TArg): TRet; +}; + +/** Hash constructor or factory type. */ +export type HasherCons = Opts extends undefined ? () => T : (opts?: Opts) => T; +/** Optional hash metadata. */ +export type HashInfo = { + /** DER-encoded object identifier bytes for the hash algorithm. */ + oid?: TRet; +}; +/** Callable hash function type. */ +export type CHash = Hash, Opts = undefined> = { + /** Digest size in bytes. */ + outputLen: number; + /** Input block size in bytes. */ + blockLen: number; + /** Whether `.create()` returns a hash instance that can be used as an XOF stream. */ + canXOF: boolean; +} & HashInfo & + (Opts extends undefined + ? { + (msg: TArg): TRet; + create(): T; + } + : { + (msg: TArg, opts?: TArg): TRet; + create(opts?: Opts): T; + }); +/** Callable extendable-output hash function type. */ +export type CHashXOF = HashXOF, Opts = undefined> = CHash; + +/** + * Creates a callable hash function from a stateful class constructor. + * @param hashCons - hash constructor or factory + * @param info - optional metadata such as DER OID + * @returns Frozen callable hash wrapper with `.create()`. + * Wrapper construction eagerly calls `hashCons(undefined)` once to read + * `outputLen` / `blockLen`, so constructor side effects happen at module + * init time. + * @example + * Wrap a stateful hash constructor into a callable helper. + * ```ts + * import { createHasher } from '@noble/hashes/utils.js'; + * import { sha256 } from '@noble/hashes/sha2.js'; + * const wrapped = createHasher(sha256.create, { oid: sha256.oid }); + * wrapped(new Uint8Array([1])); + * ``` + */ +export function createHasher, Opts = undefined>( + hashCons: HasherCons, + info: TArg = {} +): TRet> { + const hashC: any = (msg: TArg, opts?: TArg) => + hashCons(opts as Opts) + .update(msg) + .digest(); + const tmp = hashCons(undefined); + hashC.outputLen = tmp.outputLen; + hashC.blockLen = tmp.blockLen; + hashC.canXOF = tmp.canXOF; + hashC.create = (opts?: Opts) => hashCons(opts); + Object.assign(hashC, info); + return Object.freeze(hashC) as TRet>; +} + +/** + * Cryptographically secure PRNG backed by `crypto.getRandomValues`. + * @param bytesLength - number of random bytes to generate + * @returns Random bytes. + * The platform `getRandomValues()` implementation still defines any + * single-call length cap, and this helper rejects oversize requests + * with a stable library `RangeError` instead of host-specific errors. + * @throws On wrong argument types. {@link TypeError} + * @throws On wrong argument ranges or values. {@link RangeError} + * @throws If the current runtime does not provide `crypto.getRandomValues`. {@link Error} + * @example + * Generate a fresh random key or nonce. + * ```ts + * const key = randomBytes(16); + * ``` + */ +export function randomBytes(bytesLength = 32): TRet { + // Match the repo's other length-taking helpers instead of relying on Uint8Array coercion. + anumber(bytesLength, 'bytesLength'); + const cr = typeof globalThis === 'object' ? (globalThis as any).crypto : null; + if (typeof cr?.getRandomValues !== 'function') + throw new Error('crypto.getRandomValues must be defined'); + // Web Cryptography API Level 2 §10.1.1: + // if `byteLength > 65536`, throw `QuotaExceededError`. + // Keep the guard explicit so callers can see the quota in code + // instead of discovering it by reading the spec or host errors. + // This wrapper surfaces the same quota as a stable library RangeError. + if (bytesLength > 65536) + throw new RangeError(`"bytesLength" expected <= 65536, got ${bytesLength}`); + return cr.getRandomValues(new Uint8Array(bytesLength)); +} + +/** + * Creates OID metadata for NIST hashes with prefix `06 09 60 86 48 01 65 03 04 02`. + * @param suffix - final OID byte for the selected hash. + * The helper accepts any byte even though only the documented NIST hash + * suffixes are meaningful downstream. + * @returns Object containing the DER-encoded OID. + * @example + * Build OID metadata for a NIST hash. + * ```ts + * oidNist(0x01); + * ``` + */ +export const oidNist = (suffix: number): TRet> => ({ + // Current NIST hashAlgs suffixes used here fit in one DER subidentifier octet. + // Larger suffix values would need base-128 OID encoding and a different length byte. + oid: Uint8Array.from([0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, suffix]), +}); diff --git a/node_modules/@noble/hashes/src/webcrypto.ts b/node_modules/@noble/hashes/src/webcrypto.ts new file mode 100644 index 0000000..3f772e1 --- /dev/null +++ b/node_modules/@noble/hashes/src/webcrypto.ts @@ -0,0 +1,239 @@ +import { type Pbkdf2Opt } from './pbkdf2.ts'; +import { + abytes, + ahash, + anumber, + checkOpts, + kdfInputToBytes, + type CHash, + type KDFInput, + type TArg, + type TRet, +} from './utils.ts'; + +function _subtle(): typeof crypto.subtle { + const cr = typeof globalThis === 'object' ? (globalThis as any).crypto : null; + const sb = cr?.subtle; + if (typeof sb === 'object' && sb != null) return sb; + throw new Error('crypto.subtle must be defined'); +} + +/** Callable WebCrypto hash function descriptor. */ +export type WebHash = { + /** + * Hashes one message with the selected WebCrypto digest. + * @param msg - message bytes to hash + * @returns Promise resolving to digest bytes. + */ + (msg: TArg): Promise>; + /** WebCrypto algorithm name passed to `crypto.subtle`. */ + webCryptoName: string; + /** Digest size in bytes. */ + outputLen: number; + /** Input block size in bytes. */ + blockLen: number; +}; + +function createWebHash(name: string, blockLen: number, outputLen: number): TRet { + const hashC: any = async (msg: TArg): Promise> => { + abytes(msg); + const crypto = _subtle(); + return new Uint8Array(await crypto.digest(name, msg as BufferSource)) as TRet; + }; + hashC.webCryptoName = name; // make sure it won't interfere with function name + hashC.outputLen = outputLen; + hashC.blockLen = blockLen; + hashC.create = () => { + // Present only so this async wrapper satisfies the shared + // hash-wrapper shape checked by `ahashWeb()`. + throw new Error('not implemented'); + }; + // Later WebCrypto HMAC/HKDF/PBKDF2 calls read descriptor metadata directly, so freezing prevents + // callers from retargeting a `sha256` wrapper into a different backend digest by mutation. + return Object.freeze(hashC) as TRet; +} + +function ahashWeb(hash: TArg) { + ahash(hash as unknown as TArg); + if (typeof hash.webCryptoName !== 'string') throw new Error('non-web hash'); +} + +/** WebCrypto SHA1 (RFC 3174) legacy hash function. It was cryptographically broken. */ +// export const sha1: WebHash = createHash('SHA-1', 64, 20); + +/** + * WebCrypto SHA2-256 hash function from RFC 6234. + * @param msg - message bytes to hash + * @returns Promise resolving to digest bytes. + * @example + * Hash a message with WebCrypto SHA2-256. + * ```ts + * await sha256(new Uint8Array([97, 98, 99])); + * ``` + */ +export const sha256: TRet = /* @__PURE__ */ createWebHash('SHA-256', 64, 32); +/** + * WebCrypto SHA2-384 hash function from RFC 6234. + * @param msg - message bytes to hash + * @returns Promise resolving to digest bytes. + * @example + * Hash a message with WebCrypto SHA2-384. + * ```ts + * await sha384(new Uint8Array([97, 98, 99])); + * ``` + */ +export const sha384: TRet = /* @__PURE__ */ createWebHash('SHA-384', 128, 48); +/** + * WebCrypto SHA2-512 hash function from RFC 6234. + * @param msg - message bytes to hash + * @returns Promise resolving to digest bytes. + * @example + * Hash a message with WebCrypto SHA2-512. + * ```ts + * await sha512(new Uint8Array([97, 98, 99])); + * ``` + */ +export const sha512: TRet = /* @__PURE__ */ createWebHash('SHA-512', 128, 64); + +/** + * WebCrypto HMAC: RFC2104 message authentication code. + * @param hash - function that would be used e.g. sha256. Webcrypto version. + * @param key - authentication key bytes + * @param message - message bytes to authenticate + * @returns Promise resolving to authentication tag bytes. + * `.create()` exists only to mirror the synchronous API surface + * and always throws `not implemented`. + * @example + * Compute an RFC 2104 HMAC with WebCrypto. + * ```ts + * import { hmac, sha256 } from '@noble/hashes/webcrypto.js'; + * await hmac(sha256, new Uint8Array([1, 2, 3]), new Uint8Array([4, 5, 6])); + * ``` + */ +type WebHmacFn = { + ( + hash: TArg, + key: TArg, + message: TArg + ): Promise>; + create(hash: TArg, key: TArg): any; +}; +export const hmac: TRet = /* @__PURE__ */ (() => { + const hmac_ = async ( + hash: TArg, + key: TArg, + message: TArg + ): Promise> => { + const crypto = _subtle(); + abytes(key, undefined, 'key'); + abytes(message, undefined, 'message'); + ahashWeb(hash); + // WebCrypto keys can't be zeroized + // prettier-ignore + const wkey = await crypto.importKey( + 'raw', + key as BufferSource, + { name: 'HMAC', hash: hash.webCryptoName }, + false, + ['sign'] + ); + return new Uint8Array( + await crypto.sign('HMAC', wkey, message as BufferSource) + ) as TRet; + }; + hmac_.create = (_hash: TArg, _key: TArg) => { + throw new Error('not implemented'); + }; + return hmac_ as TRet; +})(); + +/** + * WebCrypto HKDF (RFC 5869): derive keys from an initial input. + * Combines hkdf_extract + hkdf_expand in one step + * @param hash - hash function that would be used (e.g. sha256). Webcrypto version. + * @param ikm - input keying material, the initial key + * @param salt - optional salt value (a non-secret random value) + * @param info - optional context and application specific information bytes + * @param length - length of output keying material in bytes. + * RFC 5869 §2.3 allows `0..255*HashLen`, so `0` requests an empty OKM. + * @returns Promise resolving to derived key bytes. + * The RFC `L <= 255 * HashLen` bound is currently enforced only by backend + * `deriveBits()` rejection, not by an explicit library-side guard. + * @throws If the current runtime does not provide `crypto.subtle`. {@link Error} + * @example + * WebCrypto HKDF (RFC 5869): derive keys from an initial input. + * ```ts + * import { hkdf, sha256 } from '@noble/hashes/webcrypto.js'; + * import { randomBytes, utf8ToBytes } from '@noble/hashes/utils.js'; + * const inputKey = randomBytes(32); + * const salt = randomBytes(32); + * const info = utf8ToBytes('application-key'); + * const okm = await hkdf(sha256, inputKey, salt, info, 32); + * ``` + */ +export async function hkdf( + hash: TArg, + ikm: TArg, + salt: TArg, + info: TArg, + length: number +): Promise> { + const crypto = _subtle(); + ahashWeb(hash); + abytes(ikm, undefined, 'ikm'); + anumber(length, 'length'); + if (salt !== undefined) abytes(salt, undefined, 'salt'); + if (info !== undefined) abytes(info, undefined, 'info'); + const wkey = await crypto.importKey('raw', ikm as BufferSource, 'HKDF', false, ['deriveBits']); + const opts = { + name: 'HKDF', + hash: hash.webCryptoName, + salt: salt === undefined ? new Uint8Array(0) : salt, + info: info === undefined ? new Uint8Array(0) : info, + }; + return new Uint8Array(await crypto.deriveBits(opts, wkey, 8 * length)) as TRet; +} + +/** + * WebCrypto PBKDF2-HMAC: RFC 8018 key derivation function. + * @param hash - hash function that would be used e.g. sha256. Webcrypto version. + * @param password - password from which a derived key is generated; string + * inputs are normalized through `kdfInputToBytes()`, i.e. UTF-8 + * @param salt - cryptographic salt; string inputs are normalized through + * `kdfInputToBytes()`, i.e. UTF-8 + * @param opts - PBKDF2 work factor and output settings. `dkLen`, if provided, + * must be `>= 1` per RFC 8018 §5.2. See {@link Pbkdf2Opt}. + * @returns Promise resolving to derived key bytes. + * Positive-iteration enforcement is currently delegated to backend + * `deriveBits()` rejection (for example `c = 0`), not a dedicated + * library-side guard. + * @throws If the current runtime does not provide `crypto.subtle`. {@link Error} + * @example + * WebCrypto PBKDF2-HMAC: RFC 2898 key derivation function. + * ```ts + * import { pbkdf2, sha256 } from '@noble/hashes/webcrypto.js'; + * const key = await pbkdf2(sha256, 'password', 'salt', { dkLen: 32, c: Math.pow(2, 18) }); + * ``` + */ +export async function pbkdf2( + hash: TArg, + password: TArg, + salt: TArg, + opts: Pbkdf2Opt +): Promise> { + const crypto = _subtle(); + ahashWeb(hash); + const _opts = checkOpts({ dkLen: 32 }, opts); + const { c, dkLen } = _opts; + anumber(c, 'c'); + anumber(dkLen, 'dkLen'); + // RFC 8018 §5.2 defines dkLen as a positive integer. + if (dkLen < 1) throw new Error('"dkLen" must be >= 1'); + const _password = kdfInputToBytes(password, 'password'); + const _salt = kdfInputToBytes(salt, 'salt'); + const key = await crypto.importKey('raw', _password as BufferSource, 'PBKDF2', false, [ + 'deriveBits', + ]); + const deriveOpts = { name: 'PBKDF2', salt: _salt, iterations: c, hash: hash.webCryptoName }; + return new Uint8Array(await crypto.deriveBits(deriveOpts, key, 8 * dkLen)) as TRet; +} diff --git a/node_modules/@noble/hashes/utils.d.ts b/node_modules/@noble/hashes/utils.d.ts new file mode 100644 index 0000000..4033d83 --- /dev/null +++ b/node_modules/@noble/hashes/utils.d.ts @@ -0,0 +1,519 @@ +/** + * Utilities for hex, bytes, CSPRNG. + * @module + */ +/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */ +/** + * Bytes API type helpers for old + new TypeScript. + * + * TS 5.6 has `Uint8Array`, while TS 5.9+ made it generic `Uint8Array`. + * We can't use specific return type, because TS 5.6 will error. + * We can't use generic return type, because most TS 5.9 software will expect specific type. + * + * Maps typed-array input leaves to broad forms. + * These are compatibility adapters, not ownership guarantees. + * + * - `TArg` keeps byte inputs broad. + * - `TRet` marks byte outputs for TS 5.6 and TS 5.9+ compatibility. + */ +export type TypedArg = T extends BigInt64Array ? BigInt64Array : T extends BigUint64Array ? BigUint64Array : T extends Float32Array ? Float32Array : T extends Float64Array ? Float64Array : T extends Int16Array ? Int16Array : T extends Int32Array ? Int32Array : T extends Int8Array ? Int8Array : T extends Uint16Array ? Uint16Array : T extends Uint32Array ? Uint32Array : T extends Uint8ClampedArray ? Uint8ClampedArray : T extends Uint8Array ? Uint8Array : never; +/** Maps typed-array output leaves to narrow TS-compatible forms. */ +export type TypedRet = T extends BigInt64Array ? ReturnType : T extends BigUint64Array ? ReturnType : T extends Float32Array ? ReturnType : T extends Float64Array ? ReturnType : T extends Int16Array ? ReturnType : T extends Int32Array ? ReturnType : T extends Int8Array ? ReturnType : T extends Uint16Array ? ReturnType : T extends Uint32Array ? ReturnType : T extends Uint8ClampedArray ? ReturnType : T extends Uint8Array ? ReturnType : never; +/** Recursively adapts byte-carrying API input types. See {@link TypedArg}. */ +export type TArg = T | ([TypedArg] extends [never] ? T extends (...args: infer A) => infer R ? ((...args: { + [K in keyof A]: TRet; +}) => TArg) & { + [K in keyof T]: T[K] extends (...args: any) => any ? T[K] : TArg; +} : T extends [infer A, ...infer R] ? [TArg, ...{ + [K in keyof R]: TArg; +}] : T extends readonly [infer A, ...infer R] ? readonly [TArg, ...{ + [K in keyof R]: TArg; +}] : T extends (infer A)[] ? TArg[] : T extends readonly (infer A)[] ? readonly TArg[] : T extends Promise ? Promise> : T extends object ? { + [K in keyof T]: TArg; +} : T : TypedArg); +/** Recursively adapts byte-carrying API output types. See {@link TypedArg}. */ +export type TRet = T extends unknown ? T & ([TypedRet] extends [never] ? T extends (...args: infer A) => infer R ? ((...args: { + [K in keyof A]: TArg; +}) => TRet) & { + [K in keyof T]: T[K] extends (...args: any) => any ? T[K] : TRet; +} : T extends [infer A, ...infer R] ? [TRet, ...{ + [K in keyof R]: TRet; +}] : T extends readonly [infer A, ...infer R] ? readonly [TRet, ...{ + [K in keyof R]: TRet; +}] : T extends (infer A)[] ? TRet[] : T extends readonly (infer A)[] ? readonly TRet[] : T extends Promise ? Promise> : T extends object ? { + [K in keyof T]: TRet; +} : T : TypedRet) : never; +/** + * Checks if something is Uint8Array. Be careful: nodejs Buffer will return true. + * @param a - value to test + * @returns `true` when the value is a Uint8Array-compatible view. + * @example + * Check whether a value is a Uint8Array-compatible view. + * ```ts + * isBytes(new Uint8Array([1, 2, 3])); + * ``` + */ +export declare function isBytes(a: unknown): a is Uint8Array; +/** + * Asserts something is a non-negative integer. + * @param n - number to validate + * @param title - label included in thrown errors + * @throws On wrong argument types. {@link TypeError} + * @throws On wrong argument ranges or values. {@link RangeError} + * @example + * Validate a non-negative integer option. + * ```ts + * anumber(32, 'length'); + * ``` + */ +export declare function anumber(n: number, title?: string): void; +/** + * Asserts something is Uint8Array. + * @param value - value to validate + * @param length - optional exact length constraint + * @param title - label included in thrown errors + * @returns The validated byte array. + * @throws On wrong argument types. {@link TypeError} + * @throws On wrong argument ranges or values. {@link RangeError} + * @example + * Validate that a value is a byte array. + * ```ts + * abytes(new Uint8Array([1, 2, 3])); + * ``` + */ +export declare function abytes(value: TArg, length?: number, title?: string): TRet; +/** + * Copies bytes into a fresh Uint8Array. + * Buffer-style slices can alias the same backing store, so callers that need ownership should copy. + * @param bytes - source bytes to clone + * @returns Freshly allocated copy of `bytes`. + * @throws On wrong argument types. {@link TypeError} + * @example + * Clone a byte array before mutating it. + * ```ts + * const copy = copyBytes(new Uint8Array([1, 2, 3])); + * ``` + */ +export declare function copyBytes(bytes: TArg): TRet; +/** + * Asserts something is a wrapped hash constructor. + * @param h - hash constructor to validate + * @throws On wrong argument types or invalid hash wrapper shape. {@link TypeError} + * @throws On invalid hash metadata ranges or values. {@link RangeError} + * @throws If the hash metadata allows empty outputs or block sizes. {@link Error} + * @example + * Validate a callable hash wrapper. + * ```ts + * import { ahash } from '@noble/hashes/utils.js'; + * import { sha256 } from '@noble/hashes/sha2.js'; + * ahash(sha256); + * ``` + */ +export declare function ahash(h: TArg): void; +/** + * Asserts a hash instance has not been destroyed or finished. + * @param instance - hash instance to validate + * @param checkFinished - whether to reject finalized instances + * @throws If the hash instance has already been destroyed or finalized. {@link Error} + * @example + * Validate that a hash instance is still usable. + * ```ts + * import { aexists } from '@noble/hashes/utils.js'; + * import { sha256 } from '@noble/hashes/sha2.js'; + * const hash = sha256.create(); + * aexists(hash); + * ``` + */ +export declare function aexists(instance: any, checkFinished?: boolean): void; +/** + * Asserts output is a sufficiently-sized byte array. + * @param out - destination buffer + * @param instance - hash instance providing output length + * Oversized buffers are allowed; downstream code only promises to fill the first `outputLen` bytes. + * @throws On wrong argument types. {@link TypeError} + * @throws On wrong argument ranges or values. {@link RangeError} + * @example + * Validate a caller-provided digest buffer. + * ```ts + * import { aoutput } from '@noble/hashes/utils.js'; + * import { sha256 } from '@noble/hashes/sha2.js'; + * const hash = sha256.create(); + * aoutput(new Uint8Array(hash.outputLen), hash); + * ``` + */ +export declare function aoutput(out: any, instance: any): void; +/** Generic type encompassing 8/16/32-byte array views, but not 64-bit variants. */ +export type TypedArray = Int8Array | Uint8ClampedArray | Uint8Array | Uint16Array | Int16Array | Uint32Array | Int32Array; +/** + * Casts a typed array view to Uint8Array. + * @param arr - source typed array + * @returns Uint8Array view over the same buffer. + * @example + * Reinterpret a typed array as bytes. + * ```ts + * u8(new Uint32Array([1, 2])); + * ``` + */ +export declare function u8(arr: TArg): TRet; +/** + * Casts a typed array view to Uint32Array. + * `arr.byteOffset` must already be 4-byte aligned or the platform + * Uint32Array constructor will throw. + * @param arr - source typed array + * @returns Uint32Array view over the same buffer. + * @example + * Reinterpret a byte array as 32-bit words. + * ```ts + * u32(new Uint8Array(8)); + * ``` + */ +export declare function u32(arr: TArg): TRet; +/** + * Zeroizes typed arrays in place. Warning: JS provides no guarantees. + * @param arrays - arrays to overwrite with zeros + * @example + * Zeroize sensitive buffers in place. + * ```ts + * clean(new Uint8Array([1, 2, 3])); + * ``` + */ +export declare function clean(...arrays: TArg): void; +/** + * Creates a DataView for byte-level manipulation. + * @param arr - source typed array + * @returns DataView over the same buffer region. + * @example + * Create a DataView over an existing buffer. + * ```ts + * createView(new Uint8Array(4)); + * ``` + */ +export declare function createView(arr: TArg): DataView; +/** + * Rotate-right operation for uint32 values. + * @param word - source word + * @param shift - shift amount in bits + * @returns Rotated word. + * @example + * Rotate a 32-bit word to the right. + * ```ts + * rotr(0x12345678, 8); + * ``` + */ +export declare function rotr(word: number, shift: number): number; +/** + * Rotate-left operation for uint32 values. + * @param word - source word + * @param shift - shift amount in bits + * @returns Rotated word. + * @example + * Rotate a 32-bit word to the left. + * ```ts + * rotl(0x12345678, 8); + * ``` + */ +export declare function rotl(word: number, shift: number): number; +/** Whether the current platform is little-endian. */ +export declare const isLE: boolean; +/** + * Byte-swap operation for uint32 values. + * @param word - source word + * @returns Word with reversed byte order. + * @example + * Reverse the byte order of a 32-bit word. + * ```ts + * byteSwap(0x11223344); + * ``` + */ +export declare function byteSwap(word: number): number; +/** + * Conditionally byte-swaps one 32-bit word on big-endian platforms. + * @param n - source word + * @returns Original or byte-swapped word depending on platform endianness. + * @example + * Normalize a 32-bit word for host endianness. + * ```ts + * swap8IfBE(0x11223344); + * ``` + */ +export declare const swap8IfBE: (n: number) => number; +/** + * Byte-swaps every word of a Uint32Array in place. + * @param arr - array to mutate + * @returns The same array after mutation; callers pass live state arrays here. + * @example + * Reverse the byte order of every word in place. + * ```ts + * byteSwap32(new Uint32Array([0x11223344])); + * ``` + */ +export declare function byteSwap32(arr: TArg): TRet; +/** + * Conditionally byte-swaps a Uint32Array on big-endian platforms. + * @param u - array to normalize for host endianness + * @returns Original or byte-swapped array depending on platform endianness. + * On big-endian runtimes this mutates `u` in place via `byteSwap32(...)`. + * @example + * Normalize a word array for host endianness. + * ```ts + * swap32IfBE(new Uint32Array([0x11223344])); + * ``` + */ +export declare const swap32IfBE: (u: TArg) => TRet; +/** + * Convert byte array to hex string. + * Uses the built-in function when available and assumes it matches the tested + * fallback semantics. + * @param bytes - bytes to encode + * @returns Lowercase hexadecimal string. + * @throws On wrong argument types. {@link TypeError} + * @example + * Convert bytes to lowercase hexadecimal. + * ```ts + * bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])); // 'cafe0123' + * ``` + */ +export declare function bytesToHex(bytes: TArg): string; +/** + * Convert hex string to byte array. Uses built-in function, when available. + * @param hex - hexadecimal string to decode + * @returns Decoded bytes. + * @throws On wrong argument types. {@link TypeError} + * @throws On wrong argument ranges or values. {@link RangeError} + * @example + * Decode lowercase hexadecimal into bytes. + * ```ts + * hexToBytes('cafe0123'); // Uint8Array.from([0xca, 0xfe, 0x01, 0x23]) + * ``` + */ +export declare function hexToBytes(hex: string): TRet; +/** + * There is no setImmediate in browser and setTimeout is slow. + * This yields to the Promise/microtask scheduler queue, not to timers or the + * full macrotask event loop. + * @example + * Yield to the next scheduler tick. + * ```ts + * await nextTick(); + * ``` + */ +export declare const nextTick: () => Promise; +/** + * Returns control to the Promise/microtask scheduler every `tick` + * milliseconds to avoid blocking long loops. + * @param iters - number of loop iterations to run + * @param tick - maximum time slice in milliseconds + * @param cb - callback executed on each iteration + * @example + * Run a loop that periodically yields back to the event loop. + * ```ts + * await asyncLoop(2, 0, () => {}); + * ``` + */ +export declare function asyncLoop(iters: number, tick: number, cb: (i: number) => void): Promise; +/** + * Converts string to bytes using UTF8 encoding. + * Built-in doesn't validate input to be string: we do the check. + * Non-ASCII details are delegated to the platform `TextEncoder`. + * @param str - string to encode + * @returns UTF-8 encoded bytes. + * @throws On wrong argument types. {@link TypeError} + * @example + * Encode a string as UTF-8 bytes. + * ```ts + * utf8ToBytes('abc'); // Uint8Array.from([97, 98, 99]) + * ``` + */ +export declare function utf8ToBytes(str: string): TRet; +/** KDFs can accept string or Uint8Array for user convenience. */ +export type KDFInput = string | Uint8Array; +/** + * Helper for KDFs: consumes Uint8Array or string. + * String inputs are UTF-8 encoded; byte-array inputs stay aliased to the caller buffer. + * @param data - user-provided KDF input + * @param errorTitle - label included in thrown errors + * @returns Byte representation of the input. + * @throws On wrong argument types. {@link TypeError} + * @example + * Normalize KDF input to bytes. + * ```ts + * kdfInputToBytes('password'); + * ``` + */ +export declare function kdfInputToBytes(data: TArg, errorTitle?: string): TRet; +/** + * Copies several Uint8Arrays into one. + * @param arrays - arrays to concatenate + * @returns Concatenated byte array. + * @throws On wrong argument types. {@link TypeError} + * @example + * Concatenate multiple byte arrays. + * ```ts + * concatBytes(new Uint8Array([1]), new Uint8Array([2])); + * ``` + */ +export declare function concatBytes(...arrays: TArg): TRet; +type EmptyObj = {}; +/** + * Merges default options and passed options. + * @param defaults - base option object + * @param opts - user overrides + * @returns Merged option object. The merge mutates `defaults` in place. + * @throws On wrong argument types. {@link TypeError} + * @example + * Merge user overrides onto default options. + * ```ts + * checkOpts({ dkLen: 32 }, { asyncTick: 10 }); + * ``` + */ +export declare function checkOpts(defaults: T1, opts?: T2): T1 & T2; +/** Common interface for all hash instances. */ +export interface Hash { + /** Bytes processed per compression block. */ + blockLen: number; + /** Bytes produced by `digest()`. */ + outputLen: number; + /** Whether the instance supports XOF-style variable-length output via `xof()` / `xofInto()`. */ + canXOF: boolean; + /** + * Absorbs more message bytes into the running hash state. + * @param buf - message chunk to absorb + * @returns The same hash instance for chaining. + */ + update(buf: TArg): this; + /** + * Finalizes the hash into a caller-provided buffer. + * @param buf - destination buffer + * @returns Nothing. Implementations write into `buf` in place. + */ + digestInto(buf: TArg): void; + /** + * Finalizes the hash and returns a freshly allocated digest. + * @returns Digest bytes. + */ + digest(): TRet; + /** Wipes internal state and makes the instance unusable. */ + destroy(): void; + /** + * Copies the current hash state into an existing or new instance. + * @param to - Optional destination instance to reuse. + * @returns Cloned hash state. + */ + _cloneInto(to?: T): T; + /** + * Creates an independent copy of the current hash state. + * @returns Cloned hash instance. + */ + clone(): T; +} +/** Pseudorandom generator interface. */ +export interface PRG { + /** + * Mixes more entropy into the generator state. + * @param seed - fresh entropy bytes + * @returns Nothing. Implementations update internal state in place. + */ + addEntropy(seed: TArg): void; + /** + * Generates pseudorandom output bytes. + * @param length - number of bytes to generate + * @returns Generated pseudorandom bytes. + */ + randomBytes(length: number): TRet; + /** Wipes generator state and makes the instance unusable. */ + clean(): void; +} +/** + * XOF: streaming API to read digest in chunks. + * Same as 'squeeze' in keccak/k12 and 'seek' in blake3, but more generic name. + * When hash used in XOF mode it is up to user to call '.destroy' afterwards, since we cannot + * destroy state, next call can require more bytes. + */ +export type HashXOF> = Hash & { + /** + * Reads more bytes from the XOF stream. + * @param bytes - number of bytes to read + * @returns Requested digest bytes. + */ + xof(bytes: number): TRet; + /** + * Reads more bytes from the XOF stream into a caller-provided buffer. + * @param buf - destination buffer + * @returns Filled output buffer. + */ + xofInto(buf: TArg): TRet; +}; +/** Hash constructor or factory type. */ +export type HasherCons = Opts extends undefined ? () => T : (opts?: Opts) => T; +/** Optional hash metadata. */ +export type HashInfo = { + /** DER-encoded object identifier bytes for the hash algorithm. */ + oid?: TRet; +}; +/** Callable hash function type. */ +export type CHash = Hash, Opts = undefined> = { + /** Digest size in bytes. */ + outputLen: number; + /** Input block size in bytes. */ + blockLen: number; + /** Whether `.create()` returns a hash instance that can be used as an XOF stream. */ + canXOF: boolean; +} & HashInfo & (Opts extends undefined ? { + (msg: TArg): TRet; + create(): T; +} : { + (msg: TArg, opts?: TArg): TRet; + create(opts?: Opts): T; +}); +/** Callable extendable-output hash function type. */ +export type CHashXOF = HashXOF, Opts = undefined> = CHash; +/** + * Creates a callable hash function from a stateful class constructor. + * @param hashCons - hash constructor or factory + * @param info - optional metadata such as DER OID + * @returns Frozen callable hash wrapper with `.create()`. + * Wrapper construction eagerly calls `hashCons(undefined)` once to read + * `outputLen` / `blockLen`, so constructor side effects happen at module + * init time. + * @example + * Wrap a stateful hash constructor into a callable helper. + * ```ts + * import { createHasher } from '@noble/hashes/utils.js'; + * import { sha256 } from '@noble/hashes/sha2.js'; + * const wrapped = createHasher(sha256.create, { oid: sha256.oid }); + * wrapped(new Uint8Array([1])); + * ``` + */ +export declare function createHasher, Opts = undefined>(hashCons: HasherCons, info?: TArg): TRet>; +/** + * Cryptographically secure PRNG backed by `crypto.getRandomValues`. + * @param bytesLength - number of random bytes to generate + * @returns Random bytes. + * The platform `getRandomValues()` implementation still defines any + * single-call length cap, and this helper rejects oversize requests + * with a stable library `RangeError` instead of host-specific errors. + * @throws On wrong argument types. {@link TypeError} + * @throws On wrong argument ranges or values. {@link RangeError} + * @throws If the current runtime does not provide `crypto.getRandomValues`. {@link Error} + * @example + * Generate a fresh random key or nonce. + * ```ts + * const key = randomBytes(16); + * ``` + */ +export declare function randomBytes(bytesLength?: number): TRet; +/** + * Creates OID metadata for NIST hashes with prefix `06 09 60 86 48 01 65 03 04 02`. + * @param suffix - final OID byte for the selected hash. + * The helper accepts any byte even though only the documented NIST hash + * suffixes are meaningful downstream. + * @returns Object containing the DER-encoded OID. + * @example + * Build OID metadata for a NIST hash. + * ```ts + * oidNist(0x01); + * ``` + */ +export declare const oidNist: (suffix: number) => TRet>; +export {}; +//# sourceMappingURL=utils.d.ts.map \ No newline at end of file diff --git a/node_modules/@noble/hashes/utils.d.ts.map b/node_modules/@noble/hashes/utils.d.ts.map new file mode 100644 index 0000000..a76edfc --- /dev/null +++ b/node_modules/@noble/hashes/utils.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["src/utils.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@noble/hashes/utils.js b/node_modules/@noble/hashes/utils.js new file mode 100644 index 0000000..b4c71b6 --- /dev/null +++ b/node_modules/@noble/hashes/utils.js @@ -0,0 +1,578 @@ +/** + * Checks if something is Uint8Array. Be careful: nodejs Buffer will return true. + * @param a - value to test + * @returns `true` when the value is a Uint8Array-compatible view. + * @example + * Check whether a value is a Uint8Array-compatible view. + * ```ts + * isBytes(new Uint8Array([1, 2, 3])); + * ``` + */ +export function isBytes(a) { + // Plain `instanceof Uint8Array` is too strict for some Buffer / proxy / cross-realm cases. + // The fallback still requires a real ArrayBuffer view, so plain + // JSON-deserialized `{ constructor: ... }` spoofing is rejected, and + // `BYTES_PER_ELEMENT === 1` keeps the fallback on byte-oriented views. + return (a instanceof Uint8Array || + (ArrayBuffer.isView(a) && + a.constructor.name === 'Uint8Array' && + 'BYTES_PER_ELEMENT' in a && + a.BYTES_PER_ELEMENT === 1)); +} +/** + * Asserts something is a non-negative integer. + * @param n - number to validate + * @param title - label included in thrown errors + * @throws On wrong argument types. {@link TypeError} + * @throws On wrong argument ranges or values. {@link RangeError} + * @example + * Validate a non-negative integer option. + * ```ts + * anumber(32, 'length'); + * ``` + */ +export function anumber(n, title = '') { + if (typeof n !== 'number') { + const prefix = title && `"${title}" `; + throw new TypeError(`${prefix}expected number, got ${typeof n}`); + } + if (!Number.isSafeInteger(n) || n < 0) { + const prefix = title && `"${title}" `; + throw new RangeError(`${prefix}expected integer >= 0, got ${n}`); + } +} +/** + * Asserts something is Uint8Array. + * @param value - value to validate + * @param length - optional exact length constraint + * @param title - label included in thrown errors + * @returns The validated byte array. + * @throws On wrong argument types. {@link TypeError} + * @throws On wrong argument ranges or values. {@link RangeError} + * @example + * Validate that a value is a byte array. + * ```ts + * abytes(new Uint8Array([1, 2, 3])); + * ``` + */ +export function abytes(value, length, title = '') { + const bytes = isBytes(value); + const len = value?.length; + const needsLen = length !== undefined; + if (!bytes || (needsLen && len !== length)) { + const prefix = title && `"${title}" `; + const ofLen = needsLen ? ` of length ${length}` : ''; + const got = bytes ? `length=${len}` : `type=${typeof value}`; + const message = prefix + 'expected Uint8Array' + ofLen + ', got ' + got; + if (!bytes) + throw new TypeError(message); + throw new RangeError(message); + } + return value; +} +/** + * Copies bytes into a fresh Uint8Array. + * Buffer-style slices can alias the same backing store, so callers that need ownership should copy. + * @param bytes - source bytes to clone + * @returns Freshly allocated copy of `bytes`. + * @throws On wrong argument types. {@link TypeError} + * @example + * Clone a byte array before mutating it. + * ```ts + * const copy = copyBytes(new Uint8Array([1, 2, 3])); + * ``` + */ +export function copyBytes(bytes) { + // `Uint8Array.from(...)` would also accept arrays / other typed arrays. Keep this helper strict + // because callers use it at byte-validation boundaries before mutating the detached copy. + return Uint8Array.from(abytes(bytes)); +} +/** + * Asserts something is a wrapped hash constructor. + * @param h - hash constructor to validate + * @throws On wrong argument types or invalid hash wrapper shape. {@link TypeError} + * @throws On invalid hash metadata ranges or values. {@link RangeError} + * @throws If the hash metadata allows empty outputs or block sizes. {@link Error} + * @example + * Validate a callable hash wrapper. + * ```ts + * import { ahash } from '@noble/hashes/utils.js'; + * import { sha256 } from '@noble/hashes/sha2.js'; + * ahash(sha256); + * ``` + */ +export function ahash(h) { + if (typeof h !== 'function' || typeof h.create !== 'function') + throw new TypeError('Hash must wrapped by utils.createHasher'); + anumber(h.outputLen); + anumber(h.blockLen); + // HMAC and KDF callers treat these as real byte lengths; allowing zero lets fake wrappers pass + // validation and can produce empty outputs instead of failing fast. + if (h.outputLen < 1) + throw new Error('"outputLen" must be >= 1'); + if (h.blockLen < 1) + throw new Error('"blockLen" must be >= 1'); +} +/** + * Asserts a hash instance has not been destroyed or finished. + * @param instance - hash instance to validate + * @param checkFinished - whether to reject finalized instances + * @throws If the hash instance has already been destroyed or finalized. {@link Error} + * @example + * Validate that a hash instance is still usable. + * ```ts + * import { aexists } from '@noble/hashes/utils.js'; + * import { sha256 } from '@noble/hashes/sha2.js'; + * const hash = sha256.create(); + * aexists(hash); + * ``` + */ +export function aexists(instance, checkFinished = true) { + if (instance.destroyed) + throw new Error('Hash instance has been destroyed'); + if (checkFinished && instance.finished) + throw new Error('Hash#digest() has already been called'); +} +/** + * Asserts output is a sufficiently-sized byte array. + * @param out - destination buffer + * @param instance - hash instance providing output length + * Oversized buffers are allowed; downstream code only promises to fill the first `outputLen` bytes. + * @throws On wrong argument types. {@link TypeError} + * @throws On wrong argument ranges or values. {@link RangeError} + * @example + * Validate a caller-provided digest buffer. + * ```ts + * import { aoutput } from '@noble/hashes/utils.js'; + * import { sha256 } from '@noble/hashes/sha2.js'; + * const hash = sha256.create(); + * aoutput(new Uint8Array(hash.outputLen), hash); + * ``` + */ +export function aoutput(out, instance) { + abytes(out, undefined, 'digestInto() output'); + const min = instance.outputLen; + if (out.length < min) { + throw new RangeError('"digestInto() output" expected to be of length >=' + min); + } +} +/** + * Casts a typed array view to Uint8Array. + * @param arr - source typed array + * @returns Uint8Array view over the same buffer. + * @example + * Reinterpret a typed array as bytes. + * ```ts + * u8(new Uint32Array([1, 2])); + * ``` + */ +export function u8(arr) { + return new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength); +} +/** + * Casts a typed array view to Uint32Array. + * `arr.byteOffset` must already be 4-byte aligned or the platform + * Uint32Array constructor will throw. + * @param arr - source typed array + * @returns Uint32Array view over the same buffer. + * @example + * Reinterpret a byte array as 32-bit words. + * ```ts + * u32(new Uint8Array(8)); + * ``` + */ +export function u32(arr) { + return new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4)); +} +/** + * Zeroizes typed arrays in place. Warning: JS provides no guarantees. + * @param arrays - arrays to overwrite with zeros + * @example + * Zeroize sensitive buffers in place. + * ```ts + * clean(new Uint8Array([1, 2, 3])); + * ``` + */ +export function clean(...arrays) { + for (let i = 0; i < arrays.length; i++) { + arrays[i].fill(0); + } +} +/** + * Creates a DataView for byte-level manipulation. + * @param arr - source typed array + * @returns DataView over the same buffer region. + * @example + * Create a DataView over an existing buffer. + * ```ts + * createView(new Uint8Array(4)); + * ``` + */ +export function createView(arr) { + return new DataView(arr.buffer, arr.byteOffset, arr.byteLength); +} +/** + * Rotate-right operation for uint32 values. + * @param word - source word + * @param shift - shift amount in bits + * @returns Rotated word. + * @example + * Rotate a 32-bit word to the right. + * ```ts + * rotr(0x12345678, 8); + * ``` + */ +export function rotr(word, shift) { + return (word << (32 - shift)) | (word >>> shift); +} +/** + * Rotate-left operation for uint32 values. + * @param word - source word + * @param shift - shift amount in bits + * @returns Rotated word. + * @example + * Rotate a 32-bit word to the left. + * ```ts + * rotl(0x12345678, 8); + * ``` + */ +export function rotl(word, shift) { + return (word << shift) | ((word >>> (32 - shift)) >>> 0); +} +/** Whether the current platform is little-endian. */ +export const isLE = /* @__PURE__ */ (() => new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44)(); +/** + * Byte-swap operation for uint32 values. + * @param word - source word + * @returns Word with reversed byte order. + * @example + * Reverse the byte order of a 32-bit word. + * ```ts + * byteSwap(0x11223344); + * ``` + */ +export function byteSwap(word) { + return (((word << 24) & 0xff000000) | + ((word << 8) & 0xff0000) | + ((word >>> 8) & 0xff00) | + ((word >>> 24) & 0xff)); +} +/** + * Conditionally byte-swaps one 32-bit word on big-endian platforms. + * @param n - source word + * @returns Original or byte-swapped word depending on platform endianness. + * @example + * Normalize a 32-bit word for host endianness. + * ```ts + * swap8IfBE(0x11223344); + * ``` + */ +export const swap8IfBE = isLE + ? (n) => n + : (n) => byteSwap(n) >>> 0; +/** + * Byte-swaps every word of a Uint32Array in place. + * @param arr - array to mutate + * @returns The same array after mutation; callers pass live state arrays here. + * @example + * Reverse the byte order of every word in place. + * ```ts + * byteSwap32(new Uint32Array([0x11223344])); + * ``` + */ +export function byteSwap32(arr) { + for (let i = 0; i < arr.length; i++) { + arr[i] = byteSwap(arr[i]); + } + return arr; +} +/** + * Conditionally byte-swaps a Uint32Array on big-endian platforms. + * @param u - array to normalize for host endianness + * @returns Original or byte-swapped array depending on platform endianness. + * On big-endian runtimes this mutates `u` in place via `byteSwap32(...)`. + * @example + * Normalize a word array for host endianness. + * ```ts + * swap32IfBE(new Uint32Array([0x11223344])); + * ``` + */ +export const swap32IfBE = isLE + ? (u) => u + : byteSwap32; +// Built-in hex conversion https://caniuse.com/mdn-javascript_builtins_uint8array_fromhex +const hasHexBuiltin = /* @__PURE__ */ (() => +// @ts-ignore +typeof Uint8Array.from([]).toHex === 'function' && typeof Uint8Array.fromHex === 'function')(); +// Array where index 0xf0 (240) is mapped to string 'f0' +const hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, '0')); +/** + * Convert byte array to hex string. + * Uses the built-in function when available and assumes it matches the tested + * fallback semantics. + * @param bytes - bytes to encode + * @returns Lowercase hexadecimal string. + * @throws On wrong argument types. {@link TypeError} + * @example + * Convert bytes to lowercase hexadecimal. + * ```ts + * bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])); // 'cafe0123' + * ``` + */ +export function bytesToHex(bytes) { + abytes(bytes); + // @ts-ignore + if (hasHexBuiltin) + return bytes.toHex(); + // pre-caching improves the speed 6x + let hex = ''; + for (let i = 0; i < bytes.length; i++) { + hex += hexes[bytes[i]]; + } + return hex; +} +// We use optimized technique to convert hex string to byte array +const asciis = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 }; +function asciiToBase16(ch) { + if (ch >= asciis._0 && ch <= asciis._9) + return ch - asciis._0; // '2' => 50-48 + if (ch >= asciis.A && ch <= asciis.F) + return ch - (asciis.A - 10); // 'B' => 66-(65-10) + if (ch >= asciis.a && ch <= asciis.f) + return ch - (asciis.a - 10); // 'b' => 98-(97-10) + return; +} +/** + * Convert hex string to byte array. Uses built-in function, when available. + * @param hex - hexadecimal string to decode + * @returns Decoded bytes. + * @throws On wrong argument types. {@link TypeError} + * @throws On wrong argument ranges or values. {@link RangeError} + * @example + * Decode lowercase hexadecimal into bytes. + * ```ts + * hexToBytes('cafe0123'); // Uint8Array.from([0xca, 0xfe, 0x01, 0x23]) + * ``` + */ +export function hexToBytes(hex) { + if (typeof hex !== 'string') + throw new TypeError('hex string expected, got ' + typeof hex); + if (hasHexBuiltin) { + try { + return Uint8Array.fromHex(hex); + } + catch (error) { + if (error instanceof SyntaxError) + throw new RangeError(error.message); + throw error; + } + } + const hl = hex.length; + const al = hl / 2; + if (hl % 2) + throw new RangeError('hex string expected, got unpadded hex of length ' + hl); + const array = new Uint8Array(al); + for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) { + const n1 = asciiToBase16(hex.charCodeAt(hi)); + const n2 = asciiToBase16(hex.charCodeAt(hi + 1)); + if (n1 === undefined || n2 === undefined) { + const char = hex[hi] + hex[hi + 1]; + throw new RangeError('hex string expected, got non-hex character "' + char + '" at index ' + hi); + } + array[ai] = n1 * 16 + n2; // multiply first octet, e.g. 'a3' => 10*16+3 => 160 + 3 => 163 + } + return array; +} +/** + * There is no setImmediate in browser and setTimeout is slow. + * This yields to the Promise/microtask scheduler queue, not to timers or the + * full macrotask event loop. + * @example + * Yield to the next scheduler tick. + * ```ts + * await nextTick(); + * ``` + */ +export const nextTick = async () => { }; +/** + * Returns control to the Promise/microtask scheduler every `tick` + * milliseconds to avoid blocking long loops. + * @param iters - number of loop iterations to run + * @param tick - maximum time slice in milliseconds + * @param cb - callback executed on each iteration + * @example + * Run a loop that periodically yields back to the event loop. + * ```ts + * await asyncLoop(2, 0, () => {}); + * ``` + */ +export async function asyncLoop(iters, tick, cb) { + let ts = Date.now(); + for (let i = 0; i < iters; i++) { + cb(i); + // Date.now() is not monotonic, so in case if clock goes backwards we return return control too + const diff = Date.now() - ts; + if (diff >= 0 && diff < tick) + continue; + await nextTick(); + ts += diff; + } +} +/** + * Converts string to bytes using UTF8 encoding. + * Built-in doesn't validate input to be string: we do the check. + * Non-ASCII details are delegated to the platform `TextEncoder`. + * @param str - string to encode + * @returns UTF-8 encoded bytes. + * @throws On wrong argument types. {@link TypeError} + * @example + * Encode a string as UTF-8 bytes. + * ```ts + * utf8ToBytes('abc'); // Uint8Array.from([97, 98, 99]) + * ``` + */ +export function utf8ToBytes(str) { + if (typeof str !== 'string') + throw new TypeError('string expected'); + return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809 +} +/** + * Helper for KDFs: consumes Uint8Array or string. + * String inputs are UTF-8 encoded; byte-array inputs stay aliased to the caller buffer. + * @param data - user-provided KDF input + * @param errorTitle - label included in thrown errors + * @returns Byte representation of the input. + * @throws On wrong argument types. {@link TypeError} + * @example + * Normalize KDF input to bytes. + * ```ts + * kdfInputToBytes('password'); + * ``` + */ +export function kdfInputToBytes(data, errorTitle = '') { + if (typeof data === 'string') + return utf8ToBytes(data); + return abytes(data, undefined, errorTitle); +} +/** + * Copies several Uint8Arrays into one. + * @param arrays - arrays to concatenate + * @returns Concatenated byte array. + * @throws On wrong argument types. {@link TypeError} + * @example + * Concatenate multiple byte arrays. + * ```ts + * concatBytes(new Uint8Array([1]), new Uint8Array([2])); + * ``` + */ +export function concatBytes(...arrays) { + let sum = 0; + for (let i = 0; i < arrays.length; i++) { + const a = arrays[i]; + abytes(a); + sum += a.length; + } + const res = new Uint8Array(sum); + for (let i = 0, pad = 0; i < arrays.length; i++) { + const a = arrays[i]; + res.set(a, pad); + pad += a.length; + } + return res; +} +/** + * Merges default options and passed options. + * @param defaults - base option object + * @param opts - user overrides + * @returns Merged option object. The merge mutates `defaults` in place. + * @throws On wrong argument types. {@link TypeError} + * @example + * Merge user overrides onto default options. + * ```ts + * checkOpts({ dkLen: 32 }, { asyncTick: 10 }); + * ``` + */ +export function checkOpts(defaults, opts) { + if (opts !== undefined && {}.toString.call(opts) !== '[object Object]') + throw new TypeError('options must be object or undefined'); + const merged = Object.assign(defaults, opts); + return merged; +} +/** + * Creates a callable hash function from a stateful class constructor. + * @param hashCons - hash constructor or factory + * @param info - optional metadata such as DER OID + * @returns Frozen callable hash wrapper with `.create()`. + * Wrapper construction eagerly calls `hashCons(undefined)` once to read + * `outputLen` / `blockLen`, so constructor side effects happen at module + * init time. + * @example + * Wrap a stateful hash constructor into a callable helper. + * ```ts + * import { createHasher } from '@noble/hashes/utils.js'; + * import { sha256 } from '@noble/hashes/sha2.js'; + * const wrapped = createHasher(sha256.create, { oid: sha256.oid }); + * wrapped(new Uint8Array([1])); + * ``` + */ +export function createHasher(hashCons, info = {}) { + const hashC = (msg, opts) => hashCons(opts) + .update(msg) + .digest(); + const tmp = hashCons(undefined); + hashC.outputLen = tmp.outputLen; + hashC.blockLen = tmp.blockLen; + hashC.canXOF = tmp.canXOF; + hashC.create = (opts) => hashCons(opts); + Object.assign(hashC, info); + return Object.freeze(hashC); +} +/** + * Cryptographically secure PRNG backed by `crypto.getRandomValues`. + * @param bytesLength - number of random bytes to generate + * @returns Random bytes. + * The platform `getRandomValues()` implementation still defines any + * single-call length cap, and this helper rejects oversize requests + * with a stable library `RangeError` instead of host-specific errors. + * @throws On wrong argument types. {@link TypeError} + * @throws On wrong argument ranges or values. {@link RangeError} + * @throws If the current runtime does not provide `crypto.getRandomValues`. {@link Error} + * @example + * Generate a fresh random key or nonce. + * ```ts + * const key = randomBytes(16); + * ``` + */ +export function randomBytes(bytesLength = 32) { + // Match the repo's other length-taking helpers instead of relying on Uint8Array coercion. + anumber(bytesLength, 'bytesLength'); + const cr = typeof globalThis === 'object' ? globalThis.crypto : null; + if (typeof cr?.getRandomValues !== 'function') + throw new Error('crypto.getRandomValues must be defined'); + // Web Cryptography API Level 2 §10.1.1: + // if `byteLength > 65536`, throw `QuotaExceededError`. + // Keep the guard explicit so callers can see the quota in code + // instead of discovering it by reading the spec or host errors. + // This wrapper surfaces the same quota as a stable library RangeError. + if (bytesLength > 65536) + throw new RangeError(`"bytesLength" expected <= 65536, got ${bytesLength}`); + return cr.getRandomValues(new Uint8Array(bytesLength)); +} +/** + * Creates OID metadata for NIST hashes with prefix `06 09 60 86 48 01 65 03 04 02`. + * @param suffix - final OID byte for the selected hash. + * The helper accepts any byte even though only the documented NIST hash + * suffixes are meaningful downstream. + * @returns Object containing the DER-encoded OID. + * @example + * Build OID metadata for a NIST hash. + * ```ts + * oidNist(0x01); + * ``` + */ +export const oidNist = (suffix) => ({ + // Current NIST hashAlgs suffixes used here fit in one DER subidentifier octet. + // Larger suffix values would need base-128 OID encoding and a different length byte. + oid: Uint8Array.from([0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, suffix]), +}); +//# sourceMappingURL=utils.js.map \ No newline at end of file diff --git a/node_modules/@noble/hashes/utils.js.map b/node_modules/@noble/hashes/utils.js.map new file mode 100644 index 0000000..76f809d --- /dev/null +++ b/node_modules/@noble/hashes/utils.js.map @@ -0,0 +1 @@ +{"version":3,"file":"utils.js","sourceRoot":"","sources":["src/utils.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/@noble/hashes/webcrypto.d.ts b/node_modules/@noble/hashes/webcrypto.d.ts new file mode 100644 index 0000000..9226c66 --- /dev/null +++ b/node_modules/@noble/hashes/webcrypto.d.ts @@ -0,0 +1,120 @@ +import { type Pbkdf2Opt } from './pbkdf2.ts'; +import { type KDFInput, type TArg, type TRet } from './utils.ts'; +/** Callable WebCrypto hash function descriptor. */ +export type WebHash = { + /** + * Hashes one message with the selected WebCrypto digest. + * @param msg - message bytes to hash + * @returns Promise resolving to digest bytes. + */ + (msg: TArg): Promise>; + /** WebCrypto algorithm name passed to `crypto.subtle`. */ + webCryptoName: string; + /** Digest size in bytes. */ + outputLen: number; + /** Input block size in bytes. */ + blockLen: number; +}; +/** WebCrypto SHA1 (RFC 3174) legacy hash function. It was cryptographically broken. */ +/** + * WebCrypto SHA2-256 hash function from RFC 6234. + * @param msg - message bytes to hash + * @returns Promise resolving to digest bytes. + * @example + * Hash a message with WebCrypto SHA2-256. + * ```ts + * await sha256(new Uint8Array([97, 98, 99])); + * ``` + */ +export declare const sha256: TRet; +/** + * WebCrypto SHA2-384 hash function from RFC 6234. + * @param msg - message bytes to hash + * @returns Promise resolving to digest bytes. + * @example + * Hash a message with WebCrypto SHA2-384. + * ```ts + * await sha384(new Uint8Array([97, 98, 99])); + * ``` + */ +export declare const sha384: TRet; +/** + * WebCrypto SHA2-512 hash function from RFC 6234. + * @param msg - message bytes to hash + * @returns Promise resolving to digest bytes. + * @example + * Hash a message with WebCrypto SHA2-512. + * ```ts + * await sha512(new Uint8Array([97, 98, 99])); + * ``` + */ +export declare const sha512: TRet; +/** + * WebCrypto HMAC: RFC2104 message authentication code. + * @param hash - function that would be used e.g. sha256. Webcrypto version. + * @param key - authentication key bytes + * @param message - message bytes to authenticate + * @returns Promise resolving to authentication tag bytes. + * `.create()` exists only to mirror the synchronous API surface + * and always throws `not implemented`. + * @example + * Compute an RFC 2104 HMAC with WebCrypto. + * ```ts + * import { hmac, sha256 } from '@noble/hashes/webcrypto.js'; + * await hmac(sha256, new Uint8Array([1, 2, 3]), new Uint8Array([4, 5, 6])); + * ``` + */ +type WebHmacFn = { + (hash: TArg, key: TArg, message: TArg): Promise>; + create(hash: TArg, key: TArg): any; +}; +export declare const hmac: TRet; +/** + * WebCrypto HKDF (RFC 5869): derive keys from an initial input. + * Combines hkdf_extract + hkdf_expand in one step + * @param hash - hash function that would be used (e.g. sha256). Webcrypto version. + * @param ikm - input keying material, the initial key + * @param salt - optional salt value (a non-secret random value) + * @param info - optional context and application specific information bytes + * @param length - length of output keying material in bytes. + * RFC 5869 §2.3 allows `0..255*HashLen`, so `0` requests an empty OKM. + * @returns Promise resolving to derived key bytes. + * The RFC `L <= 255 * HashLen` bound is currently enforced only by backend + * `deriveBits()` rejection, not by an explicit library-side guard. + * @throws If the current runtime does not provide `crypto.subtle`. {@link Error} + * @example + * WebCrypto HKDF (RFC 5869): derive keys from an initial input. + * ```ts + * import { hkdf, sha256 } from '@noble/hashes/webcrypto.js'; + * import { randomBytes, utf8ToBytes } from '@noble/hashes/utils.js'; + * const inputKey = randomBytes(32); + * const salt = randomBytes(32); + * const info = utf8ToBytes('application-key'); + * const okm = await hkdf(sha256, inputKey, salt, info, 32); + * ``` + */ +export declare function hkdf(hash: TArg, ikm: TArg, salt: TArg, info: TArg, length: number): Promise>; +/** + * WebCrypto PBKDF2-HMAC: RFC 8018 key derivation function. + * @param hash - hash function that would be used e.g. sha256. Webcrypto version. + * @param password - password from which a derived key is generated; string + * inputs are normalized through `kdfInputToBytes()`, i.e. UTF-8 + * @param salt - cryptographic salt; string inputs are normalized through + * `kdfInputToBytes()`, i.e. UTF-8 + * @param opts - PBKDF2 work factor and output settings. `dkLen`, if provided, + * must be `>= 1` per RFC 8018 §5.2. See {@link Pbkdf2Opt}. + * @returns Promise resolving to derived key bytes. + * Positive-iteration enforcement is currently delegated to backend + * `deriveBits()` rejection (for example `c = 0`), not a dedicated + * library-side guard. + * @throws If the current runtime does not provide `crypto.subtle`. {@link Error} + * @example + * WebCrypto PBKDF2-HMAC: RFC 2898 key derivation function. + * ```ts + * import { pbkdf2, sha256 } from '@noble/hashes/webcrypto.js'; + * const key = await pbkdf2(sha256, 'password', 'salt', { dkLen: 32, c: Math.pow(2, 18) }); + * ``` + */ +export declare function pbkdf2(hash: TArg, password: TArg, salt: TArg, opts: Pbkdf2Opt): Promise>; +export {}; +//# sourceMappingURL=webcrypto.d.ts.map \ No newline at end of file diff --git a/node_modules/@noble/hashes/webcrypto.d.ts.map b/node_modules/@noble/hashes/webcrypto.d.ts.map new file mode 100644 index 0000000..be40d07 --- /dev/null +++ b/node_modules/@noble/hashes/webcrypto.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"webcrypto.d.ts","sourceRoot":"","sources":["src/webcrypto.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAOL,KAAK,QAAQ,EACb,KAAK,IAAI,EACT,KAAK,IAAI,EACV,MAAM,YAAY,CAAC;AASpB,mDAAmD;AACnD,MAAM,MAAM,OAAO,GAAG;IACpB;;;;OAIG;IACH,CAAC,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;IACnD,0DAA0D;IAC1D,aAAa,EAAE,MAAM,CAAC;IACtB,4BAA4B;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,iCAAiC;IACjC,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AA0BF,uFAAuF;AAGvF;;;;;;;;;GASG;AACH,eAAO,MAAM,MAAM,EAAE,IAAI,CAAC,OAAO,CAAoD,CAAC;AACtF;;;;;;;;;GASG;AACH,eAAO,MAAM,MAAM,EAAE,IAAI,CAAC,OAAO,CAAqD,CAAC;AACvF;;;;;;;;;GASG;AACH,eAAO,MAAM,MAAM,EAAE,IAAI,CAAC,OAAO,CAAqD,CAAC;AAEvF;;;;;;;;;;;;;;GAcG;AACH,KAAK,SAAS,GAAG;IACf,CACE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,EACnB,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,EACrB,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC,GACxB,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;IAC7B,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,GAAG,GAAG,CAAC;CACzD,CAAC;AACF,eAAO,MAAM,IAAI,EAAE,IAAI,CAAC,SAAS,CA2B7B,CAAC;AAEL;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,IAAI,CACxB,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,EACnB,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,EACrB,IAAI,EAAE,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC,EAClC,IAAI,EAAE,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC,EAClC,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAe3B;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,MAAM,CAC1B,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,EACnB,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,EACxB,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,EACpB,IAAI,EAAE,SAAS,GACd,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAgB3B"} \ No newline at end of file diff --git a/node_modules/@noble/hashes/webcrypto.js b/node_modules/@noble/hashes/webcrypto.js new file mode 100644 index 0000000..0818023 --- /dev/null +++ b/node_modules/@noble/hashes/webcrypto.js @@ -0,0 +1,165 @@ +import {} from "./pbkdf2.js"; +import { abytes, ahash, anumber, checkOpts, kdfInputToBytes, } from "./utils.js"; +function _subtle() { + const cr = typeof globalThis === 'object' ? globalThis.crypto : null; + const sb = cr?.subtle; + if (typeof sb === 'object' && sb != null) + return sb; + throw new Error('crypto.subtle must be defined'); +} +function createWebHash(name, blockLen, outputLen) { + const hashC = async (msg) => { + abytes(msg); + const crypto = _subtle(); + return new Uint8Array(await crypto.digest(name, msg)); + }; + hashC.webCryptoName = name; // make sure it won't interfere with function name + hashC.outputLen = outputLen; + hashC.blockLen = blockLen; + hashC.create = () => { + // Present only so this async wrapper satisfies the shared + // hash-wrapper shape checked by `ahashWeb()`. + throw new Error('not implemented'); + }; + // Later WebCrypto HMAC/HKDF/PBKDF2 calls read descriptor metadata directly, so freezing prevents + // callers from retargeting a `sha256` wrapper into a different backend digest by mutation. + return Object.freeze(hashC); +} +function ahashWeb(hash) { + ahash(hash); + if (typeof hash.webCryptoName !== 'string') + throw new Error('non-web hash'); +} +/** WebCrypto SHA1 (RFC 3174) legacy hash function. It was cryptographically broken. */ +// export const sha1: WebHash = createHash('SHA-1', 64, 20); +/** + * WebCrypto SHA2-256 hash function from RFC 6234. + * @param msg - message bytes to hash + * @returns Promise resolving to digest bytes. + * @example + * Hash a message with WebCrypto SHA2-256. + * ```ts + * await sha256(new Uint8Array([97, 98, 99])); + * ``` + */ +export const sha256 = /* @__PURE__ */ createWebHash('SHA-256', 64, 32); +/** + * WebCrypto SHA2-384 hash function from RFC 6234. + * @param msg - message bytes to hash + * @returns Promise resolving to digest bytes. + * @example + * Hash a message with WebCrypto SHA2-384. + * ```ts + * await sha384(new Uint8Array([97, 98, 99])); + * ``` + */ +export const sha384 = /* @__PURE__ */ createWebHash('SHA-384', 128, 48); +/** + * WebCrypto SHA2-512 hash function from RFC 6234. + * @param msg - message bytes to hash + * @returns Promise resolving to digest bytes. + * @example + * Hash a message with WebCrypto SHA2-512. + * ```ts + * await sha512(new Uint8Array([97, 98, 99])); + * ``` + */ +export const sha512 = /* @__PURE__ */ createWebHash('SHA-512', 128, 64); +export const hmac = /* @__PURE__ */ (() => { + const hmac_ = async (hash, key, message) => { + const crypto = _subtle(); + abytes(key, undefined, 'key'); + abytes(message, undefined, 'message'); + ahashWeb(hash); + // WebCrypto keys can't be zeroized + // prettier-ignore + const wkey = await crypto.importKey('raw', key, { name: 'HMAC', hash: hash.webCryptoName }, false, ['sign']); + return new Uint8Array(await crypto.sign('HMAC', wkey, message)); + }; + hmac_.create = (_hash, _key) => { + throw new Error('not implemented'); + }; + return hmac_; +})(); +/** + * WebCrypto HKDF (RFC 5869): derive keys from an initial input. + * Combines hkdf_extract + hkdf_expand in one step + * @param hash - hash function that would be used (e.g. sha256). Webcrypto version. + * @param ikm - input keying material, the initial key + * @param salt - optional salt value (a non-secret random value) + * @param info - optional context and application specific information bytes + * @param length - length of output keying material in bytes. + * RFC 5869 §2.3 allows `0..255*HashLen`, so `0` requests an empty OKM. + * @returns Promise resolving to derived key bytes. + * The RFC `L <= 255 * HashLen` bound is currently enforced only by backend + * `deriveBits()` rejection, not by an explicit library-side guard. + * @throws If the current runtime does not provide `crypto.subtle`. {@link Error} + * @example + * WebCrypto HKDF (RFC 5869): derive keys from an initial input. + * ```ts + * import { hkdf, sha256 } from '@noble/hashes/webcrypto.js'; + * import { randomBytes, utf8ToBytes } from '@noble/hashes/utils.js'; + * const inputKey = randomBytes(32); + * const salt = randomBytes(32); + * const info = utf8ToBytes('application-key'); + * const okm = await hkdf(sha256, inputKey, salt, info, 32); + * ``` + */ +export async function hkdf(hash, ikm, salt, info, length) { + const crypto = _subtle(); + ahashWeb(hash); + abytes(ikm, undefined, 'ikm'); + anumber(length, 'length'); + if (salt !== undefined) + abytes(salt, undefined, 'salt'); + if (info !== undefined) + abytes(info, undefined, 'info'); + const wkey = await crypto.importKey('raw', ikm, 'HKDF', false, ['deriveBits']); + const opts = { + name: 'HKDF', + hash: hash.webCryptoName, + salt: salt === undefined ? new Uint8Array(0) : salt, + info: info === undefined ? new Uint8Array(0) : info, + }; + return new Uint8Array(await crypto.deriveBits(opts, wkey, 8 * length)); +} +/** + * WebCrypto PBKDF2-HMAC: RFC 8018 key derivation function. + * @param hash - hash function that would be used e.g. sha256. Webcrypto version. + * @param password - password from which a derived key is generated; string + * inputs are normalized through `kdfInputToBytes()`, i.e. UTF-8 + * @param salt - cryptographic salt; string inputs are normalized through + * `kdfInputToBytes()`, i.e. UTF-8 + * @param opts - PBKDF2 work factor and output settings. `dkLen`, if provided, + * must be `>= 1` per RFC 8018 §5.2. See {@link Pbkdf2Opt}. + * @returns Promise resolving to derived key bytes. + * Positive-iteration enforcement is currently delegated to backend + * `deriveBits()` rejection (for example `c = 0`), not a dedicated + * library-side guard. + * @throws If the current runtime does not provide `crypto.subtle`. {@link Error} + * @example + * WebCrypto PBKDF2-HMAC: RFC 2898 key derivation function. + * ```ts + * import { pbkdf2, sha256 } from '@noble/hashes/webcrypto.js'; + * const key = await pbkdf2(sha256, 'password', 'salt', { dkLen: 32, c: Math.pow(2, 18) }); + * ``` + */ +export async function pbkdf2(hash, password, salt, opts) { + const crypto = _subtle(); + ahashWeb(hash); + const _opts = checkOpts({ dkLen: 32 }, opts); + const { c, dkLen } = _opts; + anumber(c, 'c'); + anumber(dkLen, 'dkLen'); + // RFC 8018 §5.2 defines dkLen as a positive integer. + if (dkLen < 1) + throw new Error('"dkLen" must be >= 1'); + const _password = kdfInputToBytes(password, 'password'); + const _salt = kdfInputToBytes(salt, 'salt'); + const key = await crypto.importKey('raw', _password, 'PBKDF2', false, [ + 'deriveBits', + ]); + const deriveOpts = { name: 'PBKDF2', salt: _salt, iterations: c, hash: hash.webCryptoName }; + return new Uint8Array(await crypto.deriveBits(deriveOpts, key, 8 * dkLen)); +} +//# sourceMappingURL=webcrypto.js.map \ No newline at end of file diff --git a/node_modules/@noble/hashes/webcrypto.js.map b/node_modules/@noble/hashes/webcrypto.js.map new file mode 100644 index 0000000..f489b26 --- /dev/null +++ b/node_modules/@noble/hashes/webcrypto.js.map @@ -0,0 +1 @@ +{"version":3,"file":"webcrypto.js","sourceRoot":"","sources":["src/webcrypto.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/crypto-js/CONTRIBUTING.md b/node_modules/crypto-js/CONTRIBUTING.md new file mode 100644 index 0000000..09bf774 --- /dev/null +++ b/node_modules/crypto-js/CONTRIBUTING.md @@ -0,0 +1,28 @@ +# Contribution + +# Git Flow + +The crypto-js project uses [git flow](https://github.com/nvie/gitflow) to manage branches. +Do your changes on the `develop` or even better on a `feature/*` branch. Don't do any changes on the `master` branch. + +# Pull request + +Target your pull request on `develop` branch. Other pull request won't be accepted. + +# How to build + +1. Clone + +2. Run + + ```sh + npm install + ``` + +3. Run + + ```sh + npm run build + ``` + +4. Check `build` folder \ No newline at end of file diff --git a/node_modules/crypto-js/LICENSE b/node_modules/crypto-js/LICENSE new file mode 100644 index 0000000..b0828e5 --- /dev/null +++ b/node_modules/crypto-js/LICENSE @@ -0,0 +1,24 @@ +# License + +[The MIT License (MIT)](http://opensource.org/licenses/MIT) + +Copyright (c) 2009-2013 Jeff Mott +Copyright (c) 2013-2016 Evan Vosberg + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/crypto-js/README.md b/node_modules/crypto-js/README.md new file mode 100644 index 0000000..6a9bcdf --- /dev/null +++ b/node_modules/crypto-js/README.md @@ -0,0 +1,275 @@ +# crypto-js + +JavaScript library of crypto standards. + +## Discontinued + +Active development of CryptoJS has been discontinued. This library is no longer maintained. + +Nowadays, NodeJS and modern browsers have a native `Crypto` module. The latest version of CryptoJS already uses the native Crypto module for random number generation, since `Math.random()` is not crypto-safe. Further development of CryptoJS would result in it only being a wrapper of native Crypto. Therefore, development and maintenance has been discontinued, it is time to go for the native `crypto` module. + +## Node.js (Install) + +Requirements: + +- Node.js +- npm (Node.js package manager) + +```bash +npm install crypto-js +``` + +### Usage + +ES6 import for typical API call signing use case: + +```javascript +import sha256 from 'crypto-js/sha256'; +import hmacSHA512 from 'crypto-js/hmac-sha512'; +import Base64 from 'crypto-js/enc-base64'; + +const message, nonce, path, privateKey; // ... +const hashDigest = sha256(nonce + message); +const hmacDigest = Base64.stringify(hmacSHA512(path + hashDigest, privateKey)); +``` + +Modular include: + +```javascript +var AES = require("crypto-js/aes"); +var SHA256 = require("crypto-js/sha256"); +... +console.log(SHA256("Message")); +``` + +Including all libraries, for access to extra methods: + +```javascript +var CryptoJS = require("crypto-js"); +console.log(CryptoJS.HmacSHA1("Message", "Key")); +``` + +## Client (browser) + +Requirements: + +- Node.js +- Bower (package manager for frontend) + +```bash +bower install crypto-js +``` + +### Usage + +Modular include: + +```javascript +require.config({ + packages: [ + { + name: 'crypto-js', + location: 'path-to/bower_components/crypto-js', + main: 'index' + } + ] +}); + +require(["crypto-js/aes", "crypto-js/sha256"], function (AES, SHA256) { + console.log(SHA256("Message")); +}); +``` + +Including all libraries, for access to extra methods: + +```javascript +// Above-mentioned will work or use this simple form +require.config({ + paths: { + 'crypto-js': 'path-to/bower_components/crypto-js/crypto-js' + } +}); + +require(["crypto-js"], function (CryptoJS) { + console.log(CryptoJS.HmacSHA1("Message", "Key")); +}); +``` + +### Usage without RequireJS + +```html + + +``` + +## API + +See: https://cryptojs.gitbook.io/docs/ + +### AES Encryption + +#### Plain text encryption + +```javascript +var CryptoJS = require("crypto-js"); + +// Encrypt +var ciphertext = CryptoJS.AES.encrypt('my message', 'secret key 123').toString(); + +// Decrypt +var bytes = CryptoJS.AES.decrypt(ciphertext, 'secret key 123'); +var originalText = bytes.toString(CryptoJS.enc.Utf8); + +console.log(originalText); // 'my message' +``` + +#### Object encryption + +```javascript +var CryptoJS = require("crypto-js"); + +var data = [{id: 1}, {id: 2}] + +// Encrypt +var ciphertext = CryptoJS.AES.encrypt(JSON.stringify(data), 'secret key 123').toString(); + +// Decrypt +var bytes = CryptoJS.AES.decrypt(ciphertext, 'secret key 123'); +var decryptedData = JSON.parse(bytes.toString(CryptoJS.enc.Utf8)); + +console.log(decryptedData); // [{id: 1}, {id: 2}] +``` + +### List of modules + + +- ```crypto-js/core``` +- ```crypto-js/x64-core``` +- ```crypto-js/lib-typedarrays``` + +--- + +- ```crypto-js/md5``` +- ```crypto-js/sha1``` +- ```crypto-js/sha256``` +- ```crypto-js/sha224``` +- ```crypto-js/sha512``` +- ```crypto-js/sha384``` +- ```crypto-js/sha3``` +- ```crypto-js/ripemd160``` + +--- + +- ```crypto-js/hmac-md5``` +- ```crypto-js/hmac-sha1``` +- ```crypto-js/hmac-sha256``` +- ```crypto-js/hmac-sha224``` +- ```crypto-js/hmac-sha512``` +- ```crypto-js/hmac-sha384``` +- ```crypto-js/hmac-sha3``` +- ```crypto-js/hmac-ripemd160``` + +--- + +- ```crypto-js/pbkdf2``` + +--- + +- ```crypto-js/aes``` +- ```crypto-js/tripledes``` +- ```crypto-js/rc4``` +- ```crypto-js/rabbit``` +- ```crypto-js/rabbit-legacy``` +- ```crypto-js/evpkdf``` + +--- + +- ```crypto-js/format-openssl``` +- ```crypto-js/format-hex``` + +--- + +- ```crypto-js/enc-latin1``` +- ```crypto-js/enc-utf8``` +- ```crypto-js/enc-hex``` +- ```crypto-js/enc-utf16``` +- ```crypto-js/enc-base64``` + +--- + +- ```crypto-js/mode-cfb``` +- ```crypto-js/mode-ctr``` +- ```crypto-js/mode-ctr-gladman``` +- ```crypto-js/mode-ofb``` +- ```crypto-js/mode-ecb``` + +--- + +- ```crypto-js/pad-pkcs7``` +- ```crypto-js/pad-ansix923``` +- ```crypto-js/pad-iso10126``` +- ```crypto-js/pad-iso97971``` +- ```crypto-js/pad-zeropadding``` +- ```crypto-js/pad-nopadding``` + + +## Release notes + +### 4.2.0 + +Change default hash algorithm and iteration's for PBKDF2 to prevent weak security by using the default configuration. + +Custom KDF Hasher + +Blowfish support + +### 4.1.1 + +Fix module order in bundled release. + +Include the browser field in the released package.json. + +### 4.1.0 + +Added url safe variant of base64 encoding. [357](https://github.com/brix/crypto-js/pull/357) + +Avoid webpack to add crypto-browser package. [364](https://github.com/brix/crypto-js/pull/364) + +### 4.0.0 + +This is an update including breaking changes for some environments. + +In this version `Math.random()` has been replaced by the random methods of the native crypto module. + +For this reason CryptoJS might not run in some JavaScript environments without native crypto module. Such as IE 10 or before or React Native. + +### 3.3.0 + +Rollback, `3.3.0` is the same as `3.1.9-1`. + +The move of using native secure crypto module will be shifted to a new `4.x.x` version. As it is a breaking change the impact is too big for a minor release. + +### 3.2.1 + +The usage of the native crypto module has been fixed. The import and access of the native crypto module has been improved. + +### 3.2.0 + +In this version `Math.random()` has been replaced by the random methods of the native crypto module. + +For this reason CryptoJS might does not run in some JavaScript environments without native crypto module. Such as IE 10 or before. + +If it's absolute required to run CryptoJS in such an environment, stay with `3.1.x` version. Encrypting and decrypting stays compatible. But keep in mind `3.1.x` versions still use `Math.random()` which is cryptographically not secure, as it's not random enough. + +This version came along with `CRITICAL` `BUG`. + +DO NOT USE THIS VERSION! Please, go for a newer version! + +### 3.1.x + +The `3.1.x` are based on the original CryptoJS, wrapped in CommonJS modules. + + diff --git a/node_modules/crypto-js/aes.js b/node_modules/crypto-js/aes.js new file mode 100644 index 0000000..166e3ea --- /dev/null +++ b/node_modules/crypto-js/aes.js @@ -0,0 +1,234 @@ +;(function (root, factory, undef) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require("./core"), require("./enc-base64"), require("./md5"), require("./evpkdf"), require("./cipher-core")); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core", "./enc-base64", "./md5", "./evpkdf", "./cipher-core"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + (function () { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var BlockCipher = C_lib.BlockCipher; + var C_algo = C.algo; + + // Lookup tables + var SBOX = []; + var INV_SBOX = []; + var SUB_MIX_0 = []; + var SUB_MIX_1 = []; + var SUB_MIX_2 = []; + var SUB_MIX_3 = []; + var INV_SUB_MIX_0 = []; + var INV_SUB_MIX_1 = []; + var INV_SUB_MIX_2 = []; + var INV_SUB_MIX_3 = []; + + // Compute lookup tables + (function () { + // Compute double table + var d = []; + for (var i = 0; i < 256; i++) { + if (i < 128) { + d[i] = i << 1; + } else { + d[i] = (i << 1) ^ 0x11b; + } + } + + // Walk GF(2^8) + var x = 0; + var xi = 0; + for (var i = 0; i < 256; i++) { + // Compute sbox + var sx = xi ^ (xi << 1) ^ (xi << 2) ^ (xi << 3) ^ (xi << 4); + sx = (sx >>> 8) ^ (sx & 0xff) ^ 0x63; + SBOX[x] = sx; + INV_SBOX[sx] = x; + + // Compute multiplication + var x2 = d[x]; + var x4 = d[x2]; + var x8 = d[x4]; + + // Compute sub bytes, mix columns tables + var t = (d[sx] * 0x101) ^ (sx * 0x1010100); + SUB_MIX_0[x] = (t << 24) | (t >>> 8); + SUB_MIX_1[x] = (t << 16) | (t >>> 16); + SUB_MIX_2[x] = (t << 8) | (t >>> 24); + SUB_MIX_3[x] = t; + + // Compute inv sub bytes, inv mix columns tables + var t = (x8 * 0x1010101) ^ (x4 * 0x10001) ^ (x2 * 0x101) ^ (x * 0x1010100); + INV_SUB_MIX_0[sx] = (t << 24) | (t >>> 8); + INV_SUB_MIX_1[sx] = (t << 16) | (t >>> 16); + INV_SUB_MIX_2[sx] = (t << 8) | (t >>> 24); + INV_SUB_MIX_3[sx] = t; + + // Compute next counter + if (!x) { + x = xi = 1; + } else { + x = x2 ^ d[d[d[x8 ^ x2]]]; + xi ^= d[d[xi]]; + } + } + }()); + + // Precomputed Rcon lookup + var RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36]; + + /** + * AES block cipher algorithm. + */ + var AES = C_algo.AES = BlockCipher.extend({ + _doReset: function () { + var t; + + // Skip reset of nRounds has been set before and key did not change + if (this._nRounds && this._keyPriorReset === this._key) { + return; + } + + // Shortcuts + var key = this._keyPriorReset = this._key; + var keyWords = key.words; + var keySize = key.sigBytes / 4; + + // Compute number of rounds + var nRounds = this._nRounds = keySize + 6; + + // Compute number of key schedule rows + var ksRows = (nRounds + 1) * 4; + + // Compute key schedule + var keySchedule = this._keySchedule = []; + for (var ksRow = 0; ksRow < ksRows; ksRow++) { + if (ksRow < keySize) { + keySchedule[ksRow] = keyWords[ksRow]; + } else { + t = keySchedule[ksRow - 1]; + + if (!(ksRow % keySize)) { + // Rot word + t = (t << 8) | (t >>> 24); + + // Sub word + t = (SBOX[t >>> 24] << 24) | (SBOX[(t >>> 16) & 0xff] << 16) | (SBOX[(t >>> 8) & 0xff] << 8) | SBOX[t & 0xff]; + + // Mix Rcon + t ^= RCON[(ksRow / keySize) | 0] << 24; + } else if (keySize > 6 && ksRow % keySize == 4) { + // Sub word + t = (SBOX[t >>> 24] << 24) | (SBOX[(t >>> 16) & 0xff] << 16) | (SBOX[(t >>> 8) & 0xff] << 8) | SBOX[t & 0xff]; + } + + keySchedule[ksRow] = keySchedule[ksRow - keySize] ^ t; + } + } + + // Compute inv key schedule + var invKeySchedule = this._invKeySchedule = []; + for (var invKsRow = 0; invKsRow < ksRows; invKsRow++) { + var ksRow = ksRows - invKsRow; + + if (invKsRow % 4) { + var t = keySchedule[ksRow]; + } else { + var t = keySchedule[ksRow - 4]; + } + + if (invKsRow < 4 || ksRow <= 4) { + invKeySchedule[invKsRow] = t; + } else { + invKeySchedule[invKsRow] = INV_SUB_MIX_0[SBOX[t >>> 24]] ^ INV_SUB_MIX_1[SBOX[(t >>> 16) & 0xff]] ^ + INV_SUB_MIX_2[SBOX[(t >>> 8) & 0xff]] ^ INV_SUB_MIX_3[SBOX[t & 0xff]]; + } + } + }, + + encryptBlock: function (M, offset) { + this._doCryptBlock(M, offset, this._keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX); + }, + + decryptBlock: function (M, offset) { + // Swap 2nd and 4th rows + var t = M[offset + 1]; + M[offset + 1] = M[offset + 3]; + M[offset + 3] = t; + + this._doCryptBlock(M, offset, this._invKeySchedule, INV_SUB_MIX_0, INV_SUB_MIX_1, INV_SUB_MIX_2, INV_SUB_MIX_3, INV_SBOX); + + // Inv swap 2nd and 4th rows + var t = M[offset + 1]; + M[offset + 1] = M[offset + 3]; + M[offset + 3] = t; + }, + + _doCryptBlock: function (M, offset, keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX) { + // Shortcut + var nRounds = this._nRounds; + + // Get input, add round key + var s0 = M[offset] ^ keySchedule[0]; + var s1 = M[offset + 1] ^ keySchedule[1]; + var s2 = M[offset + 2] ^ keySchedule[2]; + var s3 = M[offset + 3] ^ keySchedule[3]; + + // Key schedule row counter + var ksRow = 4; + + // Rounds + for (var round = 1; round < nRounds; round++) { + // Shift rows, sub bytes, mix columns, add round key + var t0 = SUB_MIX_0[s0 >>> 24] ^ SUB_MIX_1[(s1 >>> 16) & 0xff] ^ SUB_MIX_2[(s2 >>> 8) & 0xff] ^ SUB_MIX_3[s3 & 0xff] ^ keySchedule[ksRow++]; + var t1 = SUB_MIX_0[s1 >>> 24] ^ SUB_MIX_1[(s2 >>> 16) & 0xff] ^ SUB_MIX_2[(s3 >>> 8) & 0xff] ^ SUB_MIX_3[s0 & 0xff] ^ keySchedule[ksRow++]; + var t2 = SUB_MIX_0[s2 >>> 24] ^ SUB_MIX_1[(s3 >>> 16) & 0xff] ^ SUB_MIX_2[(s0 >>> 8) & 0xff] ^ SUB_MIX_3[s1 & 0xff] ^ keySchedule[ksRow++]; + var t3 = SUB_MIX_0[s3 >>> 24] ^ SUB_MIX_1[(s0 >>> 16) & 0xff] ^ SUB_MIX_2[(s1 >>> 8) & 0xff] ^ SUB_MIX_3[s2 & 0xff] ^ keySchedule[ksRow++]; + + // Update state + s0 = t0; + s1 = t1; + s2 = t2; + s3 = t3; + } + + // Shift rows, sub bytes, add round key + var t0 = ((SBOX[s0 >>> 24] << 24) | (SBOX[(s1 >>> 16) & 0xff] << 16) | (SBOX[(s2 >>> 8) & 0xff] << 8) | SBOX[s3 & 0xff]) ^ keySchedule[ksRow++]; + var t1 = ((SBOX[s1 >>> 24] << 24) | (SBOX[(s2 >>> 16) & 0xff] << 16) | (SBOX[(s3 >>> 8) & 0xff] << 8) | SBOX[s0 & 0xff]) ^ keySchedule[ksRow++]; + var t2 = ((SBOX[s2 >>> 24] << 24) | (SBOX[(s3 >>> 16) & 0xff] << 16) | (SBOX[(s0 >>> 8) & 0xff] << 8) | SBOX[s1 & 0xff]) ^ keySchedule[ksRow++]; + var t3 = ((SBOX[s3 >>> 24] << 24) | (SBOX[(s0 >>> 16) & 0xff] << 16) | (SBOX[(s1 >>> 8) & 0xff] << 8) | SBOX[s2 & 0xff]) ^ keySchedule[ksRow++]; + + // Set output + M[offset] = t0; + M[offset + 1] = t1; + M[offset + 2] = t2; + M[offset + 3] = t3; + }, + + keySize: 256/32 + }); + + /** + * Shortcut functions to the cipher's object interface. + * + * @example + * + * var ciphertext = CryptoJS.AES.encrypt(message, key, cfg); + * var plaintext = CryptoJS.AES.decrypt(ciphertext, key, cfg); + */ + C.AES = BlockCipher._createHelper(AES); + }()); + + + return CryptoJS.AES; + +})); \ No newline at end of file diff --git a/node_modules/crypto-js/blowfish.js b/node_modules/crypto-js/blowfish.js new file mode 100644 index 0000000..149812f --- /dev/null +++ b/node_modules/crypto-js/blowfish.js @@ -0,0 +1,471 @@ +;(function (root, factory, undef) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require("./core"), require("./enc-base64"), require("./md5"), require("./evpkdf"), require("./cipher-core")); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core", "./enc-base64", "./md5", "./evpkdf", "./cipher-core"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + (function () { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var BlockCipher = C_lib.BlockCipher; + var C_algo = C.algo; + + const N = 16; + + //Origin pbox and sbox, derived from PI + const ORIG_P = [ + 0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344, + 0xA4093822, 0x299F31D0, 0x082EFA98, 0xEC4E6C89, + 0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C, + 0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917, + 0x9216D5D9, 0x8979FB1B + ]; + + const ORIG_S = [ + [ 0xD1310BA6, 0x98DFB5AC, 0x2FFD72DB, 0xD01ADFB7, + 0xB8E1AFED, 0x6A267E96, 0xBA7C9045, 0xF12C7F99, + 0x24A19947, 0xB3916CF7, 0x0801F2E2, 0x858EFC16, + 0x636920D8, 0x71574E69, 0xA458FEA3, 0xF4933D7E, + 0x0D95748F, 0x728EB658, 0x718BCD58, 0x82154AEE, + 0x7B54A41D, 0xC25A59B5, 0x9C30D539, 0x2AF26013, + 0xC5D1B023, 0x286085F0, 0xCA417918, 0xB8DB38EF, + 0x8E79DCB0, 0x603A180E, 0x6C9E0E8B, 0xB01E8A3E, + 0xD71577C1, 0xBD314B27, 0x78AF2FDA, 0x55605C60, + 0xE65525F3, 0xAA55AB94, 0x57489862, 0x63E81440, + 0x55CA396A, 0x2AAB10B6, 0xB4CC5C34, 0x1141E8CE, + 0xA15486AF, 0x7C72E993, 0xB3EE1411, 0x636FBC2A, + 0x2BA9C55D, 0x741831F6, 0xCE5C3E16, 0x9B87931E, + 0xAFD6BA33, 0x6C24CF5C, 0x7A325381, 0x28958677, + 0x3B8F4898, 0x6B4BB9AF, 0xC4BFE81B, 0x66282193, + 0x61D809CC, 0xFB21A991, 0x487CAC60, 0x5DEC8032, + 0xEF845D5D, 0xE98575B1, 0xDC262302, 0xEB651B88, + 0x23893E81, 0xD396ACC5, 0x0F6D6FF3, 0x83F44239, + 0x2E0B4482, 0xA4842004, 0x69C8F04A, 0x9E1F9B5E, + 0x21C66842, 0xF6E96C9A, 0x670C9C61, 0xABD388F0, + 0x6A51A0D2, 0xD8542F68, 0x960FA728, 0xAB5133A3, + 0x6EEF0B6C, 0x137A3BE4, 0xBA3BF050, 0x7EFB2A98, + 0xA1F1651D, 0x39AF0176, 0x66CA593E, 0x82430E88, + 0x8CEE8619, 0x456F9FB4, 0x7D84A5C3, 0x3B8B5EBE, + 0xE06F75D8, 0x85C12073, 0x401A449F, 0x56C16AA6, + 0x4ED3AA62, 0x363F7706, 0x1BFEDF72, 0x429B023D, + 0x37D0D724, 0xD00A1248, 0xDB0FEAD3, 0x49F1C09B, + 0x075372C9, 0x80991B7B, 0x25D479D8, 0xF6E8DEF7, + 0xE3FE501A, 0xB6794C3B, 0x976CE0BD, 0x04C006BA, + 0xC1A94FB6, 0x409F60C4, 0x5E5C9EC2, 0x196A2463, + 0x68FB6FAF, 0x3E6C53B5, 0x1339B2EB, 0x3B52EC6F, + 0x6DFC511F, 0x9B30952C, 0xCC814544, 0xAF5EBD09, + 0xBEE3D004, 0xDE334AFD, 0x660F2807, 0x192E4BB3, + 0xC0CBA857, 0x45C8740F, 0xD20B5F39, 0xB9D3FBDB, + 0x5579C0BD, 0x1A60320A, 0xD6A100C6, 0x402C7279, + 0x679F25FE, 0xFB1FA3CC, 0x8EA5E9F8, 0xDB3222F8, + 0x3C7516DF, 0xFD616B15, 0x2F501EC8, 0xAD0552AB, + 0x323DB5FA, 0xFD238760, 0x53317B48, 0x3E00DF82, + 0x9E5C57BB, 0xCA6F8CA0, 0x1A87562E, 0xDF1769DB, + 0xD542A8F6, 0x287EFFC3, 0xAC6732C6, 0x8C4F5573, + 0x695B27B0, 0xBBCA58C8, 0xE1FFA35D, 0xB8F011A0, + 0x10FA3D98, 0xFD2183B8, 0x4AFCB56C, 0x2DD1D35B, + 0x9A53E479, 0xB6F84565, 0xD28E49BC, 0x4BFB9790, + 0xE1DDF2DA, 0xA4CB7E33, 0x62FB1341, 0xCEE4C6E8, + 0xEF20CADA, 0x36774C01, 0xD07E9EFE, 0x2BF11FB4, + 0x95DBDA4D, 0xAE909198, 0xEAAD8E71, 0x6B93D5A0, + 0xD08ED1D0, 0xAFC725E0, 0x8E3C5B2F, 0x8E7594B7, + 0x8FF6E2FB, 0xF2122B64, 0x8888B812, 0x900DF01C, + 0x4FAD5EA0, 0x688FC31C, 0xD1CFF191, 0xB3A8C1AD, + 0x2F2F2218, 0xBE0E1777, 0xEA752DFE, 0x8B021FA1, + 0xE5A0CC0F, 0xB56F74E8, 0x18ACF3D6, 0xCE89E299, + 0xB4A84FE0, 0xFD13E0B7, 0x7CC43B81, 0xD2ADA8D9, + 0x165FA266, 0x80957705, 0x93CC7314, 0x211A1477, + 0xE6AD2065, 0x77B5FA86, 0xC75442F5, 0xFB9D35CF, + 0xEBCDAF0C, 0x7B3E89A0, 0xD6411BD3, 0xAE1E7E49, + 0x00250E2D, 0x2071B35E, 0x226800BB, 0x57B8E0AF, + 0x2464369B, 0xF009B91E, 0x5563911D, 0x59DFA6AA, + 0x78C14389, 0xD95A537F, 0x207D5BA2, 0x02E5B9C5, + 0x83260376, 0x6295CFA9, 0x11C81968, 0x4E734A41, + 0xB3472DCA, 0x7B14A94A, 0x1B510052, 0x9A532915, + 0xD60F573F, 0xBC9BC6E4, 0x2B60A476, 0x81E67400, + 0x08BA6FB5, 0x571BE91F, 0xF296EC6B, 0x2A0DD915, + 0xB6636521, 0xE7B9F9B6, 0xFF34052E, 0xC5855664, + 0x53B02D5D, 0xA99F8FA1, 0x08BA4799, 0x6E85076A ], + [ 0x4B7A70E9, 0xB5B32944, 0xDB75092E, 0xC4192623, + 0xAD6EA6B0, 0x49A7DF7D, 0x9CEE60B8, 0x8FEDB266, + 0xECAA8C71, 0x699A17FF, 0x5664526C, 0xC2B19EE1, + 0x193602A5, 0x75094C29, 0xA0591340, 0xE4183A3E, + 0x3F54989A, 0x5B429D65, 0x6B8FE4D6, 0x99F73FD6, + 0xA1D29C07, 0xEFE830F5, 0x4D2D38E6, 0xF0255DC1, + 0x4CDD2086, 0x8470EB26, 0x6382E9C6, 0x021ECC5E, + 0x09686B3F, 0x3EBAEFC9, 0x3C971814, 0x6B6A70A1, + 0x687F3584, 0x52A0E286, 0xB79C5305, 0xAA500737, + 0x3E07841C, 0x7FDEAE5C, 0x8E7D44EC, 0x5716F2B8, + 0xB03ADA37, 0xF0500C0D, 0xF01C1F04, 0x0200B3FF, + 0xAE0CF51A, 0x3CB574B2, 0x25837A58, 0xDC0921BD, + 0xD19113F9, 0x7CA92FF6, 0x94324773, 0x22F54701, + 0x3AE5E581, 0x37C2DADC, 0xC8B57634, 0x9AF3DDA7, + 0xA9446146, 0x0FD0030E, 0xECC8C73E, 0xA4751E41, + 0xE238CD99, 0x3BEA0E2F, 0x3280BBA1, 0x183EB331, + 0x4E548B38, 0x4F6DB908, 0x6F420D03, 0xF60A04BF, + 0x2CB81290, 0x24977C79, 0x5679B072, 0xBCAF89AF, + 0xDE9A771F, 0xD9930810, 0xB38BAE12, 0xDCCF3F2E, + 0x5512721F, 0x2E6B7124, 0x501ADDE6, 0x9F84CD87, + 0x7A584718, 0x7408DA17, 0xBC9F9ABC, 0xE94B7D8C, + 0xEC7AEC3A, 0xDB851DFA, 0x63094366, 0xC464C3D2, + 0xEF1C1847, 0x3215D908, 0xDD433B37, 0x24C2BA16, + 0x12A14D43, 0x2A65C451, 0x50940002, 0x133AE4DD, + 0x71DFF89E, 0x10314E55, 0x81AC77D6, 0x5F11199B, + 0x043556F1, 0xD7A3C76B, 0x3C11183B, 0x5924A509, + 0xF28FE6ED, 0x97F1FBFA, 0x9EBABF2C, 0x1E153C6E, + 0x86E34570, 0xEAE96FB1, 0x860E5E0A, 0x5A3E2AB3, + 0x771FE71C, 0x4E3D06FA, 0x2965DCB9, 0x99E71D0F, + 0x803E89D6, 0x5266C825, 0x2E4CC978, 0x9C10B36A, + 0xC6150EBA, 0x94E2EA78, 0xA5FC3C53, 0x1E0A2DF4, + 0xF2F74EA7, 0x361D2B3D, 0x1939260F, 0x19C27960, + 0x5223A708, 0xF71312B6, 0xEBADFE6E, 0xEAC31F66, + 0xE3BC4595, 0xA67BC883, 0xB17F37D1, 0x018CFF28, + 0xC332DDEF, 0xBE6C5AA5, 0x65582185, 0x68AB9802, + 0xEECEA50F, 0xDB2F953B, 0x2AEF7DAD, 0x5B6E2F84, + 0x1521B628, 0x29076170, 0xECDD4775, 0x619F1510, + 0x13CCA830, 0xEB61BD96, 0x0334FE1E, 0xAA0363CF, + 0xB5735C90, 0x4C70A239, 0xD59E9E0B, 0xCBAADE14, + 0xEECC86BC, 0x60622CA7, 0x9CAB5CAB, 0xB2F3846E, + 0x648B1EAF, 0x19BDF0CA, 0xA02369B9, 0x655ABB50, + 0x40685A32, 0x3C2AB4B3, 0x319EE9D5, 0xC021B8F7, + 0x9B540B19, 0x875FA099, 0x95F7997E, 0x623D7DA8, + 0xF837889A, 0x97E32D77, 0x11ED935F, 0x16681281, + 0x0E358829, 0xC7E61FD6, 0x96DEDFA1, 0x7858BA99, + 0x57F584A5, 0x1B227263, 0x9B83C3FF, 0x1AC24696, + 0xCDB30AEB, 0x532E3054, 0x8FD948E4, 0x6DBC3128, + 0x58EBF2EF, 0x34C6FFEA, 0xFE28ED61, 0xEE7C3C73, + 0x5D4A14D9, 0xE864B7E3, 0x42105D14, 0x203E13E0, + 0x45EEE2B6, 0xA3AAABEA, 0xDB6C4F15, 0xFACB4FD0, + 0xC742F442, 0xEF6ABBB5, 0x654F3B1D, 0x41CD2105, + 0xD81E799E, 0x86854DC7, 0xE44B476A, 0x3D816250, + 0xCF62A1F2, 0x5B8D2646, 0xFC8883A0, 0xC1C7B6A3, + 0x7F1524C3, 0x69CB7492, 0x47848A0B, 0x5692B285, + 0x095BBF00, 0xAD19489D, 0x1462B174, 0x23820E00, + 0x58428D2A, 0x0C55F5EA, 0x1DADF43E, 0x233F7061, + 0x3372F092, 0x8D937E41, 0xD65FECF1, 0x6C223BDB, + 0x7CDE3759, 0xCBEE7460, 0x4085F2A7, 0xCE77326E, + 0xA6078084, 0x19F8509E, 0xE8EFD855, 0x61D99735, + 0xA969A7AA, 0xC50C06C2, 0x5A04ABFC, 0x800BCADC, + 0x9E447A2E, 0xC3453484, 0xFDD56705, 0x0E1E9EC9, + 0xDB73DBD3, 0x105588CD, 0x675FDA79, 0xE3674340, + 0xC5C43465, 0x713E38D8, 0x3D28F89E, 0xF16DFF20, + 0x153E21E7, 0x8FB03D4A, 0xE6E39F2B, 0xDB83ADF7 ], + [ 0xE93D5A68, 0x948140F7, 0xF64C261C, 0x94692934, + 0x411520F7, 0x7602D4F7, 0xBCF46B2E, 0xD4A20068, + 0xD4082471, 0x3320F46A, 0x43B7D4B7, 0x500061AF, + 0x1E39F62E, 0x97244546, 0x14214F74, 0xBF8B8840, + 0x4D95FC1D, 0x96B591AF, 0x70F4DDD3, 0x66A02F45, + 0xBFBC09EC, 0x03BD9785, 0x7FAC6DD0, 0x31CB8504, + 0x96EB27B3, 0x55FD3941, 0xDA2547E6, 0xABCA0A9A, + 0x28507825, 0x530429F4, 0x0A2C86DA, 0xE9B66DFB, + 0x68DC1462, 0xD7486900, 0x680EC0A4, 0x27A18DEE, + 0x4F3FFEA2, 0xE887AD8C, 0xB58CE006, 0x7AF4D6B6, + 0xAACE1E7C, 0xD3375FEC, 0xCE78A399, 0x406B2A42, + 0x20FE9E35, 0xD9F385B9, 0xEE39D7AB, 0x3B124E8B, + 0x1DC9FAF7, 0x4B6D1856, 0x26A36631, 0xEAE397B2, + 0x3A6EFA74, 0xDD5B4332, 0x6841E7F7, 0xCA7820FB, + 0xFB0AF54E, 0xD8FEB397, 0x454056AC, 0xBA489527, + 0x55533A3A, 0x20838D87, 0xFE6BA9B7, 0xD096954B, + 0x55A867BC, 0xA1159A58, 0xCCA92963, 0x99E1DB33, + 0xA62A4A56, 0x3F3125F9, 0x5EF47E1C, 0x9029317C, + 0xFDF8E802, 0x04272F70, 0x80BB155C, 0x05282CE3, + 0x95C11548, 0xE4C66D22, 0x48C1133F, 0xC70F86DC, + 0x07F9C9EE, 0x41041F0F, 0x404779A4, 0x5D886E17, + 0x325F51EB, 0xD59BC0D1, 0xF2BCC18F, 0x41113564, + 0x257B7834, 0x602A9C60, 0xDFF8E8A3, 0x1F636C1B, + 0x0E12B4C2, 0x02E1329E, 0xAF664FD1, 0xCAD18115, + 0x6B2395E0, 0x333E92E1, 0x3B240B62, 0xEEBEB922, + 0x85B2A20E, 0xE6BA0D99, 0xDE720C8C, 0x2DA2F728, + 0xD0127845, 0x95B794FD, 0x647D0862, 0xE7CCF5F0, + 0x5449A36F, 0x877D48FA, 0xC39DFD27, 0xF33E8D1E, + 0x0A476341, 0x992EFF74, 0x3A6F6EAB, 0xF4F8FD37, + 0xA812DC60, 0xA1EBDDF8, 0x991BE14C, 0xDB6E6B0D, + 0xC67B5510, 0x6D672C37, 0x2765D43B, 0xDCD0E804, + 0xF1290DC7, 0xCC00FFA3, 0xB5390F92, 0x690FED0B, + 0x667B9FFB, 0xCEDB7D9C, 0xA091CF0B, 0xD9155EA3, + 0xBB132F88, 0x515BAD24, 0x7B9479BF, 0x763BD6EB, + 0x37392EB3, 0xCC115979, 0x8026E297, 0xF42E312D, + 0x6842ADA7, 0xC66A2B3B, 0x12754CCC, 0x782EF11C, + 0x6A124237, 0xB79251E7, 0x06A1BBE6, 0x4BFB6350, + 0x1A6B1018, 0x11CAEDFA, 0x3D25BDD8, 0xE2E1C3C9, + 0x44421659, 0x0A121386, 0xD90CEC6E, 0xD5ABEA2A, + 0x64AF674E, 0xDA86A85F, 0xBEBFE988, 0x64E4C3FE, + 0x9DBC8057, 0xF0F7C086, 0x60787BF8, 0x6003604D, + 0xD1FD8346, 0xF6381FB0, 0x7745AE04, 0xD736FCCC, + 0x83426B33, 0xF01EAB71, 0xB0804187, 0x3C005E5F, + 0x77A057BE, 0xBDE8AE24, 0x55464299, 0xBF582E61, + 0x4E58F48F, 0xF2DDFDA2, 0xF474EF38, 0x8789BDC2, + 0x5366F9C3, 0xC8B38E74, 0xB475F255, 0x46FCD9B9, + 0x7AEB2661, 0x8B1DDF84, 0x846A0E79, 0x915F95E2, + 0x466E598E, 0x20B45770, 0x8CD55591, 0xC902DE4C, + 0xB90BACE1, 0xBB8205D0, 0x11A86248, 0x7574A99E, + 0xB77F19B6, 0xE0A9DC09, 0x662D09A1, 0xC4324633, + 0xE85A1F02, 0x09F0BE8C, 0x4A99A025, 0x1D6EFE10, + 0x1AB93D1D, 0x0BA5A4DF, 0xA186F20F, 0x2868F169, + 0xDCB7DA83, 0x573906FE, 0xA1E2CE9B, 0x4FCD7F52, + 0x50115E01, 0xA70683FA, 0xA002B5C4, 0x0DE6D027, + 0x9AF88C27, 0x773F8641, 0xC3604C06, 0x61A806B5, + 0xF0177A28, 0xC0F586E0, 0x006058AA, 0x30DC7D62, + 0x11E69ED7, 0x2338EA63, 0x53C2DD94, 0xC2C21634, + 0xBBCBEE56, 0x90BCB6DE, 0xEBFC7DA1, 0xCE591D76, + 0x6F05E409, 0x4B7C0188, 0x39720A3D, 0x7C927C24, + 0x86E3725F, 0x724D9DB9, 0x1AC15BB4, 0xD39EB8FC, + 0xED545578, 0x08FCA5B5, 0xD83D7CD3, 0x4DAD0FC4, + 0x1E50EF5E, 0xB161E6F8, 0xA28514D9, 0x6C51133C, + 0x6FD5C7E7, 0x56E14EC4, 0x362ABFCE, 0xDDC6C837, + 0xD79A3234, 0x92638212, 0x670EFA8E, 0x406000E0 ], + [ 0x3A39CE37, 0xD3FAF5CF, 0xABC27737, 0x5AC52D1B, + 0x5CB0679E, 0x4FA33742, 0xD3822740, 0x99BC9BBE, + 0xD5118E9D, 0xBF0F7315, 0xD62D1C7E, 0xC700C47B, + 0xB78C1B6B, 0x21A19045, 0xB26EB1BE, 0x6A366EB4, + 0x5748AB2F, 0xBC946E79, 0xC6A376D2, 0x6549C2C8, + 0x530FF8EE, 0x468DDE7D, 0xD5730A1D, 0x4CD04DC6, + 0x2939BBDB, 0xA9BA4650, 0xAC9526E8, 0xBE5EE304, + 0xA1FAD5F0, 0x6A2D519A, 0x63EF8CE2, 0x9A86EE22, + 0xC089C2B8, 0x43242EF6, 0xA51E03AA, 0x9CF2D0A4, + 0x83C061BA, 0x9BE96A4D, 0x8FE51550, 0xBA645BD6, + 0x2826A2F9, 0xA73A3AE1, 0x4BA99586, 0xEF5562E9, + 0xC72FEFD3, 0xF752F7DA, 0x3F046F69, 0x77FA0A59, + 0x80E4A915, 0x87B08601, 0x9B09E6AD, 0x3B3EE593, + 0xE990FD5A, 0x9E34D797, 0x2CF0B7D9, 0x022B8B51, + 0x96D5AC3A, 0x017DA67D, 0xD1CF3ED6, 0x7C7D2D28, + 0x1F9F25CF, 0xADF2B89B, 0x5AD6B472, 0x5A88F54C, + 0xE029AC71, 0xE019A5E6, 0x47B0ACFD, 0xED93FA9B, + 0xE8D3C48D, 0x283B57CC, 0xF8D56629, 0x79132E28, + 0x785F0191, 0xED756055, 0xF7960E44, 0xE3D35E8C, + 0x15056DD4, 0x88F46DBA, 0x03A16125, 0x0564F0BD, + 0xC3EB9E15, 0x3C9057A2, 0x97271AEC, 0xA93A072A, + 0x1B3F6D9B, 0x1E6321F5, 0xF59C66FB, 0x26DCF319, + 0x7533D928, 0xB155FDF5, 0x03563482, 0x8ABA3CBB, + 0x28517711, 0xC20AD9F8, 0xABCC5167, 0xCCAD925F, + 0x4DE81751, 0x3830DC8E, 0x379D5862, 0x9320F991, + 0xEA7A90C2, 0xFB3E7BCE, 0x5121CE64, 0x774FBE32, + 0xA8B6E37E, 0xC3293D46, 0x48DE5369, 0x6413E680, + 0xA2AE0810, 0xDD6DB224, 0x69852DFD, 0x09072166, + 0xB39A460A, 0x6445C0DD, 0x586CDECF, 0x1C20C8AE, + 0x5BBEF7DD, 0x1B588D40, 0xCCD2017F, 0x6BB4E3BB, + 0xDDA26A7E, 0x3A59FF45, 0x3E350A44, 0xBCB4CDD5, + 0x72EACEA8, 0xFA6484BB, 0x8D6612AE, 0xBF3C6F47, + 0xD29BE463, 0x542F5D9E, 0xAEC2771B, 0xF64E6370, + 0x740E0D8D, 0xE75B1357, 0xF8721671, 0xAF537D5D, + 0x4040CB08, 0x4EB4E2CC, 0x34D2466A, 0x0115AF84, + 0xE1B00428, 0x95983A1D, 0x06B89FB4, 0xCE6EA048, + 0x6F3F3B82, 0x3520AB82, 0x011A1D4B, 0x277227F8, + 0x611560B1, 0xE7933FDC, 0xBB3A792B, 0x344525BD, + 0xA08839E1, 0x51CE794B, 0x2F32C9B7, 0xA01FBAC9, + 0xE01CC87E, 0xBCC7D1F6, 0xCF0111C3, 0xA1E8AAC7, + 0x1A908749, 0xD44FBD9A, 0xD0DADECB, 0xD50ADA38, + 0x0339C32A, 0xC6913667, 0x8DF9317C, 0xE0B12B4F, + 0xF79E59B7, 0x43F5BB3A, 0xF2D519FF, 0x27D9459C, + 0xBF97222C, 0x15E6FC2A, 0x0F91FC71, 0x9B941525, + 0xFAE59361, 0xCEB69CEB, 0xC2A86459, 0x12BAA8D1, + 0xB6C1075E, 0xE3056A0C, 0x10D25065, 0xCB03A442, + 0xE0EC6E0E, 0x1698DB3B, 0x4C98A0BE, 0x3278E964, + 0x9F1F9532, 0xE0D392DF, 0xD3A0342B, 0x8971F21E, + 0x1B0A7441, 0x4BA3348C, 0xC5BE7120, 0xC37632D8, + 0xDF359F8D, 0x9B992F2E, 0xE60B6F47, 0x0FE3F11D, + 0xE54CDA54, 0x1EDAD891, 0xCE6279CF, 0xCD3E7E6F, + 0x1618B166, 0xFD2C1D05, 0x848FD2C5, 0xF6FB2299, + 0xF523F357, 0xA6327623, 0x93A83531, 0x56CCCD02, + 0xACF08162, 0x5A75EBB5, 0x6E163697, 0x88D273CC, + 0xDE966292, 0x81B949D0, 0x4C50901B, 0x71C65614, + 0xE6C6C7BD, 0x327A140A, 0x45E1D006, 0xC3F27B9A, + 0xC9AA53FD, 0x62A80F00, 0xBB25BFE2, 0x35BDD2F6, + 0x71126905, 0xB2040222, 0xB6CBCF7C, 0xCD769C2B, + 0x53113EC0, 0x1640E3D3, 0x38ABBD60, 0x2547ADF0, + 0xBA38209C, 0xF746CE76, 0x77AFA1C5, 0x20756060, + 0x85CBFE4E, 0x8AE88DD8, 0x7AAAF9B0, 0x4CF9AA7E, + 0x1948C25C, 0x02FB8A8C, 0x01C36AE4, 0xD6EBE1F9, + 0x90D4F869, 0xA65CDEA0, 0x3F09252D, 0xC208E69F, + 0xB74E6132, 0xCE77E25B, 0x578FDFE3, 0x3AC372E6 ] + ]; + + var BLOWFISH_CTX = { + pbox: [], + sbox: [] + } + + function F(ctx, x){ + let a = (x >> 24) & 0xFF; + let b = (x >> 16) & 0xFF; + let c = (x >> 8) & 0xFF; + let d = x & 0xFF; + + let y = ctx.sbox[0][a] + ctx.sbox[1][b]; + y = y ^ ctx.sbox[2][c]; + y = y + ctx.sbox[3][d]; + + return y; + } + + function BlowFish_Encrypt(ctx, left, right){ + let Xl = left; + let Xr = right; + let temp; + + for(let i = 0; i < N; ++i){ + Xl = Xl ^ ctx.pbox[i]; + Xr = F(ctx, Xl) ^ Xr; + + temp = Xl; + Xl = Xr; + Xr = temp; + } + + temp = Xl; + Xl = Xr; + Xr = temp; + + Xr = Xr ^ ctx.pbox[N]; + Xl = Xl ^ ctx.pbox[N + 1]; + + return {left: Xl, right: Xr}; + } + + function BlowFish_Decrypt(ctx, left, right){ + let Xl = left; + let Xr = right; + let temp; + + for(let i = N + 1; i > 1; --i){ + Xl = Xl ^ ctx.pbox[i]; + Xr = F(ctx, Xl) ^ Xr; + + temp = Xl; + Xl = Xr; + Xr = temp; + } + + temp = Xl; + Xl = Xr; + Xr = temp; + + Xr = Xr ^ ctx.pbox[1]; + Xl = Xl ^ ctx.pbox[0]; + + return {left: Xl, right: Xr}; + } + + /** + * Initialization ctx's pbox and sbox. + * + * @param {Object} ctx The object has pbox and sbox. + * @param {Array} key An array of 32-bit words. + * @param {int} keysize The length of the key. + * + * @example + * + * BlowFishInit(BLOWFISH_CTX, key, 128/32); + */ + function BlowFishInit(ctx, key, keysize) + { + for(let Row = 0; Row < 4; Row++) + { + ctx.sbox[Row] = []; + for(let Col = 0; Col < 256; Col++) + { + ctx.sbox[Row][Col] = ORIG_S[Row][Col]; + } + } + + let keyIndex = 0; + for(let index = 0; index < N + 2; index++) + { + ctx.pbox[index] = ORIG_P[index] ^ key[keyIndex]; + keyIndex++; + if(keyIndex >= keysize) + { + keyIndex = 0; + } + } + + let Data1 = 0; + let Data2 = 0; + let res = 0; + for(let i = 0; i < N + 2; i += 2) + { + res = BlowFish_Encrypt(ctx, Data1, Data2); + Data1 = res.left; + Data2 = res.right; + ctx.pbox[i] = Data1; + ctx.pbox[i + 1] = Data2; + } + + for(let i = 0; i < 4; i++) + { + for(let j = 0; j < 256; j += 2) + { + res = BlowFish_Encrypt(ctx, Data1, Data2); + Data1 = res.left; + Data2 = res.right; + ctx.sbox[i][j] = Data1; + ctx.sbox[i][j + 1] = Data2; + } + } + + return true; + } + + /** + * Blowfish block cipher algorithm. + */ + var Blowfish = C_algo.Blowfish = BlockCipher.extend({ + _doReset: function () { + // Skip reset of nRounds has been set before and key did not change + if (this._keyPriorReset === this._key) { + return; + } + + // Shortcuts + var key = this._keyPriorReset = this._key; + var keyWords = key.words; + var keySize = key.sigBytes / 4; + + //Initialization pbox and sbox + BlowFishInit(BLOWFISH_CTX, keyWords, keySize); + }, + + encryptBlock: function (M, offset) { + var res = BlowFish_Encrypt(BLOWFISH_CTX, M[offset], M[offset + 1]); + M[offset] = res.left; + M[offset + 1] = res.right; + }, + + decryptBlock: function (M, offset) { + var res = BlowFish_Decrypt(BLOWFISH_CTX, M[offset], M[offset + 1]); + M[offset] = res.left; + M[offset + 1] = res.right; + }, + + blockSize: 64/32, + + keySize: 128/32, + + ivSize: 64/32 + }); + + /** + * Shortcut functions to the cipher's object interface. + * + * @example + * + * var ciphertext = CryptoJS.Blowfish.encrypt(message, key, cfg); + * var plaintext = CryptoJS.Blowfish.decrypt(ciphertext, key, cfg); + */ + C.Blowfish = BlockCipher._createHelper(Blowfish); + }()); + + + return CryptoJS.Blowfish; + +})); \ No newline at end of file diff --git a/node_modules/crypto-js/bower.json b/node_modules/crypto-js/bower.json new file mode 100644 index 0000000..4dee617 --- /dev/null +++ b/node_modules/crypto-js/bower.json @@ -0,0 +1,39 @@ +{ + "name": "crypto-js", + "version": "4.2.0", + "description": "JavaScript library of crypto standards.", + "license": "MIT", + "homepage": "http://github.com/brix/crypto-js", + "repository": { + "type": "git", + "url": "http://github.com/brix/crypto-js.git" + }, + "keywords": [ + "security", + "crypto", + "Hash", + "MD5", + "SHA1", + "SHA-1", + "SHA256", + "SHA-256", + "RC4", + "Rabbit", + "AES", + "DES", + "PBKDF2", + "HMAC", + "OFB", + "CFB", + "CTR", + "CBC", + "Base64", + "Base64url" + ], + "main": "index.js", + "dependencies": {}, + "browser": { + "crypto": false + }, + "ignore": [] +} diff --git a/node_modules/crypto-js/cipher-core.js b/node_modules/crypto-js/cipher-core.js new file mode 100644 index 0000000..903f462 --- /dev/null +++ b/node_modules/crypto-js/cipher-core.js @@ -0,0 +1,895 @@ +;(function (root, factory, undef) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require("./core"), require("./evpkdf")); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core", "./evpkdf"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + /** + * Cipher core components. + */ + CryptoJS.lib.Cipher || (function (undefined) { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var Base = C_lib.Base; + var WordArray = C_lib.WordArray; + var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm; + var C_enc = C.enc; + var Utf8 = C_enc.Utf8; + var Base64 = C_enc.Base64; + var C_algo = C.algo; + var EvpKDF = C_algo.EvpKDF; + + /** + * Abstract base cipher template. + * + * @property {number} keySize This cipher's key size. Default: 4 (128 bits) + * @property {number} ivSize This cipher's IV size. Default: 4 (128 bits) + * @property {number} _ENC_XFORM_MODE A constant representing encryption mode. + * @property {number} _DEC_XFORM_MODE A constant representing decryption mode. + */ + var Cipher = C_lib.Cipher = BufferedBlockAlgorithm.extend({ + /** + * Configuration options. + * + * @property {WordArray} iv The IV to use for this operation. + */ + cfg: Base.extend(), + + /** + * Creates this cipher in encryption mode. + * + * @param {WordArray} key The key. + * @param {Object} cfg (Optional) The configuration options to use for this operation. + * + * @return {Cipher} A cipher instance. + * + * @static + * + * @example + * + * var cipher = CryptoJS.algo.AES.createEncryptor(keyWordArray, { iv: ivWordArray }); + */ + createEncryptor: function (key, cfg) { + return this.create(this._ENC_XFORM_MODE, key, cfg); + }, + + /** + * Creates this cipher in decryption mode. + * + * @param {WordArray} key The key. + * @param {Object} cfg (Optional) The configuration options to use for this operation. + * + * @return {Cipher} A cipher instance. + * + * @static + * + * @example + * + * var cipher = CryptoJS.algo.AES.createDecryptor(keyWordArray, { iv: ivWordArray }); + */ + createDecryptor: function (key, cfg) { + return this.create(this._DEC_XFORM_MODE, key, cfg); + }, + + /** + * Initializes a newly created cipher. + * + * @param {number} xformMode Either the encryption or decryption transormation mode constant. + * @param {WordArray} key The key. + * @param {Object} cfg (Optional) The configuration options to use for this operation. + * + * @example + * + * var cipher = CryptoJS.algo.AES.create(CryptoJS.algo.AES._ENC_XFORM_MODE, keyWordArray, { iv: ivWordArray }); + */ + init: function (xformMode, key, cfg) { + // Apply config defaults + this.cfg = this.cfg.extend(cfg); + + // Store transform mode and key + this._xformMode = xformMode; + this._key = key; + + // Set initial values + this.reset(); + }, + + /** + * Resets this cipher to its initial state. + * + * @example + * + * cipher.reset(); + */ + reset: function () { + // Reset data buffer + BufferedBlockAlgorithm.reset.call(this); + + // Perform concrete-cipher logic + this._doReset(); + }, + + /** + * Adds data to be encrypted or decrypted. + * + * @param {WordArray|string} dataUpdate The data to encrypt or decrypt. + * + * @return {WordArray} The data after processing. + * + * @example + * + * var encrypted = cipher.process('data'); + * var encrypted = cipher.process(wordArray); + */ + process: function (dataUpdate) { + // Append + this._append(dataUpdate); + + // Process available blocks + return this._process(); + }, + + /** + * Finalizes the encryption or decryption process. + * Note that the finalize operation is effectively a destructive, read-once operation. + * + * @param {WordArray|string} dataUpdate The final data to encrypt or decrypt. + * + * @return {WordArray} The data after final processing. + * + * @example + * + * var encrypted = cipher.finalize(); + * var encrypted = cipher.finalize('data'); + * var encrypted = cipher.finalize(wordArray); + */ + finalize: function (dataUpdate) { + // Final data update + if (dataUpdate) { + this._append(dataUpdate); + } + + // Perform concrete-cipher logic + var finalProcessedData = this._doFinalize(); + + return finalProcessedData; + }, + + keySize: 128/32, + + ivSize: 128/32, + + _ENC_XFORM_MODE: 1, + + _DEC_XFORM_MODE: 2, + + /** + * Creates shortcut functions to a cipher's object interface. + * + * @param {Cipher} cipher The cipher to create a helper for. + * + * @return {Object} An object with encrypt and decrypt shortcut functions. + * + * @static + * + * @example + * + * var AES = CryptoJS.lib.Cipher._createHelper(CryptoJS.algo.AES); + */ + _createHelper: (function () { + function selectCipherStrategy(key) { + if (typeof key == 'string') { + return PasswordBasedCipher; + } else { + return SerializableCipher; + } + } + + return function (cipher) { + return { + encrypt: function (message, key, cfg) { + return selectCipherStrategy(key).encrypt(cipher, message, key, cfg); + }, + + decrypt: function (ciphertext, key, cfg) { + return selectCipherStrategy(key).decrypt(cipher, ciphertext, key, cfg); + } + }; + }; + }()) + }); + + /** + * Abstract base stream cipher template. + * + * @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 1 (32 bits) + */ + var StreamCipher = C_lib.StreamCipher = Cipher.extend({ + _doFinalize: function () { + // Process partial blocks + var finalProcessedBlocks = this._process(!!'flush'); + + return finalProcessedBlocks; + }, + + blockSize: 1 + }); + + /** + * Mode namespace. + */ + var C_mode = C.mode = {}; + + /** + * Abstract base block cipher mode template. + */ + var BlockCipherMode = C_lib.BlockCipherMode = Base.extend({ + /** + * Creates this mode for encryption. + * + * @param {Cipher} cipher A block cipher instance. + * @param {Array} iv The IV words. + * + * @static + * + * @example + * + * var mode = CryptoJS.mode.CBC.createEncryptor(cipher, iv.words); + */ + createEncryptor: function (cipher, iv) { + return this.Encryptor.create(cipher, iv); + }, + + /** + * Creates this mode for decryption. + * + * @param {Cipher} cipher A block cipher instance. + * @param {Array} iv The IV words. + * + * @static + * + * @example + * + * var mode = CryptoJS.mode.CBC.createDecryptor(cipher, iv.words); + */ + createDecryptor: function (cipher, iv) { + return this.Decryptor.create(cipher, iv); + }, + + /** + * Initializes a newly created mode. + * + * @param {Cipher} cipher A block cipher instance. + * @param {Array} iv The IV words. + * + * @example + * + * var mode = CryptoJS.mode.CBC.Encryptor.create(cipher, iv.words); + */ + init: function (cipher, iv) { + this._cipher = cipher; + this._iv = iv; + } + }); + + /** + * Cipher Block Chaining mode. + */ + var CBC = C_mode.CBC = (function () { + /** + * Abstract base CBC mode. + */ + var CBC = BlockCipherMode.extend(); + + /** + * CBC encryptor. + */ + CBC.Encryptor = CBC.extend({ + /** + * Processes the data block at offset. + * + * @param {Array} words The data words to operate on. + * @param {number} offset The offset where the block starts. + * + * @example + * + * mode.processBlock(data.words, offset); + */ + processBlock: function (words, offset) { + // Shortcuts + var cipher = this._cipher; + var blockSize = cipher.blockSize; + + // XOR and encrypt + xorBlock.call(this, words, offset, blockSize); + cipher.encryptBlock(words, offset); + + // Remember this block to use with next block + this._prevBlock = words.slice(offset, offset + blockSize); + } + }); + + /** + * CBC decryptor. + */ + CBC.Decryptor = CBC.extend({ + /** + * Processes the data block at offset. + * + * @param {Array} words The data words to operate on. + * @param {number} offset The offset where the block starts. + * + * @example + * + * mode.processBlock(data.words, offset); + */ + processBlock: function (words, offset) { + // Shortcuts + var cipher = this._cipher; + var blockSize = cipher.blockSize; + + // Remember this block to use with next block + var thisBlock = words.slice(offset, offset + blockSize); + + // Decrypt and XOR + cipher.decryptBlock(words, offset); + xorBlock.call(this, words, offset, blockSize); + + // This block becomes the previous block + this._prevBlock = thisBlock; + } + }); + + function xorBlock(words, offset, blockSize) { + var block; + + // Shortcut + var iv = this._iv; + + // Choose mixing block + if (iv) { + block = iv; + + // Remove IV for subsequent blocks + this._iv = undefined; + } else { + block = this._prevBlock; + } + + // XOR blocks + for (var i = 0; i < blockSize; i++) { + words[offset + i] ^= block[i]; + } + } + + return CBC; + }()); + + /** + * Padding namespace. + */ + var C_pad = C.pad = {}; + + /** + * PKCS #5/7 padding strategy. + */ + var Pkcs7 = C_pad.Pkcs7 = { + /** + * Pads data using the algorithm defined in PKCS #5/7. + * + * @param {WordArray} data The data to pad. + * @param {number} blockSize The multiple that the data should be padded to. + * + * @static + * + * @example + * + * CryptoJS.pad.Pkcs7.pad(wordArray, 4); + */ + pad: function (data, blockSize) { + // Shortcut + var blockSizeBytes = blockSize * 4; + + // Count padding bytes + var nPaddingBytes = blockSizeBytes - data.sigBytes % blockSizeBytes; + + // Create padding word + var paddingWord = (nPaddingBytes << 24) | (nPaddingBytes << 16) | (nPaddingBytes << 8) | nPaddingBytes; + + // Create padding + var paddingWords = []; + for (var i = 0; i < nPaddingBytes; i += 4) { + paddingWords.push(paddingWord); + } + var padding = WordArray.create(paddingWords, nPaddingBytes); + + // Add padding + data.concat(padding); + }, + + /** + * Unpads data that had been padded using the algorithm defined in PKCS #5/7. + * + * @param {WordArray} data The data to unpad. + * + * @static + * + * @example + * + * CryptoJS.pad.Pkcs7.unpad(wordArray); + */ + unpad: function (data) { + // Get number of padding bytes from last byte + var nPaddingBytes = data.words[(data.sigBytes - 1) >>> 2] & 0xff; + + // Remove padding + data.sigBytes -= nPaddingBytes; + } + }; + + /** + * Abstract base block cipher template. + * + * @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 4 (128 bits) + */ + var BlockCipher = C_lib.BlockCipher = Cipher.extend({ + /** + * Configuration options. + * + * @property {Mode} mode The block mode to use. Default: CBC + * @property {Padding} padding The padding strategy to use. Default: Pkcs7 + */ + cfg: Cipher.cfg.extend({ + mode: CBC, + padding: Pkcs7 + }), + + reset: function () { + var modeCreator; + + // Reset cipher + Cipher.reset.call(this); + + // Shortcuts + var cfg = this.cfg; + var iv = cfg.iv; + var mode = cfg.mode; + + // Reset block mode + if (this._xformMode == this._ENC_XFORM_MODE) { + modeCreator = mode.createEncryptor; + } else /* if (this._xformMode == this._DEC_XFORM_MODE) */ { + modeCreator = mode.createDecryptor; + // Keep at least one block in the buffer for unpadding + this._minBufferSize = 1; + } + + if (this._mode && this._mode.__creator == modeCreator) { + this._mode.init(this, iv && iv.words); + } else { + this._mode = modeCreator.call(mode, this, iv && iv.words); + this._mode.__creator = modeCreator; + } + }, + + _doProcessBlock: function (words, offset) { + this._mode.processBlock(words, offset); + }, + + _doFinalize: function () { + var finalProcessedBlocks; + + // Shortcut + var padding = this.cfg.padding; + + // Finalize + if (this._xformMode == this._ENC_XFORM_MODE) { + // Pad data + padding.pad(this._data, this.blockSize); + + // Process final blocks + finalProcessedBlocks = this._process(!!'flush'); + } else /* if (this._xformMode == this._DEC_XFORM_MODE) */ { + // Process final blocks + finalProcessedBlocks = this._process(!!'flush'); + + // Unpad data + padding.unpad(finalProcessedBlocks); + } + + return finalProcessedBlocks; + }, + + blockSize: 128/32 + }); + + /** + * A collection of cipher parameters. + * + * @property {WordArray} ciphertext The raw ciphertext. + * @property {WordArray} key The key to this ciphertext. + * @property {WordArray} iv The IV used in the ciphering operation. + * @property {WordArray} salt The salt used with a key derivation function. + * @property {Cipher} algorithm The cipher algorithm. + * @property {Mode} mode The block mode used in the ciphering operation. + * @property {Padding} padding The padding scheme used in the ciphering operation. + * @property {number} blockSize The block size of the cipher. + * @property {Format} formatter The default formatting strategy to convert this cipher params object to a string. + */ + var CipherParams = C_lib.CipherParams = Base.extend({ + /** + * Initializes a newly created cipher params object. + * + * @param {Object} cipherParams An object with any of the possible cipher parameters. + * + * @example + * + * var cipherParams = CryptoJS.lib.CipherParams.create({ + * ciphertext: ciphertextWordArray, + * key: keyWordArray, + * iv: ivWordArray, + * salt: saltWordArray, + * algorithm: CryptoJS.algo.AES, + * mode: CryptoJS.mode.CBC, + * padding: CryptoJS.pad.PKCS7, + * blockSize: 4, + * formatter: CryptoJS.format.OpenSSL + * }); + */ + init: function (cipherParams) { + this.mixIn(cipherParams); + }, + + /** + * Converts this cipher params object to a string. + * + * @param {Format} formatter (Optional) The formatting strategy to use. + * + * @return {string} The stringified cipher params. + * + * @throws Error If neither the formatter nor the default formatter is set. + * + * @example + * + * var string = cipherParams + ''; + * var string = cipherParams.toString(); + * var string = cipherParams.toString(CryptoJS.format.OpenSSL); + */ + toString: function (formatter) { + return (formatter || this.formatter).stringify(this); + } + }); + + /** + * Format namespace. + */ + var C_format = C.format = {}; + + /** + * OpenSSL formatting strategy. + */ + var OpenSSLFormatter = C_format.OpenSSL = { + /** + * Converts a cipher params object to an OpenSSL-compatible string. + * + * @param {CipherParams} cipherParams The cipher params object. + * + * @return {string} The OpenSSL-compatible string. + * + * @static + * + * @example + * + * var openSSLString = CryptoJS.format.OpenSSL.stringify(cipherParams); + */ + stringify: function (cipherParams) { + var wordArray; + + // Shortcuts + var ciphertext = cipherParams.ciphertext; + var salt = cipherParams.salt; + + // Format + if (salt) { + wordArray = WordArray.create([0x53616c74, 0x65645f5f]).concat(salt).concat(ciphertext); + } else { + wordArray = ciphertext; + } + + return wordArray.toString(Base64); + }, + + /** + * Converts an OpenSSL-compatible string to a cipher params object. + * + * @param {string} openSSLStr The OpenSSL-compatible string. + * + * @return {CipherParams} The cipher params object. + * + * @static + * + * @example + * + * var cipherParams = CryptoJS.format.OpenSSL.parse(openSSLString); + */ + parse: function (openSSLStr) { + var salt; + + // Parse base64 + var ciphertext = Base64.parse(openSSLStr); + + // Shortcut + var ciphertextWords = ciphertext.words; + + // Test for salt + if (ciphertextWords[0] == 0x53616c74 && ciphertextWords[1] == 0x65645f5f) { + // Extract salt + salt = WordArray.create(ciphertextWords.slice(2, 4)); + + // Remove salt from ciphertext + ciphertextWords.splice(0, 4); + ciphertext.sigBytes -= 16; + } + + return CipherParams.create({ ciphertext: ciphertext, salt: salt }); + } + }; + + /** + * A cipher wrapper that returns ciphertext as a serializable cipher params object. + */ + var SerializableCipher = C_lib.SerializableCipher = Base.extend({ + /** + * Configuration options. + * + * @property {Formatter} format The formatting strategy to convert cipher param objects to and from a string. Default: OpenSSL + */ + cfg: Base.extend({ + format: OpenSSLFormatter + }), + + /** + * Encrypts a message. + * + * @param {Cipher} cipher The cipher algorithm to use. + * @param {WordArray|string} message The message to encrypt. + * @param {WordArray} key The key. + * @param {Object} cfg (Optional) The configuration options to use for this operation. + * + * @return {CipherParams} A cipher params object. + * + * @static + * + * @example + * + * var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key); + * var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv }); + * var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv, format: CryptoJS.format.OpenSSL }); + */ + encrypt: function (cipher, message, key, cfg) { + // Apply config defaults + cfg = this.cfg.extend(cfg); + + // Encrypt + var encryptor = cipher.createEncryptor(key, cfg); + var ciphertext = encryptor.finalize(message); + + // Shortcut + var cipherCfg = encryptor.cfg; + + // Create and return serializable cipher params + return CipherParams.create({ + ciphertext: ciphertext, + key: key, + iv: cipherCfg.iv, + algorithm: cipher, + mode: cipherCfg.mode, + padding: cipherCfg.padding, + blockSize: cipher.blockSize, + formatter: cfg.format + }); + }, + + /** + * Decrypts serialized ciphertext. + * + * @param {Cipher} cipher The cipher algorithm to use. + * @param {CipherParams|string} ciphertext The ciphertext to decrypt. + * @param {WordArray} key The key. + * @param {Object} cfg (Optional) The configuration options to use for this operation. + * + * @return {WordArray} The plaintext. + * + * @static + * + * @example + * + * var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, key, { iv: iv, format: CryptoJS.format.OpenSSL }); + * var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, key, { iv: iv, format: CryptoJS.format.OpenSSL }); + */ + decrypt: function (cipher, ciphertext, key, cfg) { + // Apply config defaults + cfg = this.cfg.extend(cfg); + + // Convert string to CipherParams + ciphertext = this._parse(ciphertext, cfg.format); + + // Decrypt + var plaintext = cipher.createDecryptor(key, cfg).finalize(ciphertext.ciphertext); + + return plaintext; + }, + + /** + * Converts serialized ciphertext to CipherParams, + * else assumed CipherParams already and returns ciphertext unchanged. + * + * @param {CipherParams|string} ciphertext The ciphertext. + * @param {Formatter} format The formatting strategy to use to parse serialized ciphertext. + * + * @return {CipherParams} The unserialized ciphertext. + * + * @static + * + * @example + * + * var ciphertextParams = CryptoJS.lib.SerializableCipher._parse(ciphertextStringOrParams, format); + */ + _parse: function (ciphertext, format) { + if (typeof ciphertext == 'string') { + return format.parse(ciphertext, this); + } else { + return ciphertext; + } + } + }); + + /** + * Key derivation function namespace. + */ + var C_kdf = C.kdf = {}; + + /** + * OpenSSL key derivation function. + */ + var OpenSSLKdf = C_kdf.OpenSSL = { + /** + * Derives a key and IV from a password. + * + * @param {string} password The password to derive from. + * @param {number} keySize The size in words of the key to generate. + * @param {number} ivSize The size in words of the IV to generate. + * @param {WordArray|string} salt (Optional) A 64-bit salt to use. If omitted, a salt will be generated randomly. + * + * @return {CipherParams} A cipher params object with the key, IV, and salt. + * + * @static + * + * @example + * + * var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32); + * var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32, 'saltsalt'); + */ + execute: function (password, keySize, ivSize, salt, hasher) { + // Generate random salt + if (!salt) { + salt = WordArray.random(64/8); + } + + // Derive key and IV + if (!hasher) { + var key = EvpKDF.create({ keySize: keySize + ivSize }).compute(password, salt); + } else { + var key = EvpKDF.create({ keySize: keySize + ivSize, hasher: hasher }).compute(password, salt); + } + + + // Separate key and IV + var iv = WordArray.create(key.words.slice(keySize), ivSize * 4); + key.sigBytes = keySize * 4; + + // Return params + return CipherParams.create({ key: key, iv: iv, salt: salt }); + } + }; + + /** + * A serializable cipher wrapper that derives the key from a password, + * and returns ciphertext as a serializable cipher params object. + */ + var PasswordBasedCipher = C_lib.PasswordBasedCipher = SerializableCipher.extend({ + /** + * Configuration options. + * + * @property {KDF} kdf The key derivation function to use to generate a key and IV from a password. Default: OpenSSL + */ + cfg: SerializableCipher.cfg.extend({ + kdf: OpenSSLKdf + }), + + /** + * Encrypts a message using a password. + * + * @param {Cipher} cipher The cipher algorithm to use. + * @param {WordArray|string} message The message to encrypt. + * @param {string} password The password. + * @param {Object} cfg (Optional) The configuration options to use for this operation. + * + * @return {CipherParams} A cipher params object. + * + * @static + * + * @example + * + * var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password'); + * var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password', { format: CryptoJS.format.OpenSSL }); + */ + encrypt: function (cipher, message, password, cfg) { + // Apply config defaults + cfg = this.cfg.extend(cfg); + + // Derive key and other params + var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize, cfg.salt, cfg.hasher); + + // Add IV to config + cfg.iv = derivedParams.iv; + + // Encrypt + var ciphertext = SerializableCipher.encrypt.call(this, cipher, message, derivedParams.key, cfg); + + // Mix in derived params + ciphertext.mixIn(derivedParams); + + return ciphertext; + }, + + /** + * Decrypts serialized ciphertext using a password. + * + * @param {Cipher} cipher The cipher algorithm to use. + * @param {CipherParams|string} ciphertext The ciphertext to decrypt. + * @param {string} password The password. + * @param {Object} cfg (Optional) The configuration options to use for this operation. + * + * @return {WordArray} The plaintext. + * + * @static + * + * @example + * + * var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, 'password', { format: CryptoJS.format.OpenSSL }); + * var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, 'password', { format: CryptoJS.format.OpenSSL }); + */ + decrypt: function (cipher, ciphertext, password, cfg) { + // Apply config defaults + cfg = this.cfg.extend(cfg); + + // Convert string to CipherParams + ciphertext = this._parse(ciphertext, cfg.format); + + // Derive key and other params + var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize, ciphertext.salt, cfg.hasher); + + // Add IV to config + cfg.iv = derivedParams.iv; + + // Decrypt + var plaintext = SerializableCipher.decrypt.call(this, cipher, ciphertext, derivedParams.key, cfg); + + return plaintext; + } + }); + }()); + + +})); \ No newline at end of file diff --git a/node_modules/crypto-js/core.js b/node_modules/crypto-js/core.js new file mode 100644 index 0000000..e3a498b --- /dev/null +++ b/node_modules/crypto-js/core.js @@ -0,0 +1,807 @@ +;(function (root, factory) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(); + } + else if (typeof define === "function" && define.amd) { + // AMD + define([], factory); + } + else { + // Global (browser) + root.CryptoJS = factory(); + } +}(this, function () { + + /*globals window, global, require*/ + + /** + * CryptoJS core components. + */ + var CryptoJS = CryptoJS || (function (Math, undefined) { + + var crypto; + + // Native crypto from window (Browser) + if (typeof window !== 'undefined' && window.crypto) { + crypto = window.crypto; + } + + // Native crypto in web worker (Browser) + if (typeof self !== 'undefined' && self.crypto) { + crypto = self.crypto; + } + + // Native crypto from worker + if (typeof globalThis !== 'undefined' && globalThis.crypto) { + crypto = globalThis.crypto; + } + + // Native (experimental IE 11) crypto from window (Browser) + if (!crypto && typeof window !== 'undefined' && window.msCrypto) { + crypto = window.msCrypto; + } + + // Native crypto from global (NodeJS) + if (!crypto && typeof global !== 'undefined' && global.crypto) { + crypto = global.crypto; + } + + // Native crypto import via require (NodeJS) + if (!crypto && typeof require === 'function') { + try { + crypto = require('crypto'); + } catch (err) {} + } + + /* + * Cryptographically secure pseudorandom number generator + * + * As Math.random() is cryptographically not safe to use + */ + var cryptoSecureRandomInt = function () { + if (crypto) { + // Use getRandomValues method (Browser) + if (typeof crypto.getRandomValues === 'function') { + try { + return crypto.getRandomValues(new Uint32Array(1))[0]; + } catch (err) {} + } + + // Use randomBytes method (NodeJS) + if (typeof crypto.randomBytes === 'function') { + try { + return crypto.randomBytes(4).readInt32LE(); + } catch (err) {} + } + } + + throw new Error('Native crypto module could not be used to get secure random number.'); + }; + + /* + * Local polyfill of Object.create + + */ + var create = Object.create || (function () { + function F() {} + + return function (obj) { + var subtype; + + F.prototype = obj; + + subtype = new F(); + + F.prototype = null; + + return subtype; + }; + }()); + + /** + * CryptoJS namespace. + */ + var C = {}; + + /** + * Library namespace. + */ + var C_lib = C.lib = {}; + + /** + * Base object for prototypal inheritance. + */ + var Base = C_lib.Base = (function () { + + + return { + /** + * Creates a new object that inherits from this object. + * + * @param {Object} overrides Properties to copy into the new object. + * + * @return {Object} The new object. + * + * @static + * + * @example + * + * var MyType = CryptoJS.lib.Base.extend({ + * field: 'value', + * + * method: function () { + * } + * }); + */ + extend: function (overrides) { + // Spawn + var subtype = create(this); + + // Augment + if (overrides) { + subtype.mixIn(overrides); + } + + // Create default initializer + if (!subtype.hasOwnProperty('init') || this.init === subtype.init) { + subtype.init = function () { + subtype.$super.init.apply(this, arguments); + }; + } + + // Initializer's prototype is the subtype object + subtype.init.prototype = subtype; + + // Reference supertype + subtype.$super = this; + + return subtype; + }, + + /** + * Extends this object and runs the init method. + * Arguments to create() will be passed to init(). + * + * @return {Object} The new object. + * + * @static + * + * @example + * + * var instance = MyType.create(); + */ + create: function () { + var instance = this.extend(); + instance.init.apply(instance, arguments); + + return instance; + }, + + /** + * Initializes a newly created object. + * Override this method to add some logic when your objects are created. + * + * @example + * + * var MyType = CryptoJS.lib.Base.extend({ + * init: function () { + * // ... + * } + * }); + */ + init: function () { + }, + + /** + * Copies properties into this object. + * + * @param {Object} properties The properties to mix in. + * + * @example + * + * MyType.mixIn({ + * field: 'value' + * }); + */ + mixIn: function (properties) { + for (var propertyName in properties) { + if (properties.hasOwnProperty(propertyName)) { + this[propertyName] = properties[propertyName]; + } + } + + // IE won't copy toString using the loop above + if (properties.hasOwnProperty('toString')) { + this.toString = properties.toString; + } + }, + + /** + * Creates a copy of this object. + * + * @return {Object} The clone. + * + * @example + * + * var clone = instance.clone(); + */ + clone: function () { + return this.init.prototype.extend(this); + } + }; + }()); + + /** + * An array of 32-bit words. + * + * @property {Array} words The array of 32-bit words. + * @property {number} sigBytes The number of significant bytes in this word array. + */ + var WordArray = C_lib.WordArray = Base.extend({ + /** + * Initializes a newly created word array. + * + * @param {Array} words (Optional) An array of 32-bit words. + * @param {number} sigBytes (Optional) The number of significant bytes in the words. + * + * @example + * + * var wordArray = CryptoJS.lib.WordArray.create(); + * var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607]); + * var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607], 6); + */ + init: function (words, sigBytes) { + words = this.words = words || []; + + if (sigBytes != undefined) { + this.sigBytes = sigBytes; + } else { + this.sigBytes = words.length * 4; + } + }, + + /** + * Converts this word array to a string. + * + * @param {Encoder} encoder (Optional) The encoding strategy to use. Default: CryptoJS.enc.Hex + * + * @return {string} The stringified word array. + * + * @example + * + * var string = wordArray + ''; + * var string = wordArray.toString(); + * var string = wordArray.toString(CryptoJS.enc.Utf8); + */ + toString: function (encoder) { + return (encoder || Hex).stringify(this); + }, + + /** + * Concatenates a word array to this word array. + * + * @param {WordArray} wordArray The word array to append. + * + * @return {WordArray} This word array. + * + * @example + * + * wordArray1.concat(wordArray2); + */ + concat: function (wordArray) { + // Shortcuts + var thisWords = this.words; + var thatWords = wordArray.words; + var thisSigBytes = this.sigBytes; + var thatSigBytes = wordArray.sigBytes; + + // Clamp excess bits + this.clamp(); + + // Concat + if (thisSigBytes % 4) { + // Copy one byte at a time + for (var i = 0; i < thatSigBytes; i++) { + var thatByte = (thatWords[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; + thisWords[(thisSigBytes + i) >>> 2] |= thatByte << (24 - ((thisSigBytes + i) % 4) * 8); + } + } else { + // Copy one word at a time + for (var j = 0; j < thatSigBytes; j += 4) { + thisWords[(thisSigBytes + j) >>> 2] = thatWords[j >>> 2]; + } + } + this.sigBytes += thatSigBytes; + + // Chainable + return this; + }, + + /** + * Removes insignificant bits. + * + * @example + * + * wordArray.clamp(); + */ + clamp: function () { + // Shortcuts + var words = this.words; + var sigBytes = this.sigBytes; + + // Clamp + words[sigBytes >>> 2] &= 0xffffffff << (32 - (sigBytes % 4) * 8); + words.length = Math.ceil(sigBytes / 4); + }, + + /** + * Creates a copy of this word array. + * + * @return {WordArray} The clone. + * + * @example + * + * var clone = wordArray.clone(); + */ + clone: function () { + var clone = Base.clone.call(this); + clone.words = this.words.slice(0); + + return clone; + }, + + /** + * Creates a word array filled with random bytes. + * + * @param {number} nBytes The number of random bytes to generate. + * + * @return {WordArray} The random word array. + * + * @static + * + * @example + * + * var wordArray = CryptoJS.lib.WordArray.random(16); + */ + random: function (nBytes) { + var words = []; + + for (var i = 0; i < nBytes; i += 4) { + words.push(cryptoSecureRandomInt()); + } + + return new WordArray.init(words, nBytes); + } + }); + + /** + * Encoder namespace. + */ + var C_enc = C.enc = {}; + + /** + * Hex encoding strategy. + */ + var Hex = C_enc.Hex = { + /** + * Converts a word array to a hex string. + * + * @param {WordArray} wordArray The word array. + * + * @return {string} The hex string. + * + * @static + * + * @example + * + * var hexString = CryptoJS.enc.Hex.stringify(wordArray); + */ + stringify: function (wordArray) { + // Shortcuts + var words = wordArray.words; + var sigBytes = wordArray.sigBytes; + + // Convert + var hexChars = []; + for (var i = 0; i < sigBytes; i++) { + var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; + hexChars.push((bite >>> 4).toString(16)); + hexChars.push((bite & 0x0f).toString(16)); + } + + return hexChars.join(''); + }, + + /** + * Converts a hex string to a word array. + * + * @param {string} hexStr The hex string. + * + * @return {WordArray} The word array. + * + * @static + * + * @example + * + * var wordArray = CryptoJS.enc.Hex.parse(hexString); + */ + parse: function (hexStr) { + // Shortcut + var hexStrLength = hexStr.length; + + // Convert + var words = []; + for (var i = 0; i < hexStrLength; i += 2) { + words[i >>> 3] |= parseInt(hexStr.substr(i, 2), 16) << (24 - (i % 8) * 4); + } + + return new WordArray.init(words, hexStrLength / 2); + } + }; + + /** + * Latin1 encoding strategy. + */ + var Latin1 = C_enc.Latin1 = { + /** + * Converts a word array to a Latin1 string. + * + * @param {WordArray} wordArray The word array. + * + * @return {string} The Latin1 string. + * + * @static + * + * @example + * + * var latin1String = CryptoJS.enc.Latin1.stringify(wordArray); + */ + stringify: function (wordArray) { + // Shortcuts + var words = wordArray.words; + var sigBytes = wordArray.sigBytes; + + // Convert + var latin1Chars = []; + for (var i = 0; i < sigBytes; i++) { + var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; + latin1Chars.push(String.fromCharCode(bite)); + } + + return latin1Chars.join(''); + }, + + /** + * Converts a Latin1 string to a word array. + * + * @param {string} latin1Str The Latin1 string. + * + * @return {WordArray} The word array. + * + * @static + * + * @example + * + * var wordArray = CryptoJS.enc.Latin1.parse(latin1String); + */ + parse: function (latin1Str) { + // Shortcut + var latin1StrLength = latin1Str.length; + + // Convert + var words = []; + for (var i = 0; i < latin1StrLength; i++) { + words[i >>> 2] |= (latin1Str.charCodeAt(i) & 0xff) << (24 - (i % 4) * 8); + } + + return new WordArray.init(words, latin1StrLength); + } + }; + + /** + * UTF-8 encoding strategy. + */ + var Utf8 = C_enc.Utf8 = { + /** + * Converts a word array to a UTF-8 string. + * + * @param {WordArray} wordArray The word array. + * + * @return {string} The UTF-8 string. + * + * @static + * + * @example + * + * var utf8String = CryptoJS.enc.Utf8.stringify(wordArray); + */ + stringify: function (wordArray) { + try { + return decodeURIComponent(escape(Latin1.stringify(wordArray))); + } catch (e) { + throw new Error('Malformed UTF-8 data'); + } + }, + + /** + * Converts a UTF-8 string to a word array. + * + * @param {string} utf8Str The UTF-8 string. + * + * @return {WordArray} The word array. + * + * @static + * + * @example + * + * var wordArray = CryptoJS.enc.Utf8.parse(utf8String); + */ + parse: function (utf8Str) { + return Latin1.parse(unescape(encodeURIComponent(utf8Str))); + } + }; + + /** + * Abstract buffered block algorithm template. + * + * The property blockSize must be implemented in a concrete subtype. + * + * @property {number} _minBufferSize The number of blocks that should be kept unprocessed in the buffer. Default: 0 + */ + var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm = Base.extend({ + /** + * Resets this block algorithm's data buffer to its initial state. + * + * @example + * + * bufferedBlockAlgorithm.reset(); + */ + reset: function () { + // Initial values + this._data = new WordArray.init(); + this._nDataBytes = 0; + }, + + /** + * Adds new data to this block algorithm's buffer. + * + * @param {WordArray|string} data The data to append. Strings are converted to a WordArray using UTF-8. + * + * @example + * + * bufferedBlockAlgorithm._append('data'); + * bufferedBlockAlgorithm._append(wordArray); + */ + _append: function (data) { + // Convert string to WordArray, else assume WordArray already + if (typeof data == 'string') { + data = Utf8.parse(data); + } + + // Append + this._data.concat(data); + this._nDataBytes += data.sigBytes; + }, + + /** + * Processes available data blocks. + * + * This method invokes _doProcessBlock(offset), which must be implemented by a concrete subtype. + * + * @param {boolean} doFlush Whether all blocks and partial blocks should be processed. + * + * @return {WordArray} The processed data. + * + * @example + * + * var processedData = bufferedBlockAlgorithm._process(); + * var processedData = bufferedBlockAlgorithm._process(!!'flush'); + */ + _process: function (doFlush) { + var processedWords; + + // Shortcuts + var data = this._data; + var dataWords = data.words; + var dataSigBytes = data.sigBytes; + var blockSize = this.blockSize; + var blockSizeBytes = blockSize * 4; + + // Count blocks ready + var nBlocksReady = dataSigBytes / blockSizeBytes; + if (doFlush) { + // Round up to include partial blocks + nBlocksReady = Math.ceil(nBlocksReady); + } else { + // Round down to include only full blocks, + // less the number of blocks that must remain in the buffer + nBlocksReady = Math.max((nBlocksReady | 0) - this._minBufferSize, 0); + } + + // Count words ready + var nWordsReady = nBlocksReady * blockSize; + + // Count bytes ready + var nBytesReady = Math.min(nWordsReady * 4, dataSigBytes); + + // Process blocks + if (nWordsReady) { + for (var offset = 0; offset < nWordsReady; offset += blockSize) { + // Perform concrete-algorithm logic + this._doProcessBlock(dataWords, offset); + } + + // Remove processed words + processedWords = dataWords.splice(0, nWordsReady); + data.sigBytes -= nBytesReady; + } + + // Return processed words + return new WordArray.init(processedWords, nBytesReady); + }, + + /** + * Creates a copy of this object. + * + * @return {Object} The clone. + * + * @example + * + * var clone = bufferedBlockAlgorithm.clone(); + */ + clone: function () { + var clone = Base.clone.call(this); + clone._data = this._data.clone(); + + return clone; + }, + + _minBufferSize: 0 + }); + + /** + * Abstract hasher template. + * + * @property {number} blockSize The number of 32-bit words this hasher operates on. Default: 16 (512 bits) + */ + var Hasher = C_lib.Hasher = BufferedBlockAlgorithm.extend({ + /** + * Configuration options. + */ + cfg: Base.extend(), + + /** + * Initializes a newly created hasher. + * + * @param {Object} cfg (Optional) The configuration options to use for this hash computation. + * + * @example + * + * var hasher = CryptoJS.algo.SHA256.create(); + */ + init: function (cfg) { + // Apply config defaults + this.cfg = this.cfg.extend(cfg); + + // Set initial values + this.reset(); + }, + + /** + * Resets this hasher to its initial state. + * + * @example + * + * hasher.reset(); + */ + reset: function () { + // Reset data buffer + BufferedBlockAlgorithm.reset.call(this); + + // Perform concrete-hasher logic + this._doReset(); + }, + + /** + * Updates this hasher with a message. + * + * @param {WordArray|string} messageUpdate The message to append. + * + * @return {Hasher} This hasher. + * + * @example + * + * hasher.update('message'); + * hasher.update(wordArray); + */ + update: function (messageUpdate) { + // Append + this._append(messageUpdate); + + // Update the hash + this._process(); + + // Chainable + return this; + }, + + /** + * Finalizes the hash computation. + * Note that the finalize operation is effectively a destructive, read-once operation. + * + * @param {WordArray|string} messageUpdate (Optional) A final message update. + * + * @return {WordArray} The hash. + * + * @example + * + * var hash = hasher.finalize(); + * var hash = hasher.finalize('message'); + * var hash = hasher.finalize(wordArray); + */ + finalize: function (messageUpdate) { + // Final message update + if (messageUpdate) { + this._append(messageUpdate); + } + + // Perform concrete-hasher logic + var hash = this._doFinalize(); + + return hash; + }, + + blockSize: 512/32, + + /** + * Creates a shortcut function to a hasher's object interface. + * + * @param {Hasher} hasher The hasher to create a helper for. + * + * @return {Function} The shortcut function. + * + * @static + * + * @example + * + * var SHA256 = CryptoJS.lib.Hasher._createHelper(CryptoJS.algo.SHA256); + */ + _createHelper: function (hasher) { + return function (message, cfg) { + return new hasher.init(cfg).finalize(message); + }; + }, + + /** + * Creates a shortcut function to the HMAC's object interface. + * + * @param {Hasher} hasher The hasher to use in this HMAC helper. + * + * @return {Function} The shortcut function. + * + * @static + * + * @example + * + * var HmacSHA256 = CryptoJS.lib.Hasher._createHmacHelper(CryptoJS.algo.SHA256); + */ + _createHmacHelper: function (hasher) { + return function (message, key) { + return new C_algo.HMAC.init(hasher, key).finalize(message); + }; + } + }); + + /** + * Algorithm namespace. + */ + var C_algo = C.algo = {}; + + return C; + }(Math)); + + + return CryptoJS; + +})); \ No newline at end of file diff --git a/node_modules/crypto-js/crypto-js.js b/node_modules/crypto-js/crypto-js.js new file mode 100644 index 0000000..958ee53 --- /dev/null +++ b/node_modules/crypto-js/crypto-js.js @@ -0,0 +1,6657 @@ +;(function (root, factory) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(); + } + else if (typeof define === "function" && define.amd) { + // AMD + define([], factory); + } + else { + // Global (browser) + root.CryptoJS = factory(); + } +}(this, function () { + + /*globals window, global, require*/ + + /** + * CryptoJS core components. + */ + var CryptoJS = CryptoJS || (function (Math, undefined) { + + var crypto; + + // Native crypto from window (Browser) + if (typeof window !== 'undefined' && window.crypto) { + crypto = window.crypto; + } + + // Native crypto in web worker (Browser) + if (typeof self !== 'undefined' && self.crypto) { + crypto = self.crypto; + } + + // Native crypto from worker + if (typeof globalThis !== 'undefined' && globalThis.crypto) { + crypto = globalThis.crypto; + } + + // Native (experimental IE 11) crypto from window (Browser) + if (!crypto && typeof window !== 'undefined' && window.msCrypto) { + crypto = window.msCrypto; + } + + // Native crypto from global (NodeJS) + if (!crypto && typeof global !== 'undefined' && global.crypto) { + crypto = global.crypto; + } + + // Native crypto import via require (NodeJS) + if (!crypto && typeof require === 'function') { + try { + crypto = require('crypto'); + } catch (err) {} + } + + /* + * Cryptographically secure pseudorandom number generator + * + * As Math.random() is cryptographically not safe to use + */ + var cryptoSecureRandomInt = function () { + if (crypto) { + // Use getRandomValues method (Browser) + if (typeof crypto.getRandomValues === 'function') { + try { + return crypto.getRandomValues(new Uint32Array(1))[0]; + } catch (err) {} + } + + // Use randomBytes method (NodeJS) + if (typeof crypto.randomBytes === 'function') { + try { + return crypto.randomBytes(4).readInt32LE(); + } catch (err) {} + } + } + + throw new Error('Native crypto module could not be used to get secure random number.'); + }; + + /* + * Local polyfill of Object.create + + */ + var create = Object.create || (function () { + function F() {} + + return function (obj) { + var subtype; + + F.prototype = obj; + + subtype = new F(); + + F.prototype = null; + + return subtype; + }; + }()); + + /** + * CryptoJS namespace. + */ + var C = {}; + + /** + * Library namespace. + */ + var C_lib = C.lib = {}; + + /** + * Base object for prototypal inheritance. + */ + var Base = C_lib.Base = (function () { + + + return { + /** + * Creates a new object that inherits from this object. + * + * @param {Object} overrides Properties to copy into the new object. + * + * @return {Object} The new object. + * + * @static + * + * @example + * + * var MyType = CryptoJS.lib.Base.extend({ + * field: 'value', + * + * method: function () { + * } + * }); + */ + extend: function (overrides) { + // Spawn + var subtype = create(this); + + // Augment + if (overrides) { + subtype.mixIn(overrides); + } + + // Create default initializer + if (!subtype.hasOwnProperty('init') || this.init === subtype.init) { + subtype.init = function () { + subtype.$super.init.apply(this, arguments); + }; + } + + // Initializer's prototype is the subtype object + subtype.init.prototype = subtype; + + // Reference supertype + subtype.$super = this; + + return subtype; + }, + + /** + * Extends this object and runs the init method. + * Arguments to create() will be passed to init(). + * + * @return {Object} The new object. + * + * @static + * + * @example + * + * var instance = MyType.create(); + */ + create: function () { + var instance = this.extend(); + instance.init.apply(instance, arguments); + + return instance; + }, + + /** + * Initializes a newly created object. + * Override this method to add some logic when your objects are created. + * + * @example + * + * var MyType = CryptoJS.lib.Base.extend({ + * init: function () { + * // ... + * } + * }); + */ + init: function () { + }, + + /** + * Copies properties into this object. + * + * @param {Object} properties The properties to mix in. + * + * @example + * + * MyType.mixIn({ + * field: 'value' + * }); + */ + mixIn: function (properties) { + for (var propertyName in properties) { + if (properties.hasOwnProperty(propertyName)) { + this[propertyName] = properties[propertyName]; + } + } + + // IE won't copy toString using the loop above + if (properties.hasOwnProperty('toString')) { + this.toString = properties.toString; + } + }, + + /** + * Creates a copy of this object. + * + * @return {Object} The clone. + * + * @example + * + * var clone = instance.clone(); + */ + clone: function () { + return this.init.prototype.extend(this); + } + }; + }()); + + /** + * An array of 32-bit words. + * + * @property {Array} words The array of 32-bit words. + * @property {number} sigBytes The number of significant bytes in this word array. + */ + var WordArray = C_lib.WordArray = Base.extend({ + /** + * Initializes a newly created word array. + * + * @param {Array} words (Optional) An array of 32-bit words. + * @param {number} sigBytes (Optional) The number of significant bytes in the words. + * + * @example + * + * var wordArray = CryptoJS.lib.WordArray.create(); + * var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607]); + * var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607], 6); + */ + init: function (words, sigBytes) { + words = this.words = words || []; + + if (sigBytes != undefined) { + this.sigBytes = sigBytes; + } else { + this.sigBytes = words.length * 4; + } + }, + + /** + * Converts this word array to a string. + * + * @param {Encoder} encoder (Optional) The encoding strategy to use. Default: CryptoJS.enc.Hex + * + * @return {string} The stringified word array. + * + * @example + * + * var string = wordArray + ''; + * var string = wordArray.toString(); + * var string = wordArray.toString(CryptoJS.enc.Utf8); + */ + toString: function (encoder) { + return (encoder || Hex).stringify(this); + }, + + /** + * Concatenates a word array to this word array. + * + * @param {WordArray} wordArray The word array to append. + * + * @return {WordArray} This word array. + * + * @example + * + * wordArray1.concat(wordArray2); + */ + concat: function (wordArray) { + // Shortcuts + var thisWords = this.words; + var thatWords = wordArray.words; + var thisSigBytes = this.sigBytes; + var thatSigBytes = wordArray.sigBytes; + + // Clamp excess bits + this.clamp(); + + // Concat + if (thisSigBytes % 4) { + // Copy one byte at a time + for (var i = 0; i < thatSigBytes; i++) { + var thatByte = (thatWords[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; + thisWords[(thisSigBytes + i) >>> 2] |= thatByte << (24 - ((thisSigBytes + i) % 4) * 8); + } + } else { + // Copy one word at a time + for (var j = 0; j < thatSigBytes; j += 4) { + thisWords[(thisSigBytes + j) >>> 2] = thatWords[j >>> 2]; + } + } + this.sigBytes += thatSigBytes; + + // Chainable + return this; + }, + + /** + * Removes insignificant bits. + * + * @example + * + * wordArray.clamp(); + */ + clamp: function () { + // Shortcuts + var words = this.words; + var sigBytes = this.sigBytes; + + // Clamp + words[sigBytes >>> 2] &= 0xffffffff << (32 - (sigBytes % 4) * 8); + words.length = Math.ceil(sigBytes / 4); + }, + + /** + * Creates a copy of this word array. + * + * @return {WordArray} The clone. + * + * @example + * + * var clone = wordArray.clone(); + */ + clone: function () { + var clone = Base.clone.call(this); + clone.words = this.words.slice(0); + + return clone; + }, + + /** + * Creates a word array filled with random bytes. + * + * @param {number} nBytes The number of random bytes to generate. + * + * @return {WordArray} The random word array. + * + * @static + * + * @example + * + * var wordArray = CryptoJS.lib.WordArray.random(16); + */ + random: function (nBytes) { + var words = []; + + for (var i = 0; i < nBytes; i += 4) { + words.push(cryptoSecureRandomInt()); + } + + return new WordArray.init(words, nBytes); + } + }); + + /** + * Encoder namespace. + */ + var C_enc = C.enc = {}; + + /** + * Hex encoding strategy. + */ + var Hex = C_enc.Hex = { + /** + * Converts a word array to a hex string. + * + * @param {WordArray} wordArray The word array. + * + * @return {string} The hex string. + * + * @static + * + * @example + * + * var hexString = CryptoJS.enc.Hex.stringify(wordArray); + */ + stringify: function (wordArray) { + // Shortcuts + var words = wordArray.words; + var sigBytes = wordArray.sigBytes; + + // Convert + var hexChars = []; + for (var i = 0; i < sigBytes; i++) { + var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; + hexChars.push((bite >>> 4).toString(16)); + hexChars.push((bite & 0x0f).toString(16)); + } + + return hexChars.join(''); + }, + + /** + * Converts a hex string to a word array. + * + * @param {string} hexStr The hex string. + * + * @return {WordArray} The word array. + * + * @static + * + * @example + * + * var wordArray = CryptoJS.enc.Hex.parse(hexString); + */ + parse: function (hexStr) { + // Shortcut + var hexStrLength = hexStr.length; + + // Convert + var words = []; + for (var i = 0; i < hexStrLength; i += 2) { + words[i >>> 3] |= parseInt(hexStr.substr(i, 2), 16) << (24 - (i % 8) * 4); + } + + return new WordArray.init(words, hexStrLength / 2); + } + }; + + /** + * Latin1 encoding strategy. + */ + var Latin1 = C_enc.Latin1 = { + /** + * Converts a word array to a Latin1 string. + * + * @param {WordArray} wordArray The word array. + * + * @return {string} The Latin1 string. + * + * @static + * + * @example + * + * var latin1String = CryptoJS.enc.Latin1.stringify(wordArray); + */ + stringify: function (wordArray) { + // Shortcuts + var words = wordArray.words; + var sigBytes = wordArray.sigBytes; + + // Convert + var latin1Chars = []; + for (var i = 0; i < sigBytes; i++) { + var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; + latin1Chars.push(String.fromCharCode(bite)); + } + + return latin1Chars.join(''); + }, + + /** + * Converts a Latin1 string to a word array. + * + * @param {string} latin1Str The Latin1 string. + * + * @return {WordArray} The word array. + * + * @static + * + * @example + * + * var wordArray = CryptoJS.enc.Latin1.parse(latin1String); + */ + parse: function (latin1Str) { + // Shortcut + var latin1StrLength = latin1Str.length; + + // Convert + var words = []; + for (var i = 0; i < latin1StrLength; i++) { + words[i >>> 2] |= (latin1Str.charCodeAt(i) & 0xff) << (24 - (i % 4) * 8); + } + + return new WordArray.init(words, latin1StrLength); + } + }; + + /** + * UTF-8 encoding strategy. + */ + var Utf8 = C_enc.Utf8 = { + /** + * Converts a word array to a UTF-8 string. + * + * @param {WordArray} wordArray The word array. + * + * @return {string} The UTF-8 string. + * + * @static + * + * @example + * + * var utf8String = CryptoJS.enc.Utf8.stringify(wordArray); + */ + stringify: function (wordArray) { + try { + return decodeURIComponent(escape(Latin1.stringify(wordArray))); + } catch (e) { + throw new Error('Malformed UTF-8 data'); + } + }, + + /** + * Converts a UTF-8 string to a word array. + * + * @param {string} utf8Str The UTF-8 string. + * + * @return {WordArray} The word array. + * + * @static + * + * @example + * + * var wordArray = CryptoJS.enc.Utf8.parse(utf8String); + */ + parse: function (utf8Str) { + return Latin1.parse(unescape(encodeURIComponent(utf8Str))); + } + }; + + /** + * Abstract buffered block algorithm template. + * + * The property blockSize must be implemented in a concrete subtype. + * + * @property {number} _minBufferSize The number of blocks that should be kept unprocessed in the buffer. Default: 0 + */ + var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm = Base.extend({ + /** + * Resets this block algorithm's data buffer to its initial state. + * + * @example + * + * bufferedBlockAlgorithm.reset(); + */ + reset: function () { + // Initial values + this._data = new WordArray.init(); + this._nDataBytes = 0; + }, + + /** + * Adds new data to this block algorithm's buffer. + * + * @param {WordArray|string} data The data to append. Strings are converted to a WordArray using UTF-8. + * + * @example + * + * bufferedBlockAlgorithm._append('data'); + * bufferedBlockAlgorithm._append(wordArray); + */ + _append: function (data) { + // Convert string to WordArray, else assume WordArray already + if (typeof data == 'string') { + data = Utf8.parse(data); + } + + // Append + this._data.concat(data); + this._nDataBytes += data.sigBytes; + }, + + /** + * Processes available data blocks. + * + * This method invokes _doProcessBlock(offset), which must be implemented by a concrete subtype. + * + * @param {boolean} doFlush Whether all blocks and partial blocks should be processed. + * + * @return {WordArray} The processed data. + * + * @example + * + * var processedData = bufferedBlockAlgorithm._process(); + * var processedData = bufferedBlockAlgorithm._process(!!'flush'); + */ + _process: function (doFlush) { + var processedWords; + + // Shortcuts + var data = this._data; + var dataWords = data.words; + var dataSigBytes = data.sigBytes; + var blockSize = this.blockSize; + var blockSizeBytes = blockSize * 4; + + // Count blocks ready + var nBlocksReady = dataSigBytes / blockSizeBytes; + if (doFlush) { + // Round up to include partial blocks + nBlocksReady = Math.ceil(nBlocksReady); + } else { + // Round down to include only full blocks, + // less the number of blocks that must remain in the buffer + nBlocksReady = Math.max((nBlocksReady | 0) - this._minBufferSize, 0); + } + + // Count words ready + var nWordsReady = nBlocksReady * blockSize; + + // Count bytes ready + var nBytesReady = Math.min(nWordsReady * 4, dataSigBytes); + + // Process blocks + if (nWordsReady) { + for (var offset = 0; offset < nWordsReady; offset += blockSize) { + // Perform concrete-algorithm logic + this._doProcessBlock(dataWords, offset); + } + + // Remove processed words + processedWords = dataWords.splice(0, nWordsReady); + data.sigBytes -= nBytesReady; + } + + // Return processed words + return new WordArray.init(processedWords, nBytesReady); + }, + + /** + * Creates a copy of this object. + * + * @return {Object} The clone. + * + * @example + * + * var clone = bufferedBlockAlgorithm.clone(); + */ + clone: function () { + var clone = Base.clone.call(this); + clone._data = this._data.clone(); + + return clone; + }, + + _minBufferSize: 0 + }); + + /** + * Abstract hasher template. + * + * @property {number} blockSize The number of 32-bit words this hasher operates on. Default: 16 (512 bits) + */ + var Hasher = C_lib.Hasher = BufferedBlockAlgorithm.extend({ + /** + * Configuration options. + */ + cfg: Base.extend(), + + /** + * Initializes a newly created hasher. + * + * @param {Object} cfg (Optional) The configuration options to use for this hash computation. + * + * @example + * + * var hasher = CryptoJS.algo.SHA256.create(); + */ + init: function (cfg) { + // Apply config defaults + this.cfg = this.cfg.extend(cfg); + + // Set initial values + this.reset(); + }, + + /** + * Resets this hasher to its initial state. + * + * @example + * + * hasher.reset(); + */ + reset: function () { + // Reset data buffer + BufferedBlockAlgorithm.reset.call(this); + + // Perform concrete-hasher logic + this._doReset(); + }, + + /** + * Updates this hasher with a message. + * + * @param {WordArray|string} messageUpdate The message to append. + * + * @return {Hasher} This hasher. + * + * @example + * + * hasher.update('message'); + * hasher.update(wordArray); + */ + update: function (messageUpdate) { + // Append + this._append(messageUpdate); + + // Update the hash + this._process(); + + // Chainable + return this; + }, + + /** + * Finalizes the hash computation. + * Note that the finalize operation is effectively a destructive, read-once operation. + * + * @param {WordArray|string} messageUpdate (Optional) A final message update. + * + * @return {WordArray} The hash. + * + * @example + * + * var hash = hasher.finalize(); + * var hash = hasher.finalize('message'); + * var hash = hasher.finalize(wordArray); + */ + finalize: function (messageUpdate) { + // Final message update + if (messageUpdate) { + this._append(messageUpdate); + } + + // Perform concrete-hasher logic + var hash = this._doFinalize(); + + return hash; + }, + + blockSize: 512/32, + + /** + * Creates a shortcut function to a hasher's object interface. + * + * @param {Hasher} hasher The hasher to create a helper for. + * + * @return {Function} The shortcut function. + * + * @static + * + * @example + * + * var SHA256 = CryptoJS.lib.Hasher._createHelper(CryptoJS.algo.SHA256); + */ + _createHelper: function (hasher) { + return function (message, cfg) { + return new hasher.init(cfg).finalize(message); + }; + }, + + /** + * Creates a shortcut function to the HMAC's object interface. + * + * @param {Hasher} hasher The hasher to use in this HMAC helper. + * + * @return {Function} The shortcut function. + * + * @static + * + * @example + * + * var HmacSHA256 = CryptoJS.lib.Hasher._createHmacHelper(CryptoJS.algo.SHA256); + */ + _createHmacHelper: function (hasher) { + return function (message, key) { + return new C_algo.HMAC.init(hasher, key).finalize(message); + }; + } + }); + + /** + * Algorithm namespace. + */ + var C_algo = C.algo = {}; + + return C; + }(Math)); + + + (function (undefined) { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var Base = C_lib.Base; + var X32WordArray = C_lib.WordArray; + + /** + * x64 namespace. + */ + var C_x64 = C.x64 = {}; + + /** + * A 64-bit word. + */ + var X64Word = C_x64.Word = Base.extend({ + /** + * Initializes a newly created 64-bit word. + * + * @param {number} high The high 32 bits. + * @param {number} low The low 32 bits. + * + * @example + * + * var x64Word = CryptoJS.x64.Word.create(0x00010203, 0x04050607); + */ + init: function (high, low) { + this.high = high; + this.low = low; + } + + /** + * Bitwise NOTs this word. + * + * @return {X64Word} A new x64-Word object after negating. + * + * @example + * + * var negated = x64Word.not(); + */ + // not: function () { + // var high = ~this.high; + // var low = ~this.low; + + // return X64Word.create(high, low); + // }, + + /** + * Bitwise ANDs this word with the passed word. + * + * @param {X64Word} word The x64-Word to AND with this word. + * + * @return {X64Word} A new x64-Word object after ANDing. + * + * @example + * + * var anded = x64Word.and(anotherX64Word); + */ + // and: function (word) { + // var high = this.high & word.high; + // var low = this.low & word.low; + + // return X64Word.create(high, low); + // }, + + /** + * Bitwise ORs this word with the passed word. + * + * @param {X64Word} word The x64-Word to OR with this word. + * + * @return {X64Word} A new x64-Word object after ORing. + * + * @example + * + * var ored = x64Word.or(anotherX64Word); + */ + // or: function (word) { + // var high = this.high | word.high; + // var low = this.low | word.low; + + // return X64Word.create(high, low); + // }, + + /** + * Bitwise XORs this word with the passed word. + * + * @param {X64Word} word The x64-Word to XOR with this word. + * + * @return {X64Word} A new x64-Word object after XORing. + * + * @example + * + * var xored = x64Word.xor(anotherX64Word); + */ + // xor: function (word) { + // var high = this.high ^ word.high; + // var low = this.low ^ word.low; + + // return X64Word.create(high, low); + // }, + + /** + * Shifts this word n bits to the left. + * + * @param {number} n The number of bits to shift. + * + * @return {X64Word} A new x64-Word object after shifting. + * + * @example + * + * var shifted = x64Word.shiftL(25); + */ + // shiftL: function (n) { + // if (n < 32) { + // var high = (this.high << n) | (this.low >>> (32 - n)); + // var low = this.low << n; + // } else { + // var high = this.low << (n - 32); + // var low = 0; + // } + + // return X64Word.create(high, low); + // }, + + /** + * Shifts this word n bits to the right. + * + * @param {number} n The number of bits to shift. + * + * @return {X64Word} A new x64-Word object after shifting. + * + * @example + * + * var shifted = x64Word.shiftR(7); + */ + // shiftR: function (n) { + // if (n < 32) { + // var low = (this.low >>> n) | (this.high << (32 - n)); + // var high = this.high >>> n; + // } else { + // var low = this.high >>> (n - 32); + // var high = 0; + // } + + // return X64Word.create(high, low); + // }, + + /** + * Rotates this word n bits to the left. + * + * @param {number} n The number of bits to rotate. + * + * @return {X64Word} A new x64-Word object after rotating. + * + * @example + * + * var rotated = x64Word.rotL(25); + */ + // rotL: function (n) { + // return this.shiftL(n).or(this.shiftR(64 - n)); + // }, + + /** + * Rotates this word n bits to the right. + * + * @param {number} n The number of bits to rotate. + * + * @return {X64Word} A new x64-Word object after rotating. + * + * @example + * + * var rotated = x64Word.rotR(7); + */ + // rotR: function (n) { + // return this.shiftR(n).or(this.shiftL(64 - n)); + // }, + + /** + * Adds this word with the passed word. + * + * @param {X64Word} word The x64-Word to add with this word. + * + * @return {X64Word} A new x64-Word object after adding. + * + * @example + * + * var added = x64Word.add(anotherX64Word); + */ + // add: function (word) { + // var low = (this.low + word.low) | 0; + // var carry = (low >>> 0) < (this.low >>> 0) ? 1 : 0; + // var high = (this.high + word.high + carry) | 0; + + // return X64Word.create(high, low); + // } + }); + + /** + * An array of 64-bit words. + * + * @property {Array} words The array of CryptoJS.x64.Word objects. + * @property {number} sigBytes The number of significant bytes in this word array. + */ + var X64WordArray = C_x64.WordArray = Base.extend({ + /** + * Initializes a newly created word array. + * + * @param {Array} words (Optional) An array of CryptoJS.x64.Word objects. + * @param {number} sigBytes (Optional) The number of significant bytes in the words. + * + * @example + * + * var wordArray = CryptoJS.x64.WordArray.create(); + * + * var wordArray = CryptoJS.x64.WordArray.create([ + * CryptoJS.x64.Word.create(0x00010203, 0x04050607), + * CryptoJS.x64.Word.create(0x18191a1b, 0x1c1d1e1f) + * ]); + * + * var wordArray = CryptoJS.x64.WordArray.create([ + * CryptoJS.x64.Word.create(0x00010203, 0x04050607), + * CryptoJS.x64.Word.create(0x18191a1b, 0x1c1d1e1f) + * ], 10); + */ + init: function (words, sigBytes) { + words = this.words = words || []; + + if (sigBytes != undefined) { + this.sigBytes = sigBytes; + } else { + this.sigBytes = words.length * 8; + } + }, + + /** + * Converts this 64-bit word array to a 32-bit word array. + * + * @return {CryptoJS.lib.WordArray} This word array's data as a 32-bit word array. + * + * @example + * + * var x32WordArray = x64WordArray.toX32(); + */ + toX32: function () { + // Shortcuts + var x64Words = this.words; + var x64WordsLength = x64Words.length; + + // Convert + var x32Words = []; + for (var i = 0; i < x64WordsLength; i++) { + var x64Word = x64Words[i]; + x32Words.push(x64Word.high); + x32Words.push(x64Word.low); + } + + return X32WordArray.create(x32Words, this.sigBytes); + }, + + /** + * Creates a copy of this word array. + * + * @return {X64WordArray} The clone. + * + * @example + * + * var clone = x64WordArray.clone(); + */ + clone: function () { + var clone = Base.clone.call(this); + + // Clone "words" array + var words = clone.words = this.words.slice(0); + + // Clone each X64Word object + var wordsLength = words.length; + for (var i = 0; i < wordsLength; i++) { + words[i] = words[i].clone(); + } + + return clone; + } + }); + }()); + + + (function () { + // Check if typed arrays are supported + if (typeof ArrayBuffer != 'function') { + return; + } + + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var WordArray = C_lib.WordArray; + + // Reference original init + var superInit = WordArray.init; + + // Augment WordArray.init to handle typed arrays + var subInit = WordArray.init = function (typedArray) { + // Convert buffers to uint8 + if (typedArray instanceof ArrayBuffer) { + typedArray = new Uint8Array(typedArray); + } + + // Convert other array views to uint8 + if ( + typedArray instanceof Int8Array || + (typeof Uint8ClampedArray !== "undefined" && typedArray instanceof Uint8ClampedArray) || + typedArray instanceof Int16Array || + typedArray instanceof Uint16Array || + typedArray instanceof Int32Array || + typedArray instanceof Uint32Array || + typedArray instanceof Float32Array || + typedArray instanceof Float64Array + ) { + typedArray = new Uint8Array(typedArray.buffer, typedArray.byteOffset, typedArray.byteLength); + } + + // Handle Uint8Array + if (typedArray instanceof Uint8Array) { + // Shortcut + var typedArrayByteLength = typedArray.byteLength; + + // Extract bytes + var words = []; + for (var i = 0; i < typedArrayByteLength; i++) { + words[i >>> 2] |= typedArray[i] << (24 - (i % 4) * 8); + } + + // Initialize this word array + superInit.call(this, words, typedArrayByteLength); + } else { + // Else call normal init + superInit.apply(this, arguments); + } + }; + + subInit.prototype = WordArray; + }()); + + + (function () { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var WordArray = C_lib.WordArray; + var C_enc = C.enc; + + /** + * UTF-16 BE encoding strategy. + */ + var Utf16BE = C_enc.Utf16 = C_enc.Utf16BE = { + /** + * Converts a word array to a UTF-16 BE string. + * + * @param {WordArray} wordArray The word array. + * + * @return {string} The UTF-16 BE string. + * + * @static + * + * @example + * + * var utf16String = CryptoJS.enc.Utf16.stringify(wordArray); + */ + stringify: function (wordArray) { + // Shortcuts + var words = wordArray.words; + var sigBytes = wordArray.sigBytes; + + // Convert + var utf16Chars = []; + for (var i = 0; i < sigBytes; i += 2) { + var codePoint = (words[i >>> 2] >>> (16 - (i % 4) * 8)) & 0xffff; + utf16Chars.push(String.fromCharCode(codePoint)); + } + + return utf16Chars.join(''); + }, + + /** + * Converts a UTF-16 BE string to a word array. + * + * @param {string} utf16Str The UTF-16 BE string. + * + * @return {WordArray} The word array. + * + * @static + * + * @example + * + * var wordArray = CryptoJS.enc.Utf16.parse(utf16String); + */ + parse: function (utf16Str) { + // Shortcut + var utf16StrLength = utf16Str.length; + + // Convert + var words = []; + for (var i = 0; i < utf16StrLength; i++) { + words[i >>> 1] |= utf16Str.charCodeAt(i) << (16 - (i % 2) * 16); + } + + return WordArray.create(words, utf16StrLength * 2); + } + }; + + /** + * UTF-16 LE encoding strategy. + */ + C_enc.Utf16LE = { + /** + * Converts a word array to a UTF-16 LE string. + * + * @param {WordArray} wordArray The word array. + * + * @return {string} The UTF-16 LE string. + * + * @static + * + * @example + * + * var utf16Str = CryptoJS.enc.Utf16LE.stringify(wordArray); + */ + stringify: function (wordArray) { + // Shortcuts + var words = wordArray.words; + var sigBytes = wordArray.sigBytes; + + // Convert + var utf16Chars = []; + for (var i = 0; i < sigBytes; i += 2) { + var codePoint = swapEndian((words[i >>> 2] >>> (16 - (i % 4) * 8)) & 0xffff); + utf16Chars.push(String.fromCharCode(codePoint)); + } + + return utf16Chars.join(''); + }, + + /** + * Converts a UTF-16 LE string to a word array. + * + * @param {string} utf16Str The UTF-16 LE string. + * + * @return {WordArray} The word array. + * + * @static + * + * @example + * + * var wordArray = CryptoJS.enc.Utf16LE.parse(utf16Str); + */ + parse: function (utf16Str) { + // Shortcut + var utf16StrLength = utf16Str.length; + + // Convert + var words = []; + for (var i = 0; i < utf16StrLength; i++) { + words[i >>> 1] |= swapEndian(utf16Str.charCodeAt(i) << (16 - (i % 2) * 16)); + } + + return WordArray.create(words, utf16StrLength * 2); + } + }; + + function swapEndian(word) { + return ((word << 8) & 0xff00ff00) | ((word >>> 8) & 0x00ff00ff); + } + }()); + + + (function () { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var WordArray = C_lib.WordArray; + var C_enc = C.enc; + + /** + * Base64 encoding strategy. + */ + var Base64 = C_enc.Base64 = { + /** + * Converts a word array to a Base64 string. + * + * @param {WordArray} wordArray The word array. + * + * @return {string} The Base64 string. + * + * @static + * + * @example + * + * var base64String = CryptoJS.enc.Base64.stringify(wordArray); + */ + stringify: function (wordArray) { + // Shortcuts + var words = wordArray.words; + var sigBytes = wordArray.sigBytes; + var map = this._map; + + // Clamp excess bits + wordArray.clamp(); + + // Convert + var base64Chars = []; + for (var i = 0; i < sigBytes; i += 3) { + var byte1 = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; + var byte2 = (words[(i + 1) >>> 2] >>> (24 - ((i + 1) % 4) * 8)) & 0xff; + var byte3 = (words[(i + 2) >>> 2] >>> (24 - ((i + 2) % 4) * 8)) & 0xff; + + var triplet = (byte1 << 16) | (byte2 << 8) | byte3; + + for (var j = 0; (j < 4) && (i + j * 0.75 < sigBytes); j++) { + base64Chars.push(map.charAt((triplet >>> (6 * (3 - j))) & 0x3f)); + } + } + + // Add padding + var paddingChar = map.charAt(64); + if (paddingChar) { + while (base64Chars.length % 4) { + base64Chars.push(paddingChar); + } + } + + return base64Chars.join(''); + }, + + /** + * Converts a Base64 string to a word array. + * + * @param {string} base64Str The Base64 string. + * + * @return {WordArray} The word array. + * + * @static + * + * @example + * + * var wordArray = CryptoJS.enc.Base64.parse(base64String); + */ + parse: function (base64Str) { + // Shortcuts + var base64StrLength = base64Str.length; + var map = this._map; + var reverseMap = this._reverseMap; + + if (!reverseMap) { + reverseMap = this._reverseMap = []; + for (var j = 0; j < map.length; j++) { + reverseMap[map.charCodeAt(j)] = j; + } + } + + // Ignore padding + var paddingChar = map.charAt(64); + if (paddingChar) { + var paddingIndex = base64Str.indexOf(paddingChar); + if (paddingIndex !== -1) { + base64StrLength = paddingIndex; + } + } + + // Convert + return parseLoop(base64Str, base64StrLength, reverseMap); + + }, + + _map: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=' + }; + + function parseLoop(base64Str, base64StrLength, reverseMap) { + var words = []; + var nBytes = 0; + for (var i = 0; i < base64StrLength; i++) { + if (i % 4) { + var bits1 = reverseMap[base64Str.charCodeAt(i - 1)] << ((i % 4) * 2); + var bits2 = reverseMap[base64Str.charCodeAt(i)] >>> (6 - (i % 4) * 2); + var bitsCombined = bits1 | bits2; + words[nBytes >>> 2] |= bitsCombined << (24 - (nBytes % 4) * 8); + nBytes++; + } + } + return WordArray.create(words, nBytes); + } + }()); + + + (function () { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var WordArray = C_lib.WordArray; + var C_enc = C.enc; + + /** + * Base64url encoding strategy. + */ + var Base64url = C_enc.Base64url = { + /** + * Converts a word array to a Base64url string. + * + * @param {WordArray} wordArray The word array. + * + * @param {boolean} urlSafe Whether to use url safe + * + * @return {string} The Base64url string. + * + * @static + * + * @example + * + * var base64String = CryptoJS.enc.Base64url.stringify(wordArray); + */ + stringify: function (wordArray, urlSafe) { + if (urlSafe === undefined) { + urlSafe = true + } + // Shortcuts + var words = wordArray.words; + var sigBytes = wordArray.sigBytes; + var map = urlSafe ? this._safe_map : this._map; + + // Clamp excess bits + wordArray.clamp(); + + // Convert + var base64Chars = []; + for (var i = 0; i < sigBytes; i += 3) { + var byte1 = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; + var byte2 = (words[(i + 1) >>> 2] >>> (24 - ((i + 1) % 4) * 8)) & 0xff; + var byte3 = (words[(i + 2) >>> 2] >>> (24 - ((i + 2) % 4) * 8)) & 0xff; + + var triplet = (byte1 << 16) | (byte2 << 8) | byte3; + + for (var j = 0; (j < 4) && (i + j * 0.75 < sigBytes); j++) { + base64Chars.push(map.charAt((triplet >>> (6 * (3 - j))) & 0x3f)); + } + } + + // Add padding + var paddingChar = map.charAt(64); + if (paddingChar) { + while (base64Chars.length % 4) { + base64Chars.push(paddingChar); + } + } + + return base64Chars.join(''); + }, + + /** + * Converts a Base64url string to a word array. + * + * @param {string} base64Str The Base64url string. + * + * @param {boolean} urlSafe Whether to use url safe + * + * @return {WordArray} The word array. + * + * @static + * + * @example + * + * var wordArray = CryptoJS.enc.Base64url.parse(base64String); + */ + parse: function (base64Str, urlSafe) { + if (urlSafe === undefined) { + urlSafe = true + } + + // Shortcuts + var base64StrLength = base64Str.length; + var map = urlSafe ? this._safe_map : this._map; + var reverseMap = this._reverseMap; + + if (!reverseMap) { + reverseMap = this._reverseMap = []; + for (var j = 0; j < map.length; j++) { + reverseMap[map.charCodeAt(j)] = j; + } + } + + // Ignore padding + var paddingChar = map.charAt(64); + if (paddingChar) { + var paddingIndex = base64Str.indexOf(paddingChar); + if (paddingIndex !== -1) { + base64StrLength = paddingIndex; + } + } + + // Convert + return parseLoop(base64Str, base64StrLength, reverseMap); + + }, + + _map: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=', + _safe_map: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_', + }; + + function parseLoop(base64Str, base64StrLength, reverseMap) { + var words = []; + var nBytes = 0; + for (var i = 0; i < base64StrLength; i++) { + if (i % 4) { + var bits1 = reverseMap[base64Str.charCodeAt(i - 1)] << ((i % 4) * 2); + var bits2 = reverseMap[base64Str.charCodeAt(i)] >>> (6 - (i % 4) * 2); + var bitsCombined = bits1 | bits2; + words[nBytes >>> 2] |= bitsCombined << (24 - (nBytes % 4) * 8); + nBytes++; + } + } + return WordArray.create(words, nBytes); + } + }()); + + + (function (Math) { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var WordArray = C_lib.WordArray; + var Hasher = C_lib.Hasher; + var C_algo = C.algo; + + // Constants table + var T = []; + + // Compute constants + (function () { + for (var i = 0; i < 64; i++) { + T[i] = (Math.abs(Math.sin(i + 1)) * 0x100000000) | 0; + } + }()); + + /** + * MD5 hash algorithm. + */ + var MD5 = C_algo.MD5 = Hasher.extend({ + _doReset: function () { + this._hash = new WordArray.init([ + 0x67452301, 0xefcdab89, + 0x98badcfe, 0x10325476 + ]); + }, + + _doProcessBlock: function (M, offset) { + // Swap endian + for (var i = 0; i < 16; i++) { + // Shortcuts + var offset_i = offset + i; + var M_offset_i = M[offset_i]; + + M[offset_i] = ( + (((M_offset_i << 8) | (M_offset_i >>> 24)) & 0x00ff00ff) | + (((M_offset_i << 24) | (M_offset_i >>> 8)) & 0xff00ff00) + ); + } + + // Shortcuts + var H = this._hash.words; + + var M_offset_0 = M[offset + 0]; + var M_offset_1 = M[offset + 1]; + var M_offset_2 = M[offset + 2]; + var M_offset_3 = M[offset + 3]; + var M_offset_4 = M[offset + 4]; + var M_offset_5 = M[offset + 5]; + var M_offset_6 = M[offset + 6]; + var M_offset_7 = M[offset + 7]; + var M_offset_8 = M[offset + 8]; + var M_offset_9 = M[offset + 9]; + var M_offset_10 = M[offset + 10]; + var M_offset_11 = M[offset + 11]; + var M_offset_12 = M[offset + 12]; + var M_offset_13 = M[offset + 13]; + var M_offset_14 = M[offset + 14]; + var M_offset_15 = M[offset + 15]; + + // Working variables + var a = H[0]; + var b = H[1]; + var c = H[2]; + var d = H[3]; + + // Computation + a = FF(a, b, c, d, M_offset_0, 7, T[0]); + d = FF(d, a, b, c, M_offset_1, 12, T[1]); + c = FF(c, d, a, b, M_offset_2, 17, T[2]); + b = FF(b, c, d, a, M_offset_3, 22, T[3]); + a = FF(a, b, c, d, M_offset_4, 7, T[4]); + d = FF(d, a, b, c, M_offset_5, 12, T[5]); + c = FF(c, d, a, b, M_offset_6, 17, T[6]); + b = FF(b, c, d, a, M_offset_7, 22, T[7]); + a = FF(a, b, c, d, M_offset_8, 7, T[8]); + d = FF(d, a, b, c, M_offset_9, 12, T[9]); + c = FF(c, d, a, b, M_offset_10, 17, T[10]); + b = FF(b, c, d, a, M_offset_11, 22, T[11]); + a = FF(a, b, c, d, M_offset_12, 7, T[12]); + d = FF(d, a, b, c, M_offset_13, 12, T[13]); + c = FF(c, d, a, b, M_offset_14, 17, T[14]); + b = FF(b, c, d, a, M_offset_15, 22, T[15]); + + a = GG(a, b, c, d, M_offset_1, 5, T[16]); + d = GG(d, a, b, c, M_offset_6, 9, T[17]); + c = GG(c, d, a, b, M_offset_11, 14, T[18]); + b = GG(b, c, d, a, M_offset_0, 20, T[19]); + a = GG(a, b, c, d, M_offset_5, 5, T[20]); + d = GG(d, a, b, c, M_offset_10, 9, T[21]); + c = GG(c, d, a, b, M_offset_15, 14, T[22]); + b = GG(b, c, d, a, M_offset_4, 20, T[23]); + a = GG(a, b, c, d, M_offset_9, 5, T[24]); + d = GG(d, a, b, c, M_offset_14, 9, T[25]); + c = GG(c, d, a, b, M_offset_3, 14, T[26]); + b = GG(b, c, d, a, M_offset_8, 20, T[27]); + a = GG(a, b, c, d, M_offset_13, 5, T[28]); + d = GG(d, a, b, c, M_offset_2, 9, T[29]); + c = GG(c, d, a, b, M_offset_7, 14, T[30]); + b = GG(b, c, d, a, M_offset_12, 20, T[31]); + + a = HH(a, b, c, d, M_offset_5, 4, T[32]); + d = HH(d, a, b, c, M_offset_8, 11, T[33]); + c = HH(c, d, a, b, M_offset_11, 16, T[34]); + b = HH(b, c, d, a, M_offset_14, 23, T[35]); + a = HH(a, b, c, d, M_offset_1, 4, T[36]); + d = HH(d, a, b, c, M_offset_4, 11, T[37]); + c = HH(c, d, a, b, M_offset_7, 16, T[38]); + b = HH(b, c, d, a, M_offset_10, 23, T[39]); + a = HH(a, b, c, d, M_offset_13, 4, T[40]); + d = HH(d, a, b, c, M_offset_0, 11, T[41]); + c = HH(c, d, a, b, M_offset_3, 16, T[42]); + b = HH(b, c, d, a, M_offset_6, 23, T[43]); + a = HH(a, b, c, d, M_offset_9, 4, T[44]); + d = HH(d, a, b, c, M_offset_12, 11, T[45]); + c = HH(c, d, a, b, M_offset_15, 16, T[46]); + b = HH(b, c, d, a, M_offset_2, 23, T[47]); + + a = II(a, b, c, d, M_offset_0, 6, T[48]); + d = II(d, a, b, c, M_offset_7, 10, T[49]); + c = II(c, d, a, b, M_offset_14, 15, T[50]); + b = II(b, c, d, a, M_offset_5, 21, T[51]); + a = II(a, b, c, d, M_offset_12, 6, T[52]); + d = II(d, a, b, c, M_offset_3, 10, T[53]); + c = II(c, d, a, b, M_offset_10, 15, T[54]); + b = II(b, c, d, a, M_offset_1, 21, T[55]); + a = II(a, b, c, d, M_offset_8, 6, T[56]); + d = II(d, a, b, c, M_offset_15, 10, T[57]); + c = II(c, d, a, b, M_offset_6, 15, T[58]); + b = II(b, c, d, a, M_offset_13, 21, T[59]); + a = II(a, b, c, d, M_offset_4, 6, T[60]); + d = II(d, a, b, c, M_offset_11, 10, T[61]); + c = II(c, d, a, b, M_offset_2, 15, T[62]); + b = II(b, c, d, a, M_offset_9, 21, T[63]); + + // Intermediate hash value + H[0] = (H[0] + a) | 0; + H[1] = (H[1] + b) | 0; + H[2] = (H[2] + c) | 0; + H[3] = (H[3] + d) | 0; + }, + + _doFinalize: function () { + // Shortcuts + var data = this._data; + var dataWords = data.words; + + var nBitsTotal = this._nDataBytes * 8; + var nBitsLeft = data.sigBytes * 8; + + // Add padding + dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32); + + var nBitsTotalH = Math.floor(nBitsTotal / 0x100000000); + var nBitsTotalL = nBitsTotal; + dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = ( + (((nBitsTotalH << 8) | (nBitsTotalH >>> 24)) & 0x00ff00ff) | + (((nBitsTotalH << 24) | (nBitsTotalH >>> 8)) & 0xff00ff00) + ); + dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = ( + (((nBitsTotalL << 8) | (nBitsTotalL >>> 24)) & 0x00ff00ff) | + (((nBitsTotalL << 24) | (nBitsTotalL >>> 8)) & 0xff00ff00) + ); + + data.sigBytes = (dataWords.length + 1) * 4; + + // Hash final blocks + this._process(); + + // Shortcuts + var hash = this._hash; + var H = hash.words; + + // Swap endian + for (var i = 0; i < 4; i++) { + // Shortcut + var H_i = H[i]; + + H[i] = (((H_i << 8) | (H_i >>> 24)) & 0x00ff00ff) | + (((H_i << 24) | (H_i >>> 8)) & 0xff00ff00); + } + + // Return final computed hash + return hash; + }, + + clone: function () { + var clone = Hasher.clone.call(this); + clone._hash = this._hash.clone(); + + return clone; + } + }); + + function FF(a, b, c, d, x, s, t) { + var n = a + ((b & c) | (~b & d)) + x + t; + return ((n << s) | (n >>> (32 - s))) + b; + } + + function GG(a, b, c, d, x, s, t) { + var n = a + ((b & d) | (c & ~d)) + x + t; + return ((n << s) | (n >>> (32 - s))) + b; + } + + function HH(a, b, c, d, x, s, t) { + var n = a + (b ^ c ^ d) + x + t; + return ((n << s) | (n >>> (32 - s))) + b; + } + + function II(a, b, c, d, x, s, t) { + var n = a + (c ^ (b | ~d)) + x + t; + return ((n << s) | (n >>> (32 - s))) + b; + } + + /** + * Shortcut function to the hasher's object interface. + * + * @param {WordArray|string} message The message to hash. + * + * @return {WordArray} The hash. + * + * @static + * + * @example + * + * var hash = CryptoJS.MD5('message'); + * var hash = CryptoJS.MD5(wordArray); + */ + C.MD5 = Hasher._createHelper(MD5); + + /** + * Shortcut function to the HMAC's object interface. + * + * @param {WordArray|string} message The message to hash. + * @param {WordArray|string} key The secret key. + * + * @return {WordArray} The HMAC. + * + * @static + * + * @example + * + * var hmac = CryptoJS.HmacMD5(message, key); + */ + C.HmacMD5 = Hasher._createHmacHelper(MD5); + }(Math)); + + + (function () { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var WordArray = C_lib.WordArray; + var Hasher = C_lib.Hasher; + var C_algo = C.algo; + + // Reusable object + var W = []; + + /** + * SHA-1 hash algorithm. + */ + var SHA1 = C_algo.SHA1 = Hasher.extend({ + _doReset: function () { + this._hash = new WordArray.init([ + 0x67452301, 0xefcdab89, + 0x98badcfe, 0x10325476, + 0xc3d2e1f0 + ]); + }, + + _doProcessBlock: function (M, offset) { + // Shortcut + var H = this._hash.words; + + // Working variables + var a = H[0]; + var b = H[1]; + var c = H[2]; + var d = H[3]; + var e = H[4]; + + // Computation + for (var i = 0; i < 80; i++) { + if (i < 16) { + W[i] = M[offset + i] | 0; + } else { + var n = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16]; + W[i] = (n << 1) | (n >>> 31); + } + + var t = ((a << 5) | (a >>> 27)) + e + W[i]; + if (i < 20) { + t += ((b & c) | (~b & d)) + 0x5a827999; + } else if (i < 40) { + t += (b ^ c ^ d) + 0x6ed9eba1; + } else if (i < 60) { + t += ((b & c) | (b & d) | (c & d)) - 0x70e44324; + } else /* if (i < 80) */ { + t += (b ^ c ^ d) - 0x359d3e2a; + } + + e = d; + d = c; + c = (b << 30) | (b >>> 2); + b = a; + a = t; + } + + // Intermediate hash value + H[0] = (H[0] + a) | 0; + H[1] = (H[1] + b) | 0; + H[2] = (H[2] + c) | 0; + H[3] = (H[3] + d) | 0; + H[4] = (H[4] + e) | 0; + }, + + _doFinalize: function () { + // Shortcuts + var data = this._data; + var dataWords = data.words; + + var nBitsTotal = this._nDataBytes * 8; + var nBitsLeft = data.sigBytes * 8; + + // Add padding + dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32); + dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = Math.floor(nBitsTotal / 0x100000000); + dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = nBitsTotal; + data.sigBytes = dataWords.length * 4; + + // Hash final blocks + this._process(); + + // Return final computed hash + return this._hash; + }, + + clone: function () { + var clone = Hasher.clone.call(this); + clone._hash = this._hash.clone(); + + return clone; + } + }); + + /** + * Shortcut function to the hasher's object interface. + * + * @param {WordArray|string} message The message to hash. + * + * @return {WordArray} The hash. + * + * @static + * + * @example + * + * var hash = CryptoJS.SHA1('message'); + * var hash = CryptoJS.SHA1(wordArray); + */ + C.SHA1 = Hasher._createHelper(SHA1); + + /** + * Shortcut function to the HMAC's object interface. + * + * @param {WordArray|string} message The message to hash. + * @param {WordArray|string} key The secret key. + * + * @return {WordArray} The HMAC. + * + * @static + * + * @example + * + * var hmac = CryptoJS.HmacSHA1(message, key); + */ + C.HmacSHA1 = Hasher._createHmacHelper(SHA1); + }()); + + + (function (Math) { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var WordArray = C_lib.WordArray; + var Hasher = C_lib.Hasher; + var C_algo = C.algo; + + // Initialization and round constants tables + var H = []; + var K = []; + + // Compute constants + (function () { + function isPrime(n) { + var sqrtN = Math.sqrt(n); + for (var factor = 2; factor <= sqrtN; factor++) { + if (!(n % factor)) { + return false; + } + } + + return true; + } + + function getFractionalBits(n) { + return ((n - (n | 0)) * 0x100000000) | 0; + } + + var n = 2; + var nPrime = 0; + while (nPrime < 64) { + if (isPrime(n)) { + if (nPrime < 8) { + H[nPrime] = getFractionalBits(Math.pow(n, 1 / 2)); + } + K[nPrime] = getFractionalBits(Math.pow(n, 1 / 3)); + + nPrime++; + } + + n++; + } + }()); + + // Reusable object + var W = []; + + /** + * SHA-256 hash algorithm. + */ + var SHA256 = C_algo.SHA256 = Hasher.extend({ + _doReset: function () { + this._hash = new WordArray.init(H.slice(0)); + }, + + _doProcessBlock: function (M, offset) { + // Shortcut + var H = this._hash.words; + + // Working variables + var a = H[0]; + var b = H[1]; + var c = H[2]; + var d = H[3]; + var e = H[4]; + var f = H[5]; + var g = H[6]; + var h = H[7]; + + // Computation + for (var i = 0; i < 64; i++) { + if (i < 16) { + W[i] = M[offset + i] | 0; + } else { + var gamma0x = W[i - 15]; + var gamma0 = ((gamma0x << 25) | (gamma0x >>> 7)) ^ + ((gamma0x << 14) | (gamma0x >>> 18)) ^ + (gamma0x >>> 3); + + var gamma1x = W[i - 2]; + var gamma1 = ((gamma1x << 15) | (gamma1x >>> 17)) ^ + ((gamma1x << 13) | (gamma1x >>> 19)) ^ + (gamma1x >>> 10); + + W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16]; + } + + var ch = (e & f) ^ (~e & g); + var maj = (a & b) ^ (a & c) ^ (b & c); + + var sigma0 = ((a << 30) | (a >>> 2)) ^ ((a << 19) | (a >>> 13)) ^ ((a << 10) | (a >>> 22)); + var sigma1 = ((e << 26) | (e >>> 6)) ^ ((e << 21) | (e >>> 11)) ^ ((e << 7) | (e >>> 25)); + + var t1 = h + sigma1 + ch + K[i] + W[i]; + var t2 = sigma0 + maj; + + h = g; + g = f; + f = e; + e = (d + t1) | 0; + d = c; + c = b; + b = a; + a = (t1 + t2) | 0; + } + + // Intermediate hash value + H[0] = (H[0] + a) | 0; + H[1] = (H[1] + b) | 0; + H[2] = (H[2] + c) | 0; + H[3] = (H[3] + d) | 0; + H[4] = (H[4] + e) | 0; + H[5] = (H[5] + f) | 0; + H[6] = (H[6] + g) | 0; + H[7] = (H[7] + h) | 0; + }, + + _doFinalize: function () { + // Shortcuts + var data = this._data; + var dataWords = data.words; + + var nBitsTotal = this._nDataBytes * 8; + var nBitsLeft = data.sigBytes * 8; + + // Add padding + dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32); + dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = Math.floor(nBitsTotal / 0x100000000); + dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = nBitsTotal; + data.sigBytes = dataWords.length * 4; + + // Hash final blocks + this._process(); + + // Return final computed hash + return this._hash; + }, + + clone: function () { + var clone = Hasher.clone.call(this); + clone._hash = this._hash.clone(); + + return clone; + } + }); + + /** + * Shortcut function to the hasher's object interface. + * + * @param {WordArray|string} message The message to hash. + * + * @return {WordArray} The hash. + * + * @static + * + * @example + * + * var hash = CryptoJS.SHA256('message'); + * var hash = CryptoJS.SHA256(wordArray); + */ + C.SHA256 = Hasher._createHelper(SHA256); + + /** + * Shortcut function to the HMAC's object interface. + * + * @param {WordArray|string} message The message to hash. + * @param {WordArray|string} key The secret key. + * + * @return {WordArray} The HMAC. + * + * @static + * + * @example + * + * var hmac = CryptoJS.HmacSHA256(message, key); + */ + C.HmacSHA256 = Hasher._createHmacHelper(SHA256); + }(Math)); + + + (function () { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var WordArray = C_lib.WordArray; + var C_algo = C.algo; + var SHA256 = C_algo.SHA256; + + /** + * SHA-224 hash algorithm. + */ + var SHA224 = C_algo.SHA224 = SHA256.extend({ + _doReset: function () { + this._hash = new WordArray.init([ + 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, + 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4 + ]); + }, + + _doFinalize: function () { + var hash = SHA256._doFinalize.call(this); + + hash.sigBytes -= 4; + + return hash; + } + }); + + /** + * Shortcut function to the hasher's object interface. + * + * @param {WordArray|string} message The message to hash. + * + * @return {WordArray} The hash. + * + * @static + * + * @example + * + * var hash = CryptoJS.SHA224('message'); + * var hash = CryptoJS.SHA224(wordArray); + */ + C.SHA224 = SHA256._createHelper(SHA224); + + /** + * Shortcut function to the HMAC's object interface. + * + * @param {WordArray|string} message The message to hash. + * @param {WordArray|string} key The secret key. + * + * @return {WordArray} The HMAC. + * + * @static + * + * @example + * + * var hmac = CryptoJS.HmacSHA224(message, key); + */ + C.HmacSHA224 = SHA256._createHmacHelper(SHA224); + }()); + + + (function () { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var Hasher = C_lib.Hasher; + var C_x64 = C.x64; + var X64Word = C_x64.Word; + var X64WordArray = C_x64.WordArray; + var C_algo = C.algo; + + function X64Word_create() { + return X64Word.create.apply(X64Word, arguments); + } + + // Constants + var K = [ + X64Word_create(0x428a2f98, 0xd728ae22), X64Word_create(0x71374491, 0x23ef65cd), + X64Word_create(0xb5c0fbcf, 0xec4d3b2f), X64Word_create(0xe9b5dba5, 0x8189dbbc), + X64Word_create(0x3956c25b, 0xf348b538), X64Word_create(0x59f111f1, 0xb605d019), + X64Word_create(0x923f82a4, 0xaf194f9b), X64Word_create(0xab1c5ed5, 0xda6d8118), + X64Word_create(0xd807aa98, 0xa3030242), X64Word_create(0x12835b01, 0x45706fbe), + X64Word_create(0x243185be, 0x4ee4b28c), X64Word_create(0x550c7dc3, 0xd5ffb4e2), + X64Word_create(0x72be5d74, 0xf27b896f), X64Word_create(0x80deb1fe, 0x3b1696b1), + X64Word_create(0x9bdc06a7, 0x25c71235), X64Word_create(0xc19bf174, 0xcf692694), + X64Word_create(0xe49b69c1, 0x9ef14ad2), X64Word_create(0xefbe4786, 0x384f25e3), + X64Word_create(0x0fc19dc6, 0x8b8cd5b5), X64Word_create(0x240ca1cc, 0x77ac9c65), + X64Word_create(0x2de92c6f, 0x592b0275), X64Word_create(0x4a7484aa, 0x6ea6e483), + X64Word_create(0x5cb0a9dc, 0xbd41fbd4), X64Word_create(0x76f988da, 0x831153b5), + X64Word_create(0x983e5152, 0xee66dfab), X64Word_create(0xa831c66d, 0x2db43210), + X64Word_create(0xb00327c8, 0x98fb213f), X64Word_create(0xbf597fc7, 0xbeef0ee4), + X64Word_create(0xc6e00bf3, 0x3da88fc2), X64Word_create(0xd5a79147, 0x930aa725), + X64Word_create(0x06ca6351, 0xe003826f), X64Word_create(0x14292967, 0x0a0e6e70), + X64Word_create(0x27b70a85, 0x46d22ffc), X64Word_create(0x2e1b2138, 0x5c26c926), + X64Word_create(0x4d2c6dfc, 0x5ac42aed), X64Word_create(0x53380d13, 0x9d95b3df), + X64Word_create(0x650a7354, 0x8baf63de), X64Word_create(0x766a0abb, 0x3c77b2a8), + X64Word_create(0x81c2c92e, 0x47edaee6), X64Word_create(0x92722c85, 0x1482353b), + X64Word_create(0xa2bfe8a1, 0x4cf10364), X64Word_create(0xa81a664b, 0xbc423001), + X64Word_create(0xc24b8b70, 0xd0f89791), X64Word_create(0xc76c51a3, 0x0654be30), + X64Word_create(0xd192e819, 0xd6ef5218), X64Word_create(0xd6990624, 0x5565a910), + X64Word_create(0xf40e3585, 0x5771202a), X64Word_create(0x106aa070, 0x32bbd1b8), + X64Word_create(0x19a4c116, 0xb8d2d0c8), X64Word_create(0x1e376c08, 0x5141ab53), + X64Word_create(0x2748774c, 0xdf8eeb99), X64Word_create(0x34b0bcb5, 0xe19b48a8), + X64Word_create(0x391c0cb3, 0xc5c95a63), X64Word_create(0x4ed8aa4a, 0xe3418acb), + X64Word_create(0x5b9cca4f, 0x7763e373), X64Word_create(0x682e6ff3, 0xd6b2b8a3), + X64Word_create(0x748f82ee, 0x5defb2fc), X64Word_create(0x78a5636f, 0x43172f60), + X64Word_create(0x84c87814, 0xa1f0ab72), X64Word_create(0x8cc70208, 0x1a6439ec), + X64Word_create(0x90befffa, 0x23631e28), X64Word_create(0xa4506ceb, 0xde82bde9), + X64Word_create(0xbef9a3f7, 0xb2c67915), X64Word_create(0xc67178f2, 0xe372532b), + X64Word_create(0xca273ece, 0xea26619c), X64Word_create(0xd186b8c7, 0x21c0c207), + X64Word_create(0xeada7dd6, 0xcde0eb1e), X64Word_create(0xf57d4f7f, 0xee6ed178), + X64Word_create(0x06f067aa, 0x72176fba), X64Word_create(0x0a637dc5, 0xa2c898a6), + X64Word_create(0x113f9804, 0xbef90dae), X64Word_create(0x1b710b35, 0x131c471b), + X64Word_create(0x28db77f5, 0x23047d84), X64Word_create(0x32caab7b, 0x40c72493), + X64Word_create(0x3c9ebe0a, 0x15c9bebc), X64Word_create(0x431d67c4, 0x9c100d4c), + X64Word_create(0x4cc5d4be, 0xcb3e42b6), X64Word_create(0x597f299c, 0xfc657e2a), + X64Word_create(0x5fcb6fab, 0x3ad6faec), X64Word_create(0x6c44198c, 0x4a475817) + ]; + + // Reusable objects + var W = []; + (function () { + for (var i = 0; i < 80; i++) { + W[i] = X64Word_create(); + } + }()); + + /** + * SHA-512 hash algorithm. + */ + var SHA512 = C_algo.SHA512 = Hasher.extend({ + _doReset: function () { + this._hash = new X64WordArray.init([ + new X64Word.init(0x6a09e667, 0xf3bcc908), new X64Word.init(0xbb67ae85, 0x84caa73b), + new X64Word.init(0x3c6ef372, 0xfe94f82b), new X64Word.init(0xa54ff53a, 0x5f1d36f1), + new X64Word.init(0x510e527f, 0xade682d1), new X64Word.init(0x9b05688c, 0x2b3e6c1f), + new X64Word.init(0x1f83d9ab, 0xfb41bd6b), new X64Word.init(0x5be0cd19, 0x137e2179) + ]); + }, + + _doProcessBlock: function (M, offset) { + // Shortcuts + var H = this._hash.words; + + var H0 = H[0]; + var H1 = H[1]; + var H2 = H[2]; + var H3 = H[3]; + var H4 = H[4]; + var H5 = H[5]; + var H6 = H[6]; + var H7 = H[7]; + + var H0h = H0.high; + var H0l = H0.low; + var H1h = H1.high; + var H1l = H1.low; + var H2h = H2.high; + var H2l = H2.low; + var H3h = H3.high; + var H3l = H3.low; + var H4h = H4.high; + var H4l = H4.low; + var H5h = H5.high; + var H5l = H5.low; + var H6h = H6.high; + var H6l = H6.low; + var H7h = H7.high; + var H7l = H7.low; + + // Working variables + var ah = H0h; + var al = H0l; + var bh = H1h; + var bl = H1l; + var ch = H2h; + var cl = H2l; + var dh = H3h; + var dl = H3l; + var eh = H4h; + var el = H4l; + var fh = H5h; + var fl = H5l; + var gh = H6h; + var gl = H6l; + var hh = H7h; + var hl = H7l; + + // Rounds + for (var i = 0; i < 80; i++) { + var Wil; + var Wih; + + // Shortcut + var Wi = W[i]; + + // Extend message + if (i < 16) { + Wih = Wi.high = M[offset + i * 2] | 0; + Wil = Wi.low = M[offset + i * 2 + 1] | 0; + } else { + // Gamma0 + var gamma0x = W[i - 15]; + var gamma0xh = gamma0x.high; + var gamma0xl = gamma0x.low; + var gamma0h = ((gamma0xh >>> 1) | (gamma0xl << 31)) ^ ((gamma0xh >>> 8) | (gamma0xl << 24)) ^ (gamma0xh >>> 7); + var gamma0l = ((gamma0xl >>> 1) | (gamma0xh << 31)) ^ ((gamma0xl >>> 8) | (gamma0xh << 24)) ^ ((gamma0xl >>> 7) | (gamma0xh << 25)); + + // Gamma1 + var gamma1x = W[i - 2]; + var gamma1xh = gamma1x.high; + var gamma1xl = gamma1x.low; + var gamma1h = ((gamma1xh >>> 19) | (gamma1xl << 13)) ^ ((gamma1xh << 3) | (gamma1xl >>> 29)) ^ (gamma1xh >>> 6); + var gamma1l = ((gamma1xl >>> 19) | (gamma1xh << 13)) ^ ((gamma1xl << 3) | (gamma1xh >>> 29)) ^ ((gamma1xl >>> 6) | (gamma1xh << 26)); + + // W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16] + var Wi7 = W[i - 7]; + var Wi7h = Wi7.high; + var Wi7l = Wi7.low; + + var Wi16 = W[i - 16]; + var Wi16h = Wi16.high; + var Wi16l = Wi16.low; + + Wil = gamma0l + Wi7l; + Wih = gamma0h + Wi7h + ((Wil >>> 0) < (gamma0l >>> 0) ? 1 : 0); + Wil = Wil + gamma1l; + Wih = Wih + gamma1h + ((Wil >>> 0) < (gamma1l >>> 0) ? 1 : 0); + Wil = Wil + Wi16l; + Wih = Wih + Wi16h + ((Wil >>> 0) < (Wi16l >>> 0) ? 1 : 0); + + Wi.high = Wih; + Wi.low = Wil; + } + + var chh = (eh & fh) ^ (~eh & gh); + var chl = (el & fl) ^ (~el & gl); + var majh = (ah & bh) ^ (ah & ch) ^ (bh & ch); + var majl = (al & bl) ^ (al & cl) ^ (bl & cl); + + var sigma0h = ((ah >>> 28) | (al << 4)) ^ ((ah << 30) | (al >>> 2)) ^ ((ah << 25) | (al >>> 7)); + var sigma0l = ((al >>> 28) | (ah << 4)) ^ ((al << 30) | (ah >>> 2)) ^ ((al << 25) | (ah >>> 7)); + var sigma1h = ((eh >>> 14) | (el << 18)) ^ ((eh >>> 18) | (el << 14)) ^ ((eh << 23) | (el >>> 9)); + var sigma1l = ((el >>> 14) | (eh << 18)) ^ ((el >>> 18) | (eh << 14)) ^ ((el << 23) | (eh >>> 9)); + + // t1 = h + sigma1 + ch + K[i] + W[i] + var Ki = K[i]; + var Kih = Ki.high; + var Kil = Ki.low; + + var t1l = hl + sigma1l; + var t1h = hh + sigma1h + ((t1l >>> 0) < (hl >>> 0) ? 1 : 0); + var t1l = t1l + chl; + var t1h = t1h + chh + ((t1l >>> 0) < (chl >>> 0) ? 1 : 0); + var t1l = t1l + Kil; + var t1h = t1h + Kih + ((t1l >>> 0) < (Kil >>> 0) ? 1 : 0); + var t1l = t1l + Wil; + var t1h = t1h + Wih + ((t1l >>> 0) < (Wil >>> 0) ? 1 : 0); + + // t2 = sigma0 + maj + var t2l = sigma0l + majl; + var t2h = sigma0h + majh + ((t2l >>> 0) < (sigma0l >>> 0) ? 1 : 0); + + // Update working variables + hh = gh; + hl = gl; + gh = fh; + gl = fl; + fh = eh; + fl = el; + el = (dl + t1l) | 0; + eh = (dh + t1h + ((el >>> 0) < (dl >>> 0) ? 1 : 0)) | 0; + dh = ch; + dl = cl; + ch = bh; + cl = bl; + bh = ah; + bl = al; + al = (t1l + t2l) | 0; + ah = (t1h + t2h + ((al >>> 0) < (t1l >>> 0) ? 1 : 0)) | 0; + } + + // Intermediate hash value + H0l = H0.low = (H0l + al); + H0.high = (H0h + ah + ((H0l >>> 0) < (al >>> 0) ? 1 : 0)); + H1l = H1.low = (H1l + bl); + H1.high = (H1h + bh + ((H1l >>> 0) < (bl >>> 0) ? 1 : 0)); + H2l = H2.low = (H2l + cl); + H2.high = (H2h + ch + ((H2l >>> 0) < (cl >>> 0) ? 1 : 0)); + H3l = H3.low = (H3l + dl); + H3.high = (H3h + dh + ((H3l >>> 0) < (dl >>> 0) ? 1 : 0)); + H4l = H4.low = (H4l + el); + H4.high = (H4h + eh + ((H4l >>> 0) < (el >>> 0) ? 1 : 0)); + H5l = H5.low = (H5l + fl); + H5.high = (H5h + fh + ((H5l >>> 0) < (fl >>> 0) ? 1 : 0)); + H6l = H6.low = (H6l + gl); + H6.high = (H6h + gh + ((H6l >>> 0) < (gl >>> 0) ? 1 : 0)); + H7l = H7.low = (H7l + hl); + H7.high = (H7h + hh + ((H7l >>> 0) < (hl >>> 0) ? 1 : 0)); + }, + + _doFinalize: function () { + // Shortcuts + var data = this._data; + var dataWords = data.words; + + var nBitsTotal = this._nDataBytes * 8; + var nBitsLeft = data.sigBytes * 8; + + // Add padding + dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32); + dataWords[(((nBitsLeft + 128) >>> 10) << 5) + 30] = Math.floor(nBitsTotal / 0x100000000); + dataWords[(((nBitsLeft + 128) >>> 10) << 5) + 31] = nBitsTotal; + data.sigBytes = dataWords.length * 4; + + // Hash final blocks + this._process(); + + // Convert hash to 32-bit word array before returning + var hash = this._hash.toX32(); + + // Return final computed hash + return hash; + }, + + clone: function () { + var clone = Hasher.clone.call(this); + clone._hash = this._hash.clone(); + + return clone; + }, + + blockSize: 1024/32 + }); + + /** + * Shortcut function to the hasher's object interface. + * + * @param {WordArray|string} message The message to hash. + * + * @return {WordArray} The hash. + * + * @static + * + * @example + * + * var hash = CryptoJS.SHA512('message'); + * var hash = CryptoJS.SHA512(wordArray); + */ + C.SHA512 = Hasher._createHelper(SHA512); + + /** + * Shortcut function to the HMAC's object interface. + * + * @param {WordArray|string} message The message to hash. + * @param {WordArray|string} key The secret key. + * + * @return {WordArray} The HMAC. + * + * @static + * + * @example + * + * var hmac = CryptoJS.HmacSHA512(message, key); + */ + C.HmacSHA512 = Hasher._createHmacHelper(SHA512); + }()); + + + (function () { + // Shortcuts + var C = CryptoJS; + var C_x64 = C.x64; + var X64Word = C_x64.Word; + var X64WordArray = C_x64.WordArray; + var C_algo = C.algo; + var SHA512 = C_algo.SHA512; + + /** + * SHA-384 hash algorithm. + */ + var SHA384 = C_algo.SHA384 = SHA512.extend({ + _doReset: function () { + this._hash = new X64WordArray.init([ + new X64Word.init(0xcbbb9d5d, 0xc1059ed8), new X64Word.init(0x629a292a, 0x367cd507), + new X64Word.init(0x9159015a, 0x3070dd17), new X64Word.init(0x152fecd8, 0xf70e5939), + new X64Word.init(0x67332667, 0xffc00b31), new X64Word.init(0x8eb44a87, 0x68581511), + new X64Word.init(0xdb0c2e0d, 0x64f98fa7), new X64Word.init(0x47b5481d, 0xbefa4fa4) + ]); + }, + + _doFinalize: function () { + var hash = SHA512._doFinalize.call(this); + + hash.sigBytes -= 16; + + return hash; + } + }); + + /** + * Shortcut function to the hasher's object interface. + * + * @param {WordArray|string} message The message to hash. + * + * @return {WordArray} The hash. + * + * @static + * + * @example + * + * var hash = CryptoJS.SHA384('message'); + * var hash = CryptoJS.SHA384(wordArray); + */ + C.SHA384 = SHA512._createHelper(SHA384); + + /** + * Shortcut function to the HMAC's object interface. + * + * @param {WordArray|string} message The message to hash. + * @param {WordArray|string} key The secret key. + * + * @return {WordArray} The HMAC. + * + * @static + * + * @example + * + * var hmac = CryptoJS.HmacSHA384(message, key); + */ + C.HmacSHA384 = SHA512._createHmacHelper(SHA384); + }()); + + + (function (Math) { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var WordArray = C_lib.WordArray; + var Hasher = C_lib.Hasher; + var C_x64 = C.x64; + var X64Word = C_x64.Word; + var C_algo = C.algo; + + // Constants tables + var RHO_OFFSETS = []; + var PI_INDEXES = []; + var ROUND_CONSTANTS = []; + + // Compute Constants + (function () { + // Compute rho offset constants + var x = 1, y = 0; + for (var t = 0; t < 24; t++) { + RHO_OFFSETS[x + 5 * y] = ((t + 1) * (t + 2) / 2) % 64; + + var newX = y % 5; + var newY = (2 * x + 3 * y) % 5; + x = newX; + y = newY; + } + + // Compute pi index constants + for (var x = 0; x < 5; x++) { + for (var y = 0; y < 5; y++) { + PI_INDEXES[x + 5 * y] = y + ((2 * x + 3 * y) % 5) * 5; + } + } + + // Compute round constants + var LFSR = 0x01; + for (var i = 0; i < 24; i++) { + var roundConstantMsw = 0; + var roundConstantLsw = 0; + + for (var j = 0; j < 7; j++) { + if (LFSR & 0x01) { + var bitPosition = (1 << j) - 1; + if (bitPosition < 32) { + roundConstantLsw ^= 1 << bitPosition; + } else /* if (bitPosition >= 32) */ { + roundConstantMsw ^= 1 << (bitPosition - 32); + } + } + + // Compute next LFSR + if (LFSR & 0x80) { + // Primitive polynomial over GF(2): x^8 + x^6 + x^5 + x^4 + 1 + LFSR = (LFSR << 1) ^ 0x71; + } else { + LFSR <<= 1; + } + } + + ROUND_CONSTANTS[i] = X64Word.create(roundConstantMsw, roundConstantLsw); + } + }()); + + // Reusable objects for temporary values + var T = []; + (function () { + for (var i = 0; i < 25; i++) { + T[i] = X64Word.create(); + } + }()); + + /** + * SHA-3 hash algorithm. + */ + var SHA3 = C_algo.SHA3 = Hasher.extend({ + /** + * Configuration options. + * + * @property {number} outputLength + * The desired number of bits in the output hash. + * Only values permitted are: 224, 256, 384, 512. + * Default: 512 + */ + cfg: Hasher.cfg.extend({ + outputLength: 512 + }), + + _doReset: function () { + var state = this._state = [] + for (var i = 0; i < 25; i++) { + state[i] = new X64Word.init(); + } + + this.blockSize = (1600 - 2 * this.cfg.outputLength) / 32; + }, + + _doProcessBlock: function (M, offset) { + // Shortcuts + var state = this._state; + var nBlockSizeLanes = this.blockSize / 2; + + // Absorb + for (var i = 0; i < nBlockSizeLanes; i++) { + // Shortcuts + var M2i = M[offset + 2 * i]; + var M2i1 = M[offset + 2 * i + 1]; + + // Swap endian + M2i = ( + (((M2i << 8) | (M2i >>> 24)) & 0x00ff00ff) | + (((M2i << 24) | (M2i >>> 8)) & 0xff00ff00) + ); + M2i1 = ( + (((M2i1 << 8) | (M2i1 >>> 24)) & 0x00ff00ff) | + (((M2i1 << 24) | (M2i1 >>> 8)) & 0xff00ff00) + ); + + // Absorb message into state + var lane = state[i]; + lane.high ^= M2i1; + lane.low ^= M2i; + } + + // Rounds + for (var round = 0; round < 24; round++) { + // Theta + for (var x = 0; x < 5; x++) { + // Mix column lanes + var tMsw = 0, tLsw = 0; + for (var y = 0; y < 5; y++) { + var lane = state[x + 5 * y]; + tMsw ^= lane.high; + tLsw ^= lane.low; + } + + // Temporary values + var Tx = T[x]; + Tx.high = tMsw; + Tx.low = tLsw; + } + for (var x = 0; x < 5; x++) { + // Shortcuts + var Tx4 = T[(x + 4) % 5]; + var Tx1 = T[(x + 1) % 5]; + var Tx1Msw = Tx1.high; + var Tx1Lsw = Tx1.low; + + // Mix surrounding columns + var tMsw = Tx4.high ^ ((Tx1Msw << 1) | (Tx1Lsw >>> 31)); + var tLsw = Tx4.low ^ ((Tx1Lsw << 1) | (Tx1Msw >>> 31)); + for (var y = 0; y < 5; y++) { + var lane = state[x + 5 * y]; + lane.high ^= tMsw; + lane.low ^= tLsw; + } + } + + // Rho Pi + for (var laneIndex = 1; laneIndex < 25; laneIndex++) { + var tMsw; + var tLsw; + + // Shortcuts + var lane = state[laneIndex]; + var laneMsw = lane.high; + var laneLsw = lane.low; + var rhoOffset = RHO_OFFSETS[laneIndex]; + + // Rotate lanes + if (rhoOffset < 32) { + tMsw = (laneMsw << rhoOffset) | (laneLsw >>> (32 - rhoOffset)); + tLsw = (laneLsw << rhoOffset) | (laneMsw >>> (32 - rhoOffset)); + } else /* if (rhoOffset >= 32) */ { + tMsw = (laneLsw << (rhoOffset - 32)) | (laneMsw >>> (64 - rhoOffset)); + tLsw = (laneMsw << (rhoOffset - 32)) | (laneLsw >>> (64 - rhoOffset)); + } + + // Transpose lanes + var TPiLane = T[PI_INDEXES[laneIndex]]; + TPiLane.high = tMsw; + TPiLane.low = tLsw; + } + + // Rho pi at x = y = 0 + var T0 = T[0]; + var state0 = state[0]; + T0.high = state0.high; + T0.low = state0.low; + + // Chi + for (var x = 0; x < 5; x++) { + for (var y = 0; y < 5; y++) { + // Shortcuts + var laneIndex = x + 5 * y; + var lane = state[laneIndex]; + var TLane = T[laneIndex]; + var Tx1Lane = T[((x + 1) % 5) + 5 * y]; + var Tx2Lane = T[((x + 2) % 5) + 5 * y]; + + // Mix rows + lane.high = TLane.high ^ (~Tx1Lane.high & Tx2Lane.high); + lane.low = TLane.low ^ (~Tx1Lane.low & Tx2Lane.low); + } + } + + // Iota + var lane = state[0]; + var roundConstant = ROUND_CONSTANTS[round]; + lane.high ^= roundConstant.high; + lane.low ^= roundConstant.low; + } + }, + + _doFinalize: function () { + // Shortcuts + var data = this._data; + var dataWords = data.words; + var nBitsTotal = this._nDataBytes * 8; + var nBitsLeft = data.sigBytes * 8; + var blockSizeBits = this.blockSize * 32; + + // Add padding + dataWords[nBitsLeft >>> 5] |= 0x1 << (24 - nBitsLeft % 32); + dataWords[((Math.ceil((nBitsLeft + 1) / blockSizeBits) * blockSizeBits) >>> 5) - 1] |= 0x80; + data.sigBytes = dataWords.length * 4; + + // Hash final blocks + this._process(); + + // Shortcuts + var state = this._state; + var outputLengthBytes = this.cfg.outputLength / 8; + var outputLengthLanes = outputLengthBytes / 8; + + // Squeeze + var hashWords = []; + for (var i = 0; i < outputLengthLanes; i++) { + // Shortcuts + var lane = state[i]; + var laneMsw = lane.high; + var laneLsw = lane.low; + + // Swap endian + laneMsw = ( + (((laneMsw << 8) | (laneMsw >>> 24)) & 0x00ff00ff) | + (((laneMsw << 24) | (laneMsw >>> 8)) & 0xff00ff00) + ); + laneLsw = ( + (((laneLsw << 8) | (laneLsw >>> 24)) & 0x00ff00ff) | + (((laneLsw << 24) | (laneLsw >>> 8)) & 0xff00ff00) + ); + + // Squeeze state to retrieve hash + hashWords.push(laneLsw); + hashWords.push(laneMsw); + } + + // Return final computed hash + return new WordArray.init(hashWords, outputLengthBytes); + }, + + clone: function () { + var clone = Hasher.clone.call(this); + + var state = clone._state = this._state.slice(0); + for (var i = 0; i < 25; i++) { + state[i] = state[i].clone(); + } + + return clone; + } + }); + + /** + * Shortcut function to the hasher's object interface. + * + * @param {WordArray|string} message The message to hash. + * + * @return {WordArray} The hash. + * + * @static + * + * @example + * + * var hash = CryptoJS.SHA3('message'); + * var hash = CryptoJS.SHA3(wordArray); + */ + C.SHA3 = Hasher._createHelper(SHA3); + + /** + * Shortcut function to the HMAC's object interface. + * + * @param {WordArray|string} message The message to hash. + * @param {WordArray|string} key The secret key. + * + * @return {WordArray} The HMAC. + * + * @static + * + * @example + * + * var hmac = CryptoJS.HmacSHA3(message, key); + */ + C.HmacSHA3 = Hasher._createHmacHelper(SHA3); + }(Math)); + + + /** @preserve + (c) 2012 by Cédric Mesnil. All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + (function (Math) { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var WordArray = C_lib.WordArray; + var Hasher = C_lib.Hasher; + var C_algo = C.algo; + + // Constants table + var _zl = WordArray.create([ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, + 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12, + 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2, + 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13]); + var _zr = WordArray.create([ + 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, + 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2, + 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13, + 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14, + 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11]); + var _sl = WordArray.create([ + 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8, + 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12, + 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5, + 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12, + 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6 ]); + var _sr = WordArray.create([ + 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6, + 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11, + 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5, + 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8, + 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11 ]); + + var _hl = WordArray.create([ 0x00000000, 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xA953FD4E]); + var _hr = WordArray.create([ 0x50A28BE6, 0x5C4DD124, 0x6D703EF3, 0x7A6D76E9, 0x00000000]); + + /** + * RIPEMD160 hash algorithm. + */ + var RIPEMD160 = C_algo.RIPEMD160 = Hasher.extend({ + _doReset: function () { + this._hash = WordArray.create([0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0]); + }, + + _doProcessBlock: function (M, offset) { + + // Swap endian + for (var i = 0; i < 16; i++) { + // Shortcuts + var offset_i = offset + i; + var M_offset_i = M[offset_i]; + + // Swap + M[offset_i] = ( + (((M_offset_i << 8) | (M_offset_i >>> 24)) & 0x00ff00ff) | + (((M_offset_i << 24) | (M_offset_i >>> 8)) & 0xff00ff00) + ); + } + // Shortcut + var H = this._hash.words; + var hl = _hl.words; + var hr = _hr.words; + var zl = _zl.words; + var zr = _zr.words; + var sl = _sl.words; + var sr = _sr.words; + + // Working variables + var al, bl, cl, dl, el; + var ar, br, cr, dr, er; + + ar = al = H[0]; + br = bl = H[1]; + cr = cl = H[2]; + dr = dl = H[3]; + er = el = H[4]; + // Computation + var t; + for (var i = 0; i < 80; i += 1) { + t = (al + M[offset+zl[i]])|0; + if (i<16){ + t += f1(bl,cl,dl) + hl[0]; + } else if (i<32) { + t += f2(bl,cl,dl) + hl[1]; + } else if (i<48) { + t += f3(bl,cl,dl) + hl[2]; + } else if (i<64) { + t += f4(bl,cl,dl) + hl[3]; + } else {// if (i<80) { + t += f5(bl,cl,dl) + hl[4]; + } + t = t|0; + t = rotl(t,sl[i]); + t = (t+el)|0; + al = el; + el = dl; + dl = rotl(cl, 10); + cl = bl; + bl = t; + + t = (ar + M[offset+zr[i]])|0; + if (i<16){ + t += f5(br,cr,dr) + hr[0]; + } else if (i<32) { + t += f4(br,cr,dr) + hr[1]; + } else if (i<48) { + t += f3(br,cr,dr) + hr[2]; + } else if (i<64) { + t += f2(br,cr,dr) + hr[3]; + } else {// if (i<80) { + t += f1(br,cr,dr) + hr[4]; + } + t = t|0; + t = rotl(t,sr[i]) ; + t = (t+er)|0; + ar = er; + er = dr; + dr = rotl(cr, 10); + cr = br; + br = t; + } + // Intermediate hash value + t = (H[1] + cl + dr)|0; + H[1] = (H[2] + dl + er)|0; + H[2] = (H[3] + el + ar)|0; + H[3] = (H[4] + al + br)|0; + H[4] = (H[0] + bl + cr)|0; + H[0] = t; + }, + + _doFinalize: function () { + // Shortcuts + var data = this._data; + var dataWords = data.words; + + var nBitsTotal = this._nDataBytes * 8; + var nBitsLeft = data.sigBytes * 8; + + // Add padding + dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32); + dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = ( + (((nBitsTotal << 8) | (nBitsTotal >>> 24)) & 0x00ff00ff) | + (((nBitsTotal << 24) | (nBitsTotal >>> 8)) & 0xff00ff00) + ); + data.sigBytes = (dataWords.length + 1) * 4; + + // Hash final blocks + this._process(); + + // Shortcuts + var hash = this._hash; + var H = hash.words; + + // Swap endian + for (var i = 0; i < 5; i++) { + // Shortcut + var H_i = H[i]; + + // Swap + H[i] = (((H_i << 8) | (H_i >>> 24)) & 0x00ff00ff) | + (((H_i << 24) | (H_i >>> 8)) & 0xff00ff00); + } + + // Return final computed hash + return hash; + }, + + clone: function () { + var clone = Hasher.clone.call(this); + clone._hash = this._hash.clone(); + + return clone; + } + }); + + + function f1(x, y, z) { + return ((x) ^ (y) ^ (z)); + + } + + function f2(x, y, z) { + return (((x)&(y)) | ((~x)&(z))); + } + + function f3(x, y, z) { + return (((x) | (~(y))) ^ (z)); + } + + function f4(x, y, z) { + return (((x) & (z)) | ((y)&(~(z)))); + } + + function f5(x, y, z) { + return ((x) ^ ((y) |(~(z)))); + + } + + function rotl(x,n) { + return (x<>>(32-n)); + } + + + /** + * Shortcut function to the hasher's object interface. + * + * @param {WordArray|string} message The message to hash. + * + * @return {WordArray} The hash. + * + * @static + * + * @example + * + * var hash = CryptoJS.RIPEMD160('message'); + * var hash = CryptoJS.RIPEMD160(wordArray); + */ + C.RIPEMD160 = Hasher._createHelper(RIPEMD160); + + /** + * Shortcut function to the HMAC's object interface. + * + * @param {WordArray|string} message The message to hash. + * @param {WordArray|string} key The secret key. + * + * @return {WordArray} The HMAC. + * + * @static + * + * @example + * + * var hmac = CryptoJS.HmacRIPEMD160(message, key); + */ + C.HmacRIPEMD160 = Hasher._createHmacHelper(RIPEMD160); + }(Math)); + + + (function () { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var Base = C_lib.Base; + var C_enc = C.enc; + var Utf8 = C_enc.Utf8; + var C_algo = C.algo; + + /** + * HMAC algorithm. + */ + var HMAC = C_algo.HMAC = Base.extend({ + /** + * Initializes a newly created HMAC. + * + * @param {Hasher} hasher The hash algorithm to use. + * @param {WordArray|string} key The secret key. + * + * @example + * + * var hmacHasher = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA256, key); + */ + init: function (hasher, key) { + // Init hasher + hasher = this._hasher = new hasher.init(); + + // Convert string to WordArray, else assume WordArray already + if (typeof key == 'string') { + key = Utf8.parse(key); + } + + // Shortcuts + var hasherBlockSize = hasher.blockSize; + var hasherBlockSizeBytes = hasherBlockSize * 4; + + // Allow arbitrary length keys + if (key.sigBytes > hasherBlockSizeBytes) { + key = hasher.finalize(key); + } + + // Clamp excess bits + key.clamp(); + + // Clone key for inner and outer pads + var oKey = this._oKey = key.clone(); + var iKey = this._iKey = key.clone(); + + // Shortcuts + var oKeyWords = oKey.words; + var iKeyWords = iKey.words; + + // XOR keys with pad constants + for (var i = 0; i < hasherBlockSize; i++) { + oKeyWords[i] ^= 0x5c5c5c5c; + iKeyWords[i] ^= 0x36363636; + } + oKey.sigBytes = iKey.sigBytes = hasherBlockSizeBytes; + + // Set initial values + this.reset(); + }, + + /** + * Resets this HMAC to its initial state. + * + * @example + * + * hmacHasher.reset(); + */ + reset: function () { + // Shortcut + var hasher = this._hasher; + + // Reset + hasher.reset(); + hasher.update(this._iKey); + }, + + /** + * Updates this HMAC with a message. + * + * @param {WordArray|string} messageUpdate The message to append. + * + * @return {HMAC} This HMAC instance. + * + * @example + * + * hmacHasher.update('message'); + * hmacHasher.update(wordArray); + */ + update: function (messageUpdate) { + this._hasher.update(messageUpdate); + + // Chainable + return this; + }, + + /** + * Finalizes the HMAC computation. + * Note that the finalize operation is effectively a destructive, read-once operation. + * + * @param {WordArray|string} messageUpdate (Optional) A final message update. + * + * @return {WordArray} The HMAC. + * + * @example + * + * var hmac = hmacHasher.finalize(); + * var hmac = hmacHasher.finalize('message'); + * var hmac = hmacHasher.finalize(wordArray); + */ + finalize: function (messageUpdate) { + // Shortcut + var hasher = this._hasher; + + // Compute HMAC + var innerHash = hasher.finalize(messageUpdate); + hasher.reset(); + var hmac = hasher.finalize(this._oKey.clone().concat(innerHash)); + + return hmac; + } + }); + }()); + + + (function () { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var Base = C_lib.Base; + var WordArray = C_lib.WordArray; + var C_algo = C.algo; + var SHA256 = C_algo.SHA256; + var HMAC = C_algo.HMAC; + + /** + * Password-Based Key Derivation Function 2 algorithm. + */ + var PBKDF2 = C_algo.PBKDF2 = Base.extend({ + /** + * Configuration options. + * + * @property {number} keySize The key size in words to generate. Default: 4 (128 bits) + * @property {Hasher} hasher The hasher to use. Default: SHA256 + * @property {number} iterations The number of iterations to perform. Default: 250000 + */ + cfg: Base.extend({ + keySize: 128/32, + hasher: SHA256, + iterations: 250000 + }), + + /** + * Initializes a newly created key derivation function. + * + * @param {Object} cfg (Optional) The configuration options to use for the derivation. + * + * @example + * + * var kdf = CryptoJS.algo.PBKDF2.create(); + * var kdf = CryptoJS.algo.PBKDF2.create({ keySize: 8 }); + * var kdf = CryptoJS.algo.PBKDF2.create({ keySize: 8, iterations: 1000 }); + */ + init: function (cfg) { + this.cfg = this.cfg.extend(cfg); + }, + + /** + * Computes the Password-Based Key Derivation Function 2. + * + * @param {WordArray|string} password The password. + * @param {WordArray|string} salt A salt. + * + * @return {WordArray} The derived key. + * + * @example + * + * var key = kdf.compute(password, salt); + */ + compute: function (password, salt) { + // Shortcut + var cfg = this.cfg; + + // Init HMAC + var hmac = HMAC.create(cfg.hasher, password); + + // Initial values + var derivedKey = WordArray.create(); + var blockIndex = WordArray.create([0x00000001]); + + // Shortcuts + var derivedKeyWords = derivedKey.words; + var blockIndexWords = blockIndex.words; + var keySize = cfg.keySize; + var iterations = cfg.iterations; + + // Generate key + while (derivedKeyWords.length < keySize) { + var block = hmac.update(salt).finalize(blockIndex); + hmac.reset(); + + // Shortcuts + var blockWords = block.words; + var blockWordsLength = blockWords.length; + + // Iterations + var intermediate = block; + for (var i = 1; i < iterations; i++) { + intermediate = hmac.finalize(intermediate); + hmac.reset(); + + // Shortcut + var intermediateWords = intermediate.words; + + // XOR intermediate with block + for (var j = 0; j < blockWordsLength; j++) { + blockWords[j] ^= intermediateWords[j]; + } + } + + derivedKey.concat(block); + blockIndexWords[0]++; + } + derivedKey.sigBytes = keySize * 4; + + return derivedKey; + } + }); + + /** + * Computes the Password-Based Key Derivation Function 2. + * + * @param {WordArray|string} password The password. + * @param {WordArray|string} salt A salt. + * @param {Object} cfg (Optional) The configuration options to use for this computation. + * + * @return {WordArray} The derived key. + * + * @static + * + * @example + * + * var key = CryptoJS.PBKDF2(password, salt); + * var key = CryptoJS.PBKDF2(password, salt, { keySize: 8 }); + * var key = CryptoJS.PBKDF2(password, salt, { keySize: 8, iterations: 1000 }); + */ + C.PBKDF2 = function (password, salt, cfg) { + return PBKDF2.create(cfg).compute(password, salt); + }; + }()); + + + (function () { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var Base = C_lib.Base; + var WordArray = C_lib.WordArray; + var C_algo = C.algo; + var MD5 = C_algo.MD5; + + /** + * This key derivation function is meant to conform with EVP_BytesToKey. + * www.openssl.org/docs/crypto/EVP_BytesToKey.html + */ + var EvpKDF = C_algo.EvpKDF = Base.extend({ + /** + * Configuration options. + * + * @property {number} keySize The key size in words to generate. Default: 4 (128 bits) + * @property {Hasher} hasher The hash algorithm to use. Default: MD5 + * @property {number} iterations The number of iterations to perform. Default: 1 + */ + cfg: Base.extend({ + keySize: 128/32, + hasher: MD5, + iterations: 1 + }), + + /** + * Initializes a newly created key derivation function. + * + * @param {Object} cfg (Optional) The configuration options to use for the derivation. + * + * @example + * + * var kdf = CryptoJS.algo.EvpKDF.create(); + * var kdf = CryptoJS.algo.EvpKDF.create({ keySize: 8 }); + * var kdf = CryptoJS.algo.EvpKDF.create({ keySize: 8, iterations: 1000 }); + */ + init: function (cfg) { + this.cfg = this.cfg.extend(cfg); + }, + + /** + * Derives a key from a password. + * + * @param {WordArray|string} password The password. + * @param {WordArray|string} salt A salt. + * + * @return {WordArray} The derived key. + * + * @example + * + * var key = kdf.compute(password, salt); + */ + compute: function (password, salt) { + var block; + + // Shortcut + var cfg = this.cfg; + + // Init hasher + var hasher = cfg.hasher.create(); + + // Initial values + var derivedKey = WordArray.create(); + + // Shortcuts + var derivedKeyWords = derivedKey.words; + var keySize = cfg.keySize; + var iterations = cfg.iterations; + + // Generate key + while (derivedKeyWords.length < keySize) { + if (block) { + hasher.update(block); + } + block = hasher.update(password).finalize(salt); + hasher.reset(); + + // Iterations + for (var i = 1; i < iterations; i++) { + block = hasher.finalize(block); + hasher.reset(); + } + + derivedKey.concat(block); + } + derivedKey.sigBytes = keySize * 4; + + return derivedKey; + } + }); + + /** + * Derives a key from a password. + * + * @param {WordArray|string} password The password. + * @param {WordArray|string} salt A salt. + * @param {Object} cfg (Optional) The configuration options to use for this computation. + * + * @return {WordArray} The derived key. + * + * @static + * + * @example + * + * var key = CryptoJS.EvpKDF(password, salt); + * var key = CryptoJS.EvpKDF(password, salt, { keySize: 8 }); + * var key = CryptoJS.EvpKDF(password, salt, { keySize: 8, iterations: 1000 }); + */ + C.EvpKDF = function (password, salt, cfg) { + return EvpKDF.create(cfg).compute(password, salt); + }; + }()); + + + /** + * Cipher core components. + */ + CryptoJS.lib.Cipher || (function (undefined) { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var Base = C_lib.Base; + var WordArray = C_lib.WordArray; + var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm; + var C_enc = C.enc; + var Utf8 = C_enc.Utf8; + var Base64 = C_enc.Base64; + var C_algo = C.algo; + var EvpKDF = C_algo.EvpKDF; + + /** + * Abstract base cipher template. + * + * @property {number} keySize This cipher's key size. Default: 4 (128 bits) + * @property {number} ivSize This cipher's IV size. Default: 4 (128 bits) + * @property {number} _ENC_XFORM_MODE A constant representing encryption mode. + * @property {number} _DEC_XFORM_MODE A constant representing decryption mode. + */ + var Cipher = C_lib.Cipher = BufferedBlockAlgorithm.extend({ + /** + * Configuration options. + * + * @property {WordArray} iv The IV to use for this operation. + */ + cfg: Base.extend(), + + /** + * Creates this cipher in encryption mode. + * + * @param {WordArray} key The key. + * @param {Object} cfg (Optional) The configuration options to use for this operation. + * + * @return {Cipher} A cipher instance. + * + * @static + * + * @example + * + * var cipher = CryptoJS.algo.AES.createEncryptor(keyWordArray, { iv: ivWordArray }); + */ + createEncryptor: function (key, cfg) { + return this.create(this._ENC_XFORM_MODE, key, cfg); + }, + + /** + * Creates this cipher in decryption mode. + * + * @param {WordArray} key The key. + * @param {Object} cfg (Optional) The configuration options to use for this operation. + * + * @return {Cipher} A cipher instance. + * + * @static + * + * @example + * + * var cipher = CryptoJS.algo.AES.createDecryptor(keyWordArray, { iv: ivWordArray }); + */ + createDecryptor: function (key, cfg) { + return this.create(this._DEC_XFORM_MODE, key, cfg); + }, + + /** + * Initializes a newly created cipher. + * + * @param {number} xformMode Either the encryption or decryption transormation mode constant. + * @param {WordArray} key The key. + * @param {Object} cfg (Optional) The configuration options to use for this operation. + * + * @example + * + * var cipher = CryptoJS.algo.AES.create(CryptoJS.algo.AES._ENC_XFORM_MODE, keyWordArray, { iv: ivWordArray }); + */ + init: function (xformMode, key, cfg) { + // Apply config defaults + this.cfg = this.cfg.extend(cfg); + + // Store transform mode and key + this._xformMode = xformMode; + this._key = key; + + // Set initial values + this.reset(); + }, + + /** + * Resets this cipher to its initial state. + * + * @example + * + * cipher.reset(); + */ + reset: function () { + // Reset data buffer + BufferedBlockAlgorithm.reset.call(this); + + // Perform concrete-cipher logic + this._doReset(); + }, + + /** + * Adds data to be encrypted or decrypted. + * + * @param {WordArray|string} dataUpdate The data to encrypt or decrypt. + * + * @return {WordArray} The data after processing. + * + * @example + * + * var encrypted = cipher.process('data'); + * var encrypted = cipher.process(wordArray); + */ + process: function (dataUpdate) { + // Append + this._append(dataUpdate); + + // Process available blocks + return this._process(); + }, + + /** + * Finalizes the encryption or decryption process. + * Note that the finalize operation is effectively a destructive, read-once operation. + * + * @param {WordArray|string} dataUpdate The final data to encrypt or decrypt. + * + * @return {WordArray} The data after final processing. + * + * @example + * + * var encrypted = cipher.finalize(); + * var encrypted = cipher.finalize('data'); + * var encrypted = cipher.finalize(wordArray); + */ + finalize: function (dataUpdate) { + // Final data update + if (dataUpdate) { + this._append(dataUpdate); + } + + // Perform concrete-cipher logic + var finalProcessedData = this._doFinalize(); + + return finalProcessedData; + }, + + keySize: 128/32, + + ivSize: 128/32, + + _ENC_XFORM_MODE: 1, + + _DEC_XFORM_MODE: 2, + + /** + * Creates shortcut functions to a cipher's object interface. + * + * @param {Cipher} cipher The cipher to create a helper for. + * + * @return {Object} An object with encrypt and decrypt shortcut functions. + * + * @static + * + * @example + * + * var AES = CryptoJS.lib.Cipher._createHelper(CryptoJS.algo.AES); + */ + _createHelper: (function () { + function selectCipherStrategy(key) { + if (typeof key == 'string') { + return PasswordBasedCipher; + } else { + return SerializableCipher; + } + } + + return function (cipher) { + return { + encrypt: function (message, key, cfg) { + return selectCipherStrategy(key).encrypt(cipher, message, key, cfg); + }, + + decrypt: function (ciphertext, key, cfg) { + return selectCipherStrategy(key).decrypt(cipher, ciphertext, key, cfg); + } + }; + }; + }()) + }); + + /** + * Abstract base stream cipher template. + * + * @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 1 (32 bits) + */ + var StreamCipher = C_lib.StreamCipher = Cipher.extend({ + _doFinalize: function () { + // Process partial blocks + var finalProcessedBlocks = this._process(!!'flush'); + + return finalProcessedBlocks; + }, + + blockSize: 1 + }); + + /** + * Mode namespace. + */ + var C_mode = C.mode = {}; + + /** + * Abstract base block cipher mode template. + */ + var BlockCipherMode = C_lib.BlockCipherMode = Base.extend({ + /** + * Creates this mode for encryption. + * + * @param {Cipher} cipher A block cipher instance. + * @param {Array} iv The IV words. + * + * @static + * + * @example + * + * var mode = CryptoJS.mode.CBC.createEncryptor(cipher, iv.words); + */ + createEncryptor: function (cipher, iv) { + return this.Encryptor.create(cipher, iv); + }, + + /** + * Creates this mode for decryption. + * + * @param {Cipher} cipher A block cipher instance. + * @param {Array} iv The IV words. + * + * @static + * + * @example + * + * var mode = CryptoJS.mode.CBC.createDecryptor(cipher, iv.words); + */ + createDecryptor: function (cipher, iv) { + return this.Decryptor.create(cipher, iv); + }, + + /** + * Initializes a newly created mode. + * + * @param {Cipher} cipher A block cipher instance. + * @param {Array} iv The IV words. + * + * @example + * + * var mode = CryptoJS.mode.CBC.Encryptor.create(cipher, iv.words); + */ + init: function (cipher, iv) { + this._cipher = cipher; + this._iv = iv; + } + }); + + /** + * Cipher Block Chaining mode. + */ + var CBC = C_mode.CBC = (function () { + /** + * Abstract base CBC mode. + */ + var CBC = BlockCipherMode.extend(); + + /** + * CBC encryptor. + */ + CBC.Encryptor = CBC.extend({ + /** + * Processes the data block at offset. + * + * @param {Array} words The data words to operate on. + * @param {number} offset The offset where the block starts. + * + * @example + * + * mode.processBlock(data.words, offset); + */ + processBlock: function (words, offset) { + // Shortcuts + var cipher = this._cipher; + var blockSize = cipher.blockSize; + + // XOR and encrypt + xorBlock.call(this, words, offset, blockSize); + cipher.encryptBlock(words, offset); + + // Remember this block to use with next block + this._prevBlock = words.slice(offset, offset + blockSize); + } + }); + + /** + * CBC decryptor. + */ + CBC.Decryptor = CBC.extend({ + /** + * Processes the data block at offset. + * + * @param {Array} words The data words to operate on. + * @param {number} offset The offset where the block starts. + * + * @example + * + * mode.processBlock(data.words, offset); + */ + processBlock: function (words, offset) { + // Shortcuts + var cipher = this._cipher; + var blockSize = cipher.blockSize; + + // Remember this block to use with next block + var thisBlock = words.slice(offset, offset + blockSize); + + // Decrypt and XOR + cipher.decryptBlock(words, offset); + xorBlock.call(this, words, offset, blockSize); + + // This block becomes the previous block + this._prevBlock = thisBlock; + } + }); + + function xorBlock(words, offset, blockSize) { + var block; + + // Shortcut + var iv = this._iv; + + // Choose mixing block + if (iv) { + block = iv; + + // Remove IV for subsequent blocks + this._iv = undefined; + } else { + block = this._prevBlock; + } + + // XOR blocks + for (var i = 0; i < blockSize; i++) { + words[offset + i] ^= block[i]; + } + } + + return CBC; + }()); + + /** + * Padding namespace. + */ + var C_pad = C.pad = {}; + + /** + * PKCS #5/7 padding strategy. + */ + var Pkcs7 = C_pad.Pkcs7 = { + /** + * Pads data using the algorithm defined in PKCS #5/7. + * + * @param {WordArray} data The data to pad. + * @param {number} blockSize The multiple that the data should be padded to. + * + * @static + * + * @example + * + * CryptoJS.pad.Pkcs7.pad(wordArray, 4); + */ + pad: function (data, blockSize) { + // Shortcut + var blockSizeBytes = blockSize * 4; + + // Count padding bytes + var nPaddingBytes = blockSizeBytes - data.sigBytes % blockSizeBytes; + + // Create padding word + var paddingWord = (nPaddingBytes << 24) | (nPaddingBytes << 16) | (nPaddingBytes << 8) | nPaddingBytes; + + // Create padding + var paddingWords = []; + for (var i = 0; i < nPaddingBytes; i += 4) { + paddingWords.push(paddingWord); + } + var padding = WordArray.create(paddingWords, nPaddingBytes); + + // Add padding + data.concat(padding); + }, + + /** + * Unpads data that had been padded using the algorithm defined in PKCS #5/7. + * + * @param {WordArray} data The data to unpad. + * + * @static + * + * @example + * + * CryptoJS.pad.Pkcs7.unpad(wordArray); + */ + unpad: function (data) { + // Get number of padding bytes from last byte + var nPaddingBytes = data.words[(data.sigBytes - 1) >>> 2] & 0xff; + + // Remove padding + data.sigBytes -= nPaddingBytes; + } + }; + + /** + * Abstract base block cipher template. + * + * @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 4 (128 bits) + */ + var BlockCipher = C_lib.BlockCipher = Cipher.extend({ + /** + * Configuration options. + * + * @property {Mode} mode The block mode to use. Default: CBC + * @property {Padding} padding The padding strategy to use. Default: Pkcs7 + */ + cfg: Cipher.cfg.extend({ + mode: CBC, + padding: Pkcs7 + }), + + reset: function () { + var modeCreator; + + // Reset cipher + Cipher.reset.call(this); + + // Shortcuts + var cfg = this.cfg; + var iv = cfg.iv; + var mode = cfg.mode; + + // Reset block mode + if (this._xformMode == this._ENC_XFORM_MODE) { + modeCreator = mode.createEncryptor; + } else /* if (this._xformMode == this._DEC_XFORM_MODE) */ { + modeCreator = mode.createDecryptor; + // Keep at least one block in the buffer for unpadding + this._minBufferSize = 1; + } + + if (this._mode && this._mode.__creator == modeCreator) { + this._mode.init(this, iv && iv.words); + } else { + this._mode = modeCreator.call(mode, this, iv && iv.words); + this._mode.__creator = modeCreator; + } + }, + + _doProcessBlock: function (words, offset) { + this._mode.processBlock(words, offset); + }, + + _doFinalize: function () { + var finalProcessedBlocks; + + // Shortcut + var padding = this.cfg.padding; + + // Finalize + if (this._xformMode == this._ENC_XFORM_MODE) { + // Pad data + padding.pad(this._data, this.blockSize); + + // Process final blocks + finalProcessedBlocks = this._process(!!'flush'); + } else /* if (this._xformMode == this._DEC_XFORM_MODE) */ { + // Process final blocks + finalProcessedBlocks = this._process(!!'flush'); + + // Unpad data + padding.unpad(finalProcessedBlocks); + } + + return finalProcessedBlocks; + }, + + blockSize: 128/32 + }); + + /** + * A collection of cipher parameters. + * + * @property {WordArray} ciphertext The raw ciphertext. + * @property {WordArray} key The key to this ciphertext. + * @property {WordArray} iv The IV used in the ciphering operation. + * @property {WordArray} salt The salt used with a key derivation function. + * @property {Cipher} algorithm The cipher algorithm. + * @property {Mode} mode The block mode used in the ciphering operation. + * @property {Padding} padding The padding scheme used in the ciphering operation. + * @property {number} blockSize The block size of the cipher. + * @property {Format} formatter The default formatting strategy to convert this cipher params object to a string. + */ + var CipherParams = C_lib.CipherParams = Base.extend({ + /** + * Initializes a newly created cipher params object. + * + * @param {Object} cipherParams An object with any of the possible cipher parameters. + * + * @example + * + * var cipherParams = CryptoJS.lib.CipherParams.create({ + * ciphertext: ciphertextWordArray, + * key: keyWordArray, + * iv: ivWordArray, + * salt: saltWordArray, + * algorithm: CryptoJS.algo.AES, + * mode: CryptoJS.mode.CBC, + * padding: CryptoJS.pad.PKCS7, + * blockSize: 4, + * formatter: CryptoJS.format.OpenSSL + * }); + */ + init: function (cipherParams) { + this.mixIn(cipherParams); + }, + + /** + * Converts this cipher params object to a string. + * + * @param {Format} formatter (Optional) The formatting strategy to use. + * + * @return {string} The stringified cipher params. + * + * @throws Error If neither the formatter nor the default formatter is set. + * + * @example + * + * var string = cipherParams + ''; + * var string = cipherParams.toString(); + * var string = cipherParams.toString(CryptoJS.format.OpenSSL); + */ + toString: function (formatter) { + return (formatter || this.formatter).stringify(this); + } + }); + + /** + * Format namespace. + */ + var C_format = C.format = {}; + + /** + * OpenSSL formatting strategy. + */ + var OpenSSLFormatter = C_format.OpenSSL = { + /** + * Converts a cipher params object to an OpenSSL-compatible string. + * + * @param {CipherParams} cipherParams The cipher params object. + * + * @return {string} The OpenSSL-compatible string. + * + * @static + * + * @example + * + * var openSSLString = CryptoJS.format.OpenSSL.stringify(cipherParams); + */ + stringify: function (cipherParams) { + var wordArray; + + // Shortcuts + var ciphertext = cipherParams.ciphertext; + var salt = cipherParams.salt; + + // Format + if (salt) { + wordArray = WordArray.create([0x53616c74, 0x65645f5f]).concat(salt).concat(ciphertext); + } else { + wordArray = ciphertext; + } + + return wordArray.toString(Base64); + }, + + /** + * Converts an OpenSSL-compatible string to a cipher params object. + * + * @param {string} openSSLStr The OpenSSL-compatible string. + * + * @return {CipherParams} The cipher params object. + * + * @static + * + * @example + * + * var cipherParams = CryptoJS.format.OpenSSL.parse(openSSLString); + */ + parse: function (openSSLStr) { + var salt; + + // Parse base64 + var ciphertext = Base64.parse(openSSLStr); + + // Shortcut + var ciphertextWords = ciphertext.words; + + // Test for salt + if (ciphertextWords[0] == 0x53616c74 && ciphertextWords[1] == 0x65645f5f) { + // Extract salt + salt = WordArray.create(ciphertextWords.slice(2, 4)); + + // Remove salt from ciphertext + ciphertextWords.splice(0, 4); + ciphertext.sigBytes -= 16; + } + + return CipherParams.create({ ciphertext: ciphertext, salt: salt }); + } + }; + + /** + * A cipher wrapper that returns ciphertext as a serializable cipher params object. + */ + var SerializableCipher = C_lib.SerializableCipher = Base.extend({ + /** + * Configuration options. + * + * @property {Formatter} format The formatting strategy to convert cipher param objects to and from a string. Default: OpenSSL + */ + cfg: Base.extend({ + format: OpenSSLFormatter + }), + + /** + * Encrypts a message. + * + * @param {Cipher} cipher The cipher algorithm to use. + * @param {WordArray|string} message The message to encrypt. + * @param {WordArray} key The key. + * @param {Object} cfg (Optional) The configuration options to use for this operation. + * + * @return {CipherParams} A cipher params object. + * + * @static + * + * @example + * + * var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key); + * var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv }); + * var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv, format: CryptoJS.format.OpenSSL }); + */ + encrypt: function (cipher, message, key, cfg) { + // Apply config defaults + cfg = this.cfg.extend(cfg); + + // Encrypt + var encryptor = cipher.createEncryptor(key, cfg); + var ciphertext = encryptor.finalize(message); + + // Shortcut + var cipherCfg = encryptor.cfg; + + // Create and return serializable cipher params + return CipherParams.create({ + ciphertext: ciphertext, + key: key, + iv: cipherCfg.iv, + algorithm: cipher, + mode: cipherCfg.mode, + padding: cipherCfg.padding, + blockSize: cipher.blockSize, + formatter: cfg.format + }); + }, + + /** + * Decrypts serialized ciphertext. + * + * @param {Cipher} cipher The cipher algorithm to use. + * @param {CipherParams|string} ciphertext The ciphertext to decrypt. + * @param {WordArray} key The key. + * @param {Object} cfg (Optional) The configuration options to use for this operation. + * + * @return {WordArray} The plaintext. + * + * @static + * + * @example + * + * var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, key, { iv: iv, format: CryptoJS.format.OpenSSL }); + * var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, key, { iv: iv, format: CryptoJS.format.OpenSSL }); + */ + decrypt: function (cipher, ciphertext, key, cfg) { + // Apply config defaults + cfg = this.cfg.extend(cfg); + + // Convert string to CipherParams + ciphertext = this._parse(ciphertext, cfg.format); + + // Decrypt + var plaintext = cipher.createDecryptor(key, cfg).finalize(ciphertext.ciphertext); + + return plaintext; + }, + + /** + * Converts serialized ciphertext to CipherParams, + * else assumed CipherParams already and returns ciphertext unchanged. + * + * @param {CipherParams|string} ciphertext The ciphertext. + * @param {Formatter} format The formatting strategy to use to parse serialized ciphertext. + * + * @return {CipherParams} The unserialized ciphertext. + * + * @static + * + * @example + * + * var ciphertextParams = CryptoJS.lib.SerializableCipher._parse(ciphertextStringOrParams, format); + */ + _parse: function (ciphertext, format) { + if (typeof ciphertext == 'string') { + return format.parse(ciphertext, this); + } else { + return ciphertext; + } + } + }); + + /** + * Key derivation function namespace. + */ + var C_kdf = C.kdf = {}; + + /** + * OpenSSL key derivation function. + */ + var OpenSSLKdf = C_kdf.OpenSSL = { + /** + * Derives a key and IV from a password. + * + * @param {string} password The password to derive from. + * @param {number} keySize The size in words of the key to generate. + * @param {number} ivSize The size in words of the IV to generate. + * @param {WordArray|string} salt (Optional) A 64-bit salt to use. If omitted, a salt will be generated randomly. + * + * @return {CipherParams} A cipher params object with the key, IV, and salt. + * + * @static + * + * @example + * + * var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32); + * var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32, 'saltsalt'); + */ + execute: function (password, keySize, ivSize, salt, hasher) { + // Generate random salt + if (!salt) { + salt = WordArray.random(64/8); + } + + // Derive key and IV + if (!hasher) { + var key = EvpKDF.create({ keySize: keySize + ivSize }).compute(password, salt); + } else { + var key = EvpKDF.create({ keySize: keySize + ivSize, hasher: hasher }).compute(password, salt); + } + + + // Separate key and IV + var iv = WordArray.create(key.words.slice(keySize), ivSize * 4); + key.sigBytes = keySize * 4; + + // Return params + return CipherParams.create({ key: key, iv: iv, salt: salt }); + } + }; + + /** + * A serializable cipher wrapper that derives the key from a password, + * and returns ciphertext as a serializable cipher params object. + */ + var PasswordBasedCipher = C_lib.PasswordBasedCipher = SerializableCipher.extend({ + /** + * Configuration options. + * + * @property {KDF} kdf The key derivation function to use to generate a key and IV from a password. Default: OpenSSL + */ + cfg: SerializableCipher.cfg.extend({ + kdf: OpenSSLKdf + }), + + /** + * Encrypts a message using a password. + * + * @param {Cipher} cipher The cipher algorithm to use. + * @param {WordArray|string} message The message to encrypt. + * @param {string} password The password. + * @param {Object} cfg (Optional) The configuration options to use for this operation. + * + * @return {CipherParams} A cipher params object. + * + * @static + * + * @example + * + * var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password'); + * var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password', { format: CryptoJS.format.OpenSSL }); + */ + encrypt: function (cipher, message, password, cfg) { + // Apply config defaults + cfg = this.cfg.extend(cfg); + + // Derive key and other params + var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize, cfg.salt, cfg.hasher); + + // Add IV to config + cfg.iv = derivedParams.iv; + + // Encrypt + var ciphertext = SerializableCipher.encrypt.call(this, cipher, message, derivedParams.key, cfg); + + // Mix in derived params + ciphertext.mixIn(derivedParams); + + return ciphertext; + }, + + /** + * Decrypts serialized ciphertext using a password. + * + * @param {Cipher} cipher The cipher algorithm to use. + * @param {CipherParams|string} ciphertext The ciphertext to decrypt. + * @param {string} password The password. + * @param {Object} cfg (Optional) The configuration options to use for this operation. + * + * @return {WordArray} The plaintext. + * + * @static + * + * @example + * + * var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, 'password', { format: CryptoJS.format.OpenSSL }); + * var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, 'password', { format: CryptoJS.format.OpenSSL }); + */ + decrypt: function (cipher, ciphertext, password, cfg) { + // Apply config defaults + cfg = this.cfg.extend(cfg); + + // Convert string to CipherParams + ciphertext = this._parse(ciphertext, cfg.format); + + // Derive key and other params + var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize, ciphertext.salt, cfg.hasher); + + // Add IV to config + cfg.iv = derivedParams.iv; + + // Decrypt + var plaintext = SerializableCipher.decrypt.call(this, cipher, ciphertext, derivedParams.key, cfg); + + return plaintext; + } + }); + }()); + + + /** + * Cipher Feedback block mode. + */ + CryptoJS.mode.CFB = (function () { + var CFB = CryptoJS.lib.BlockCipherMode.extend(); + + CFB.Encryptor = CFB.extend({ + processBlock: function (words, offset) { + // Shortcuts + var cipher = this._cipher; + var blockSize = cipher.blockSize; + + generateKeystreamAndEncrypt.call(this, words, offset, blockSize, cipher); + + // Remember this block to use with next block + this._prevBlock = words.slice(offset, offset + blockSize); + } + }); + + CFB.Decryptor = CFB.extend({ + processBlock: function (words, offset) { + // Shortcuts + var cipher = this._cipher; + var blockSize = cipher.blockSize; + + // Remember this block to use with next block + var thisBlock = words.slice(offset, offset + blockSize); + + generateKeystreamAndEncrypt.call(this, words, offset, blockSize, cipher); + + // This block becomes the previous block + this._prevBlock = thisBlock; + } + }); + + function generateKeystreamAndEncrypt(words, offset, blockSize, cipher) { + var keystream; + + // Shortcut + var iv = this._iv; + + // Generate keystream + if (iv) { + keystream = iv.slice(0); + + // Remove IV for subsequent blocks + this._iv = undefined; + } else { + keystream = this._prevBlock; + } + cipher.encryptBlock(keystream, 0); + + // Encrypt + for (var i = 0; i < blockSize; i++) { + words[offset + i] ^= keystream[i]; + } + } + + return CFB; + }()); + + + /** + * Counter block mode. + */ + CryptoJS.mode.CTR = (function () { + var CTR = CryptoJS.lib.BlockCipherMode.extend(); + + var Encryptor = CTR.Encryptor = CTR.extend({ + processBlock: function (words, offset) { + // Shortcuts + var cipher = this._cipher + var blockSize = cipher.blockSize; + var iv = this._iv; + var counter = this._counter; + + // Generate keystream + if (iv) { + counter = this._counter = iv.slice(0); + + // Remove IV for subsequent blocks + this._iv = undefined; + } + var keystream = counter.slice(0); + cipher.encryptBlock(keystream, 0); + + // Increment counter + counter[blockSize - 1] = (counter[blockSize - 1] + 1) | 0 + + // Encrypt + for (var i = 0; i < blockSize; i++) { + words[offset + i] ^= keystream[i]; + } + } + }); + + CTR.Decryptor = Encryptor; + + return CTR; + }()); + + + /** @preserve + * Counter block mode compatible with Dr Brian Gladman fileenc.c + * derived from CryptoJS.mode.CTR + * Jan Hruby jhruby.web@gmail.com + */ + CryptoJS.mode.CTRGladman = (function () { + var CTRGladman = CryptoJS.lib.BlockCipherMode.extend(); + + function incWord(word) + { + if (((word >> 24) & 0xff) === 0xff) { //overflow + var b1 = (word >> 16)&0xff; + var b2 = (word >> 8)&0xff; + var b3 = word & 0xff; + + if (b1 === 0xff) // overflow b1 + { + b1 = 0; + if (b2 === 0xff) + { + b2 = 0; + if (b3 === 0xff) + { + b3 = 0; + } + else + { + ++b3; + } + } + else + { + ++b2; + } + } + else + { + ++b1; + } + + word = 0; + word += (b1 << 16); + word += (b2 << 8); + word += b3; + } + else + { + word += (0x01 << 24); + } + return word; + } + + function incCounter(counter) + { + if ((counter[0] = incWord(counter[0])) === 0) + { + // encr_data in fileenc.c from Dr Brian Gladman's counts only with DWORD j < 8 + counter[1] = incWord(counter[1]); + } + return counter; + } + + var Encryptor = CTRGladman.Encryptor = CTRGladman.extend({ + processBlock: function (words, offset) { + // Shortcuts + var cipher = this._cipher + var blockSize = cipher.blockSize; + var iv = this._iv; + var counter = this._counter; + + // Generate keystream + if (iv) { + counter = this._counter = iv.slice(0); + + // Remove IV for subsequent blocks + this._iv = undefined; + } + + incCounter(counter); + + var keystream = counter.slice(0); + cipher.encryptBlock(keystream, 0); + + // Encrypt + for (var i = 0; i < blockSize; i++) { + words[offset + i] ^= keystream[i]; + } + } + }); + + CTRGladman.Decryptor = Encryptor; + + return CTRGladman; + }()); + + + + + /** + * Output Feedback block mode. + */ + CryptoJS.mode.OFB = (function () { + var OFB = CryptoJS.lib.BlockCipherMode.extend(); + + var Encryptor = OFB.Encryptor = OFB.extend({ + processBlock: function (words, offset) { + // Shortcuts + var cipher = this._cipher + var blockSize = cipher.blockSize; + var iv = this._iv; + var keystream = this._keystream; + + // Generate keystream + if (iv) { + keystream = this._keystream = iv.slice(0); + + // Remove IV for subsequent blocks + this._iv = undefined; + } + cipher.encryptBlock(keystream, 0); + + // Encrypt + for (var i = 0; i < blockSize; i++) { + words[offset + i] ^= keystream[i]; + } + } + }); + + OFB.Decryptor = Encryptor; + + return OFB; + }()); + + + /** + * Electronic Codebook block mode. + */ + CryptoJS.mode.ECB = (function () { + var ECB = CryptoJS.lib.BlockCipherMode.extend(); + + ECB.Encryptor = ECB.extend({ + processBlock: function (words, offset) { + this._cipher.encryptBlock(words, offset); + } + }); + + ECB.Decryptor = ECB.extend({ + processBlock: function (words, offset) { + this._cipher.decryptBlock(words, offset); + } + }); + + return ECB; + }()); + + + /** + * ANSI X.923 padding strategy. + */ + CryptoJS.pad.AnsiX923 = { + pad: function (data, blockSize) { + // Shortcuts + var dataSigBytes = data.sigBytes; + var blockSizeBytes = blockSize * 4; + + // Count padding bytes + var nPaddingBytes = blockSizeBytes - dataSigBytes % blockSizeBytes; + + // Compute last byte position + var lastBytePos = dataSigBytes + nPaddingBytes - 1; + + // Pad + data.clamp(); + data.words[lastBytePos >>> 2] |= nPaddingBytes << (24 - (lastBytePos % 4) * 8); + data.sigBytes += nPaddingBytes; + }, + + unpad: function (data) { + // Get number of padding bytes from last byte + var nPaddingBytes = data.words[(data.sigBytes - 1) >>> 2] & 0xff; + + // Remove padding + data.sigBytes -= nPaddingBytes; + } + }; + + + /** + * ISO 10126 padding strategy. + */ + CryptoJS.pad.Iso10126 = { + pad: function (data, blockSize) { + // Shortcut + var blockSizeBytes = blockSize * 4; + + // Count padding bytes + var nPaddingBytes = blockSizeBytes - data.sigBytes % blockSizeBytes; + + // Pad + data.concat(CryptoJS.lib.WordArray.random(nPaddingBytes - 1)). + concat(CryptoJS.lib.WordArray.create([nPaddingBytes << 24], 1)); + }, + + unpad: function (data) { + // Get number of padding bytes from last byte + var nPaddingBytes = data.words[(data.sigBytes - 1) >>> 2] & 0xff; + + // Remove padding + data.sigBytes -= nPaddingBytes; + } + }; + + + /** + * ISO/IEC 9797-1 Padding Method 2. + */ + CryptoJS.pad.Iso97971 = { + pad: function (data, blockSize) { + // Add 0x80 byte + data.concat(CryptoJS.lib.WordArray.create([0x80000000], 1)); + + // Zero pad the rest + CryptoJS.pad.ZeroPadding.pad(data, blockSize); + }, + + unpad: function (data) { + // Remove zero padding + CryptoJS.pad.ZeroPadding.unpad(data); + + // Remove one more byte -- the 0x80 byte + data.sigBytes--; + } + }; + + + /** + * Zero padding strategy. + */ + CryptoJS.pad.ZeroPadding = { + pad: function (data, blockSize) { + // Shortcut + var blockSizeBytes = blockSize * 4; + + // Pad + data.clamp(); + data.sigBytes += blockSizeBytes - ((data.sigBytes % blockSizeBytes) || blockSizeBytes); + }, + + unpad: function (data) { + // Shortcut + var dataWords = data.words; + + // Unpad + var i = data.sigBytes - 1; + for (var i = data.sigBytes - 1; i >= 0; i--) { + if (((dataWords[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff)) { + data.sigBytes = i + 1; + break; + } + } + } + }; + + + /** + * A noop padding strategy. + */ + CryptoJS.pad.NoPadding = { + pad: function () { + }, + + unpad: function () { + } + }; + + + (function (undefined) { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var CipherParams = C_lib.CipherParams; + var C_enc = C.enc; + var Hex = C_enc.Hex; + var C_format = C.format; + + var HexFormatter = C_format.Hex = { + /** + * Converts the ciphertext of a cipher params object to a hexadecimally encoded string. + * + * @param {CipherParams} cipherParams The cipher params object. + * + * @return {string} The hexadecimally encoded string. + * + * @static + * + * @example + * + * var hexString = CryptoJS.format.Hex.stringify(cipherParams); + */ + stringify: function (cipherParams) { + return cipherParams.ciphertext.toString(Hex); + }, + + /** + * Converts a hexadecimally encoded ciphertext string to a cipher params object. + * + * @param {string} input The hexadecimally encoded string. + * + * @return {CipherParams} The cipher params object. + * + * @static + * + * @example + * + * var cipherParams = CryptoJS.format.Hex.parse(hexString); + */ + parse: function (input) { + var ciphertext = Hex.parse(input); + return CipherParams.create({ ciphertext: ciphertext }); + } + }; + }()); + + + (function () { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var BlockCipher = C_lib.BlockCipher; + var C_algo = C.algo; + + // Lookup tables + var SBOX = []; + var INV_SBOX = []; + var SUB_MIX_0 = []; + var SUB_MIX_1 = []; + var SUB_MIX_2 = []; + var SUB_MIX_3 = []; + var INV_SUB_MIX_0 = []; + var INV_SUB_MIX_1 = []; + var INV_SUB_MIX_2 = []; + var INV_SUB_MIX_3 = []; + + // Compute lookup tables + (function () { + // Compute double table + var d = []; + for (var i = 0; i < 256; i++) { + if (i < 128) { + d[i] = i << 1; + } else { + d[i] = (i << 1) ^ 0x11b; + } + } + + // Walk GF(2^8) + var x = 0; + var xi = 0; + for (var i = 0; i < 256; i++) { + // Compute sbox + var sx = xi ^ (xi << 1) ^ (xi << 2) ^ (xi << 3) ^ (xi << 4); + sx = (sx >>> 8) ^ (sx & 0xff) ^ 0x63; + SBOX[x] = sx; + INV_SBOX[sx] = x; + + // Compute multiplication + var x2 = d[x]; + var x4 = d[x2]; + var x8 = d[x4]; + + // Compute sub bytes, mix columns tables + var t = (d[sx] * 0x101) ^ (sx * 0x1010100); + SUB_MIX_0[x] = (t << 24) | (t >>> 8); + SUB_MIX_1[x] = (t << 16) | (t >>> 16); + SUB_MIX_2[x] = (t << 8) | (t >>> 24); + SUB_MIX_3[x] = t; + + // Compute inv sub bytes, inv mix columns tables + var t = (x8 * 0x1010101) ^ (x4 * 0x10001) ^ (x2 * 0x101) ^ (x * 0x1010100); + INV_SUB_MIX_0[sx] = (t << 24) | (t >>> 8); + INV_SUB_MIX_1[sx] = (t << 16) | (t >>> 16); + INV_SUB_MIX_2[sx] = (t << 8) | (t >>> 24); + INV_SUB_MIX_3[sx] = t; + + // Compute next counter + if (!x) { + x = xi = 1; + } else { + x = x2 ^ d[d[d[x8 ^ x2]]]; + xi ^= d[d[xi]]; + } + } + }()); + + // Precomputed Rcon lookup + var RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36]; + + /** + * AES block cipher algorithm. + */ + var AES = C_algo.AES = BlockCipher.extend({ + _doReset: function () { + var t; + + // Skip reset of nRounds has been set before and key did not change + if (this._nRounds && this._keyPriorReset === this._key) { + return; + } + + // Shortcuts + var key = this._keyPriorReset = this._key; + var keyWords = key.words; + var keySize = key.sigBytes / 4; + + // Compute number of rounds + var nRounds = this._nRounds = keySize + 6; + + // Compute number of key schedule rows + var ksRows = (nRounds + 1) * 4; + + // Compute key schedule + var keySchedule = this._keySchedule = []; + for (var ksRow = 0; ksRow < ksRows; ksRow++) { + if (ksRow < keySize) { + keySchedule[ksRow] = keyWords[ksRow]; + } else { + t = keySchedule[ksRow - 1]; + + if (!(ksRow % keySize)) { + // Rot word + t = (t << 8) | (t >>> 24); + + // Sub word + t = (SBOX[t >>> 24] << 24) | (SBOX[(t >>> 16) & 0xff] << 16) | (SBOX[(t >>> 8) & 0xff] << 8) | SBOX[t & 0xff]; + + // Mix Rcon + t ^= RCON[(ksRow / keySize) | 0] << 24; + } else if (keySize > 6 && ksRow % keySize == 4) { + // Sub word + t = (SBOX[t >>> 24] << 24) | (SBOX[(t >>> 16) & 0xff] << 16) | (SBOX[(t >>> 8) & 0xff] << 8) | SBOX[t & 0xff]; + } + + keySchedule[ksRow] = keySchedule[ksRow - keySize] ^ t; + } + } + + // Compute inv key schedule + var invKeySchedule = this._invKeySchedule = []; + for (var invKsRow = 0; invKsRow < ksRows; invKsRow++) { + var ksRow = ksRows - invKsRow; + + if (invKsRow % 4) { + var t = keySchedule[ksRow]; + } else { + var t = keySchedule[ksRow - 4]; + } + + if (invKsRow < 4 || ksRow <= 4) { + invKeySchedule[invKsRow] = t; + } else { + invKeySchedule[invKsRow] = INV_SUB_MIX_0[SBOX[t >>> 24]] ^ INV_SUB_MIX_1[SBOX[(t >>> 16) & 0xff]] ^ + INV_SUB_MIX_2[SBOX[(t >>> 8) & 0xff]] ^ INV_SUB_MIX_3[SBOX[t & 0xff]]; + } + } + }, + + encryptBlock: function (M, offset) { + this._doCryptBlock(M, offset, this._keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX); + }, + + decryptBlock: function (M, offset) { + // Swap 2nd and 4th rows + var t = M[offset + 1]; + M[offset + 1] = M[offset + 3]; + M[offset + 3] = t; + + this._doCryptBlock(M, offset, this._invKeySchedule, INV_SUB_MIX_0, INV_SUB_MIX_1, INV_SUB_MIX_2, INV_SUB_MIX_3, INV_SBOX); + + // Inv swap 2nd and 4th rows + var t = M[offset + 1]; + M[offset + 1] = M[offset + 3]; + M[offset + 3] = t; + }, + + _doCryptBlock: function (M, offset, keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX) { + // Shortcut + var nRounds = this._nRounds; + + // Get input, add round key + var s0 = M[offset] ^ keySchedule[0]; + var s1 = M[offset + 1] ^ keySchedule[1]; + var s2 = M[offset + 2] ^ keySchedule[2]; + var s3 = M[offset + 3] ^ keySchedule[3]; + + // Key schedule row counter + var ksRow = 4; + + // Rounds + for (var round = 1; round < nRounds; round++) { + // Shift rows, sub bytes, mix columns, add round key + var t0 = SUB_MIX_0[s0 >>> 24] ^ SUB_MIX_1[(s1 >>> 16) & 0xff] ^ SUB_MIX_2[(s2 >>> 8) & 0xff] ^ SUB_MIX_3[s3 & 0xff] ^ keySchedule[ksRow++]; + var t1 = SUB_MIX_0[s1 >>> 24] ^ SUB_MIX_1[(s2 >>> 16) & 0xff] ^ SUB_MIX_2[(s3 >>> 8) & 0xff] ^ SUB_MIX_3[s0 & 0xff] ^ keySchedule[ksRow++]; + var t2 = SUB_MIX_0[s2 >>> 24] ^ SUB_MIX_1[(s3 >>> 16) & 0xff] ^ SUB_MIX_2[(s0 >>> 8) & 0xff] ^ SUB_MIX_3[s1 & 0xff] ^ keySchedule[ksRow++]; + var t3 = SUB_MIX_0[s3 >>> 24] ^ SUB_MIX_1[(s0 >>> 16) & 0xff] ^ SUB_MIX_2[(s1 >>> 8) & 0xff] ^ SUB_MIX_3[s2 & 0xff] ^ keySchedule[ksRow++]; + + // Update state + s0 = t0; + s1 = t1; + s2 = t2; + s3 = t3; + } + + // Shift rows, sub bytes, add round key + var t0 = ((SBOX[s0 >>> 24] << 24) | (SBOX[(s1 >>> 16) & 0xff] << 16) | (SBOX[(s2 >>> 8) & 0xff] << 8) | SBOX[s3 & 0xff]) ^ keySchedule[ksRow++]; + var t1 = ((SBOX[s1 >>> 24] << 24) | (SBOX[(s2 >>> 16) & 0xff] << 16) | (SBOX[(s3 >>> 8) & 0xff] << 8) | SBOX[s0 & 0xff]) ^ keySchedule[ksRow++]; + var t2 = ((SBOX[s2 >>> 24] << 24) | (SBOX[(s3 >>> 16) & 0xff] << 16) | (SBOX[(s0 >>> 8) & 0xff] << 8) | SBOX[s1 & 0xff]) ^ keySchedule[ksRow++]; + var t3 = ((SBOX[s3 >>> 24] << 24) | (SBOX[(s0 >>> 16) & 0xff] << 16) | (SBOX[(s1 >>> 8) & 0xff] << 8) | SBOX[s2 & 0xff]) ^ keySchedule[ksRow++]; + + // Set output + M[offset] = t0; + M[offset + 1] = t1; + M[offset + 2] = t2; + M[offset + 3] = t3; + }, + + keySize: 256/32 + }); + + /** + * Shortcut functions to the cipher's object interface. + * + * @example + * + * var ciphertext = CryptoJS.AES.encrypt(message, key, cfg); + * var plaintext = CryptoJS.AES.decrypt(ciphertext, key, cfg); + */ + C.AES = BlockCipher._createHelper(AES); + }()); + + + (function () { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var WordArray = C_lib.WordArray; + var BlockCipher = C_lib.BlockCipher; + var C_algo = C.algo; + + // Permuted Choice 1 constants + var PC1 = [ + 57, 49, 41, 33, 25, 17, 9, 1, + 58, 50, 42, 34, 26, 18, 10, 2, + 59, 51, 43, 35, 27, 19, 11, 3, + 60, 52, 44, 36, 63, 55, 47, 39, + 31, 23, 15, 7, 62, 54, 46, 38, + 30, 22, 14, 6, 61, 53, 45, 37, + 29, 21, 13, 5, 28, 20, 12, 4 + ]; + + // Permuted Choice 2 constants + var PC2 = [ + 14, 17, 11, 24, 1, 5, + 3, 28, 15, 6, 21, 10, + 23, 19, 12, 4, 26, 8, + 16, 7, 27, 20, 13, 2, + 41, 52, 31, 37, 47, 55, + 30, 40, 51, 45, 33, 48, + 44, 49, 39, 56, 34, 53, + 46, 42, 50, 36, 29, 32 + ]; + + // Cumulative bit shift constants + var BIT_SHIFTS = [1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28]; + + // SBOXes and round permutation constants + var SBOX_P = [ + { + 0x0: 0x808200, + 0x10000000: 0x8000, + 0x20000000: 0x808002, + 0x30000000: 0x2, + 0x40000000: 0x200, + 0x50000000: 0x808202, + 0x60000000: 0x800202, + 0x70000000: 0x800000, + 0x80000000: 0x202, + 0x90000000: 0x800200, + 0xa0000000: 0x8200, + 0xb0000000: 0x808000, + 0xc0000000: 0x8002, + 0xd0000000: 0x800002, + 0xe0000000: 0x0, + 0xf0000000: 0x8202, + 0x8000000: 0x0, + 0x18000000: 0x808202, + 0x28000000: 0x8202, + 0x38000000: 0x8000, + 0x48000000: 0x808200, + 0x58000000: 0x200, + 0x68000000: 0x808002, + 0x78000000: 0x2, + 0x88000000: 0x800200, + 0x98000000: 0x8200, + 0xa8000000: 0x808000, + 0xb8000000: 0x800202, + 0xc8000000: 0x800002, + 0xd8000000: 0x8002, + 0xe8000000: 0x202, + 0xf8000000: 0x800000, + 0x1: 0x8000, + 0x10000001: 0x2, + 0x20000001: 0x808200, + 0x30000001: 0x800000, + 0x40000001: 0x808002, + 0x50000001: 0x8200, + 0x60000001: 0x200, + 0x70000001: 0x800202, + 0x80000001: 0x808202, + 0x90000001: 0x808000, + 0xa0000001: 0x800002, + 0xb0000001: 0x8202, + 0xc0000001: 0x202, + 0xd0000001: 0x800200, + 0xe0000001: 0x8002, + 0xf0000001: 0x0, + 0x8000001: 0x808202, + 0x18000001: 0x808000, + 0x28000001: 0x800000, + 0x38000001: 0x200, + 0x48000001: 0x8000, + 0x58000001: 0x800002, + 0x68000001: 0x2, + 0x78000001: 0x8202, + 0x88000001: 0x8002, + 0x98000001: 0x800202, + 0xa8000001: 0x202, + 0xb8000001: 0x808200, + 0xc8000001: 0x800200, + 0xd8000001: 0x0, + 0xe8000001: 0x8200, + 0xf8000001: 0x808002 + }, + { + 0x0: 0x40084010, + 0x1000000: 0x4000, + 0x2000000: 0x80000, + 0x3000000: 0x40080010, + 0x4000000: 0x40000010, + 0x5000000: 0x40084000, + 0x6000000: 0x40004000, + 0x7000000: 0x10, + 0x8000000: 0x84000, + 0x9000000: 0x40004010, + 0xa000000: 0x40000000, + 0xb000000: 0x84010, + 0xc000000: 0x80010, + 0xd000000: 0x0, + 0xe000000: 0x4010, + 0xf000000: 0x40080000, + 0x800000: 0x40004000, + 0x1800000: 0x84010, + 0x2800000: 0x10, + 0x3800000: 0x40004010, + 0x4800000: 0x40084010, + 0x5800000: 0x40000000, + 0x6800000: 0x80000, + 0x7800000: 0x40080010, + 0x8800000: 0x80010, + 0x9800000: 0x0, + 0xa800000: 0x4000, + 0xb800000: 0x40080000, + 0xc800000: 0x40000010, + 0xd800000: 0x84000, + 0xe800000: 0x40084000, + 0xf800000: 0x4010, + 0x10000000: 0x0, + 0x11000000: 0x40080010, + 0x12000000: 0x40004010, + 0x13000000: 0x40084000, + 0x14000000: 0x40080000, + 0x15000000: 0x10, + 0x16000000: 0x84010, + 0x17000000: 0x4000, + 0x18000000: 0x4010, + 0x19000000: 0x80000, + 0x1a000000: 0x80010, + 0x1b000000: 0x40000010, + 0x1c000000: 0x84000, + 0x1d000000: 0x40004000, + 0x1e000000: 0x40000000, + 0x1f000000: 0x40084010, + 0x10800000: 0x84010, + 0x11800000: 0x80000, + 0x12800000: 0x40080000, + 0x13800000: 0x4000, + 0x14800000: 0x40004000, + 0x15800000: 0x40084010, + 0x16800000: 0x10, + 0x17800000: 0x40000000, + 0x18800000: 0x40084000, + 0x19800000: 0x40000010, + 0x1a800000: 0x40004010, + 0x1b800000: 0x80010, + 0x1c800000: 0x0, + 0x1d800000: 0x4010, + 0x1e800000: 0x40080010, + 0x1f800000: 0x84000 + }, + { + 0x0: 0x104, + 0x100000: 0x0, + 0x200000: 0x4000100, + 0x300000: 0x10104, + 0x400000: 0x10004, + 0x500000: 0x4000004, + 0x600000: 0x4010104, + 0x700000: 0x4010000, + 0x800000: 0x4000000, + 0x900000: 0x4010100, + 0xa00000: 0x10100, + 0xb00000: 0x4010004, + 0xc00000: 0x4000104, + 0xd00000: 0x10000, + 0xe00000: 0x4, + 0xf00000: 0x100, + 0x80000: 0x4010100, + 0x180000: 0x4010004, + 0x280000: 0x0, + 0x380000: 0x4000100, + 0x480000: 0x4000004, + 0x580000: 0x10000, + 0x680000: 0x10004, + 0x780000: 0x104, + 0x880000: 0x4, + 0x980000: 0x100, + 0xa80000: 0x4010000, + 0xb80000: 0x10104, + 0xc80000: 0x10100, + 0xd80000: 0x4000104, + 0xe80000: 0x4010104, + 0xf80000: 0x4000000, + 0x1000000: 0x4010100, + 0x1100000: 0x10004, + 0x1200000: 0x10000, + 0x1300000: 0x4000100, + 0x1400000: 0x100, + 0x1500000: 0x4010104, + 0x1600000: 0x4000004, + 0x1700000: 0x0, + 0x1800000: 0x4000104, + 0x1900000: 0x4000000, + 0x1a00000: 0x4, + 0x1b00000: 0x10100, + 0x1c00000: 0x4010000, + 0x1d00000: 0x104, + 0x1e00000: 0x10104, + 0x1f00000: 0x4010004, + 0x1080000: 0x4000000, + 0x1180000: 0x104, + 0x1280000: 0x4010100, + 0x1380000: 0x0, + 0x1480000: 0x10004, + 0x1580000: 0x4000100, + 0x1680000: 0x100, + 0x1780000: 0x4010004, + 0x1880000: 0x10000, + 0x1980000: 0x4010104, + 0x1a80000: 0x10104, + 0x1b80000: 0x4000004, + 0x1c80000: 0x4000104, + 0x1d80000: 0x4010000, + 0x1e80000: 0x4, + 0x1f80000: 0x10100 + }, + { + 0x0: 0x80401000, + 0x10000: 0x80001040, + 0x20000: 0x401040, + 0x30000: 0x80400000, + 0x40000: 0x0, + 0x50000: 0x401000, + 0x60000: 0x80000040, + 0x70000: 0x400040, + 0x80000: 0x80000000, + 0x90000: 0x400000, + 0xa0000: 0x40, + 0xb0000: 0x80001000, + 0xc0000: 0x80400040, + 0xd0000: 0x1040, + 0xe0000: 0x1000, + 0xf0000: 0x80401040, + 0x8000: 0x80001040, + 0x18000: 0x40, + 0x28000: 0x80400040, + 0x38000: 0x80001000, + 0x48000: 0x401000, + 0x58000: 0x80401040, + 0x68000: 0x0, + 0x78000: 0x80400000, + 0x88000: 0x1000, + 0x98000: 0x80401000, + 0xa8000: 0x400000, + 0xb8000: 0x1040, + 0xc8000: 0x80000000, + 0xd8000: 0x400040, + 0xe8000: 0x401040, + 0xf8000: 0x80000040, + 0x100000: 0x400040, + 0x110000: 0x401000, + 0x120000: 0x80000040, + 0x130000: 0x0, + 0x140000: 0x1040, + 0x150000: 0x80400040, + 0x160000: 0x80401000, + 0x170000: 0x80001040, + 0x180000: 0x80401040, + 0x190000: 0x80000000, + 0x1a0000: 0x80400000, + 0x1b0000: 0x401040, + 0x1c0000: 0x80001000, + 0x1d0000: 0x400000, + 0x1e0000: 0x40, + 0x1f0000: 0x1000, + 0x108000: 0x80400000, + 0x118000: 0x80401040, + 0x128000: 0x0, + 0x138000: 0x401000, + 0x148000: 0x400040, + 0x158000: 0x80000000, + 0x168000: 0x80001040, + 0x178000: 0x40, + 0x188000: 0x80000040, + 0x198000: 0x1000, + 0x1a8000: 0x80001000, + 0x1b8000: 0x80400040, + 0x1c8000: 0x1040, + 0x1d8000: 0x80401000, + 0x1e8000: 0x400000, + 0x1f8000: 0x401040 + }, + { + 0x0: 0x80, + 0x1000: 0x1040000, + 0x2000: 0x40000, + 0x3000: 0x20000000, + 0x4000: 0x20040080, + 0x5000: 0x1000080, + 0x6000: 0x21000080, + 0x7000: 0x40080, + 0x8000: 0x1000000, + 0x9000: 0x20040000, + 0xa000: 0x20000080, + 0xb000: 0x21040080, + 0xc000: 0x21040000, + 0xd000: 0x0, + 0xe000: 0x1040080, + 0xf000: 0x21000000, + 0x800: 0x1040080, + 0x1800: 0x21000080, + 0x2800: 0x80, + 0x3800: 0x1040000, + 0x4800: 0x40000, + 0x5800: 0x20040080, + 0x6800: 0x21040000, + 0x7800: 0x20000000, + 0x8800: 0x20040000, + 0x9800: 0x0, + 0xa800: 0x21040080, + 0xb800: 0x1000080, + 0xc800: 0x20000080, + 0xd800: 0x21000000, + 0xe800: 0x1000000, + 0xf800: 0x40080, + 0x10000: 0x40000, + 0x11000: 0x80, + 0x12000: 0x20000000, + 0x13000: 0x21000080, + 0x14000: 0x1000080, + 0x15000: 0x21040000, + 0x16000: 0x20040080, + 0x17000: 0x1000000, + 0x18000: 0x21040080, + 0x19000: 0x21000000, + 0x1a000: 0x1040000, + 0x1b000: 0x20040000, + 0x1c000: 0x40080, + 0x1d000: 0x20000080, + 0x1e000: 0x0, + 0x1f000: 0x1040080, + 0x10800: 0x21000080, + 0x11800: 0x1000000, + 0x12800: 0x1040000, + 0x13800: 0x20040080, + 0x14800: 0x20000000, + 0x15800: 0x1040080, + 0x16800: 0x80, + 0x17800: 0x21040000, + 0x18800: 0x40080, + 0x19800: 0x21040080, + 0x1a800: 0x0, + 0x1b800: 0x21000000, + 0x1c800: 0x1000080, + 0x1d800: 0x40000, + 0x1e800: 0x20040000, + 0x1f800: 0x20000080 + }, + { + 0x0: 0x10000008, + 0x100: 0x2000, + 0x200: 0x10200000, + 0x300: 0x10202008, + 0x400: 0x10002000, + 0x500: 0x200000, + 0x600: 0x200008, + 0x700: 0x10000000, + 0x800: 0x0, + 0x900: 0x10002008, + 0xa00: 0x202000, + 0xb00: 0x8, + 0xc00: 0x10200008, + 0xd00: 0x202008, + 0xe00: 0x2008, + 0xf00: 0x10202000, + 0x80: 0x10200000, + 0x180: 0x10202008, + 0x280: 0x8, + 0x380: 0x200000, + 0x480: 0x202008, + 0x580: 0x10000008, + 0x680: 0x10002000, + 0x780: 0x2008, + 0x880: 0x200008, + 0x980: 0x2000, + 0xa80: 0x10002008, + 0xb80: 0x10200008, + 0xc80: 0x0, + 0xd80: 0x10202000, + 0xe80: 0x202000, + 0xf80: 0x10000000, + 0x1000: 0x10002000, + 0x1100: 0x10200008, + 0x1200: 0x10202008, + 0x1300: 0x2008, + 0x1400: 0x200000, + 0x1500: 0x10000000, + 0x1600: 0x10000008, + 0x1700: 0x202000, + 0x1800: 0x202008, + 0x1900: 0x0, + 0x1a00: 0x8, + 0x1b00: 0x10200000, + 0x1c00: 0x2000, + 0x1d00: 0x10002008, + 0x1e00: 0x10202000, + 0x1f00: 0x200008, + 0x1080: 0x8, + 0x1180: 0x202000, + 0x1280: 0x200000, + 0x1380: 0x10000008, + 0x1480: 0x10002000, + 0x1580: 0x2008, + 0x1680: 0x10202008, + 0x1780: 0x10200000, + 0x1880: 0x10202000, + 0x1980: 0x10200008, + 0x1a80: 0x2000, + 0x1b80: 0x202008, + 0x1c80: 0x200008, + 0x1d80: 0x0, + 0x1e80: 0x10000000, + 0x1f80: 0x10002008 + }, + { + 0x0: 0x100000, + 0x10: 0x2000401, + 0x20: 0x400, + 0x30: 0x100401, + 0x40: 0x2100401, + 0x50: 0x0, + 0x60: 0x1, + 0x70: 0x2100001, + 0x80: 0x2000400, + 0x90: 0x100001, + 0xa0: 0x2000001, + 0xb0: 0x2100400, + 0xc0: 0x2100000, + 0xd0: 0x401, + 0xe0: 0x100400, + 0xf0: 0x2000000, + 0x8: 0x2100001, + 0x18: 0x0, + 0x28: 0x2000401, + 0x38: 0x2100400, + 0x48: 0x100000, + 0x58: 0x2000001, + 0x68: 0x2000000, + 0x78: 0x401, + 0x88: 0x100401, + 0x98: 0x2000400, + 0xa8: 0x2100000, + 0xb8: 0x100001, + 0xc8: 0x400, + 0xd8: 0x2100401, + 0xe8: 0x1, + 0xf8: 0x100400, + 0x100: 0x2000000, + 0x110: 0x100000, + 0x120: 0x2000401, + 0x130: 0x2100001, + 0x140: 0x100001, + 0x150: 0x2000400, + 0x160: 0x2100400, + 0x170: 0x100401, + 0x180: 0x401, + 0x190: 0x2100401, + 0x1a0: 0x100400, + 0x1b0: 0x1, + 0x1c0: 0x0, + 0x1d0: 0x2100000, + 0x1e0: 0x2000001, + 0x1f0: 0x400, + 0x108: 0x100400, + 0x118: 0x2000401, + 0x128: 0x2100001, + 0x138: 0x1, + 0x148: 0x2000000, + 0x158: 0x100000, + 0x168: 0x401, + 0x178: 0x2100400, + 0x188: 0x2000001, + 0x198: 0x2100000, + 0x1a8: 0x0, + 0x1b8: 0x2100401, + 0x1c8: 0x100401, + 0x1d8: 0x400, + 0x1e8: 0x2000400, + 0x1f8: 0x100001 + }, + { + 0x0: 0x8000820, + 0x1: 0x20000, + 0x2: 0x8000000, + 0x3: 0x20, + 0x4: 0x20020, + 0x5: 0x8020820, + 0x6: 0x8020800, + 0x7: 0x800, + 0x8: 0x8020000, + 0x9: 0x8000800, + 0xa: 0x20800, + 0xb: 0x8020020, + 0xc: 0x820, + 0xd: 0x0, + 0xe: 0x8000020, + 0xf: 0x20820, + 0x80000000: 0x800, + 0x80000001: 0x8020820, + 0x80000002: 0x8000820, + 0x80000003: 0x8000000, + 0x80000004: 0x8020000, + 0x80000005: 0x20800, + 0x80000006: 0x20820, + 0x80000007: 0x20, + 0x80000008: 0x8000020, + 0x80000009: 0x820, + 0x8000000a: 0x20020, + 0x8000000b: 0x8020800, + 0x8000000c: 0x0, + 0x8000000d: 0x8020020, + 0x8000000e: 0x8000800, + 0x8000000f: 0x20000, + 0x10: 0x20820, + 0x11: 0x8020800, + 0x12: 0x20, + 0x13: 0x800, + 0x14: 0x8000800, + 0x15: 0x8000020, + 0x16: 0x8020020, + 0x17: 0x20000, + 0x18: 0x0, + 0x19: 0x20020, + 0x1a: 0x8020000, + 0x1b: 0x8000820, + 0x1c: 0x8020820, + 0x1d: 0x20800, + 0x1e: 0x820, + 0x1f: 0x8000000, + 0x80000010: 0x20000, + 0x80000011: 0x800, + 0x80000012: 0x8020020, + 0x80000013: 0x20820, + 0x80000014: 0x20, + 0x80000015: 0x8020000, + 0x80000016: 0x8000000, + 0x80000017: 0x8000820, + 0x80000018: 0x8020820, + 0x80000019: 0x8000020, + 0x8000001a: 0x8000800, + 0x8000001b: 0x0, + 0x8000001c: 0x20800, + 0x8000001d: 0x820, + 0x8000001e: 0x20020, + 0x8000001f: 0x8020800 + } + ]; + + // Masks that select the SBOX input + var SBOX_MASK = [ + 0xf8000001, 0x1f800000, 0x01f80000, 0x001f8000, + 0x0001f800, 0x00001f80, 0x000001f8, 0x8000001f + ]; + + /** + * DES block cipher algorithm. + */ + var DES = C_algo.DES = BlockCipher.extend({ + _doReset: function () { + // Shortcuts + var key = this._key; + var keyWords = key.words; + + // Select 56 bits according to PC1 + var keyBits = []; + for (var i = 0; i < 56; i++) { + var keyBitPos = PC1[i] - 1; + keyBits[i] = (keyWords[keyBitPos >>> 5] >>> (31 - keyBitPos % 32)) & 1; + } + + // Assemble 16 subkeys + var subKeys = this._subKeys = []; + for (var nSubKey = 0; nSubKey < 16; nSubKey++) { + // Create subkey + var subKey = subKeys[nSubKey] = []; + + // Shortcut + var bitShift = BIT_SHIFTS[nSubKey]; + + // Select 48 bits according to PC2 + for (var i = 0; i < 24; i++) { + // Select from the left 28 key bits + subKey[(i / 6) | 0] |= keyBits[((PC2[i] - 1) + bitShift) % 28] << (31 - i % 6); + + // Select from the right 28 key bits + subKey[4 + ((i / 6) | 0)] |= keyBits[28 + (((PC2[i + 24] - 1) + bitShift) % 28)] << (31 - i % 6); + } + + // Since each subkey is applied to an expanded 32-bit input, + // the subkey can be broken into 8 values scaled to 32-bits, + // which allows the key to be used without expansion + subKey[0] = (subKey[0] << 1) | (subKey[0] >>> 31); + for (var i = 1; i < 7; i++) { + subKey[i] = subKey[i] >>> ((i - 1) * 4 + 3); + } + subKey[7] = (subKey[7] << 5) | (subKey[7] >>> 27); + } + + // Compute inverse subkeys + var invSubKeys = this._invSubKeys = []; + for (var i = 0; i < 16; i++) { + invSubKeys[i] = subKeys[15 - i]; + } + }, + + encryptBlock: function (M, offset) { + this._doCryptBlock(M, offset, this._subKeys); + }, + + decryptBlock: function (M, offset) { + this._doCryptBlock(M, offset, this._invSubKeys); + }, + + _doCryptBlock: function (M, offset, subKeys) { + // Get input + this._lBlock = M[offset]; + this._rBlock = M[offset + 1]; + + // Initial permutation + exchangeLR.call(this, 4, 0x0f0f0f0f); + exchangeLR.call(this, 16, 0x0000ffff); + exchangeRL.call(this, 2, 0x33333333); + exchangeRL.call(this, 8, 0x00ff00ff); + exchangeLR.call(this, 1, 0x55555555); + + // Rounds + for (var round = 0; round < 16; round++) { + // Shortcuts + var subKey = subKeys[round]; + var lBlock = this._lBlock; + var rBlock = this._rBlock; + + // Feistel function + var f = 0; + for (var i = 0; i < 8; i++) { + f |= SBOX_P[i][((rBlock ^ subKey[i]) & SBOX_MASK[i]) >>> 0]; + } + this._lBlock = rBlock; + this._rBlock = lBlock ^ f; + } + + // Undo swap from last round + var t = this._lBlock; + this._lBlock = this._rBlock; + this._rBlock = t; + + // Final permutation + exchangeLR.call(this, 1, 0x55555555); + exchangeRL.call(this, 8, 0x00ff00ff); + exchangeRL.call(this, 2, 0x33333333); + exchangeLR.call(this, 16, 0x0000ffff); + exchangeLR.call(this, 4, 0x0f0f0f0f); + + // Set output + M[offset] = this._lBlock; + M[offset + 1] = this._rBlock; + }, + + keySize: 64/32, + + ivSize: 64/32, + + blockSize: 64/32 + }); + + // Swap bits across the left and right words + function exchangeLR(offset, mask) { + var t = ((this._lBlock >>> offset) ^ this._rBlock) & mask; + this._rBlock ^= t; + this._lBlock ^= t << offset; + } + + function exchangeRL(offset, mask) { + var t = ((this._rBlock >>> offset) ^ this._lBlock) & mask; + this._lBlock ^= t; + this._rBlock ^= t << offset; + } + + /** + * Shortcut functions to the cipher's object interface. + * + * @example + * + * var ciphertext = CryptoJS.DES.encrypt(message, key, cfg); + * var plaintext = CryptoJS.DES.decrypt(ciphertext, key, cfg); + */ + C.DES = BlockCipher._createHelper(DES); + + /** + * Triple-DES block cipher algorithm. + */ + var TripleDES = C_algo.TripleDES = BlockCipher.extend({ + _doReset: function () { + // Shortcuts + var key = this._key; + var keyWords = key.words; + // Make sure the key length is valid (64, 128 or >= 192 bit) + if (keyWords.length !== 2 && keyWords.length !== 4 && keyWords.length < 6) { + throw new Error('Invalid key length - 3DES requires the key length to be 64, 128, 192 or >192.'); + } + + // Extend the key according to the keying options defined in 3DES standard + var key1 = keyWords.slice(0, 2); + var key2 = keyWords.length < 4 ? keyWords.slice(0, 2) : keyWords.slice(2, 4); + var key3 = keyWords.length < 6 ? keyWords.slice(0, 2) : keyWords.slice(4, 6); + + // Create DES instances + this._des1 = DES.createEncryptor(WordArray.create(key1)); + this._des2 = DES.createEncryptor(WordArray.create(key2)); + this._des3 = DES.createEncryptor(WordArray.create(key3)); + }, + + encryptBlock: function (M, offset) { + this._des1.encryptBlock(M, offset); + this._des2.decryptBlock(M, offset); + this._des3.encryptBlock(M, offset); + }, + + decryptBlock: function (M, offset) { + this._des3.decryptBlock(M, offset); + this._des2.encryptBlock(M, offset); + this._des1.decryptBlock(M, offset); + }, + + keySize: 192/32, + + ivSize: 64/32, + + blockSize: 64/32 + }); + + /** + * Shortcut functions to the cipher's object interface. + * + * @example + * + * var ciphertext = CryptoJS.TripleDES.encrypt(message, key, cfg); + * var plaintext = CryptoJS.TripleDES.decrypt(ciphertext, key, cfg); + */ + C.TripleDES = BlockCipher._createHelper(TripleDES); + }()); + + + (function () { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var StreamCipher = C_lib.StreamCipher; + var C_algo = C.algo; + + /** + * RC4 stream cipher algorithm. + */ + var RC4 = C_algo.RC4 = StreamCipher.extend({ + _doReset: function () { + // Shortcuts + var key = this._key; + var keyWords = key.words; + var keySigBytes = key.sigBytes; + + // Init sbox + var S = this._S = []; + for (var i = 0; i < 256; i++) { + S[i] = i; + } + + // Key setup + for (var i = 0, j = 0; i < 256; i++) { + var keyByteIndex = i % keySigBytes; + var keyByte = (keyWords[keyByteIndex >>> 2] >>> (24 - (keyByteIndex % 4) * 8)) & 0xff; + + j = (j + S[i] + keyByte) % 256; + + // Swap + var t = S[i]; + S[i] = S[j]; + S[j] = t; + } + + // Counters + this._i = this._j = 0; + }, + + _doProcessBlock: function (M, offset) { + M[offset] ^= generateKeystreamWord.call(this); + }, + + keySize: 256/32, + + ivSize: 0 + }); + + function generateKeystreamWord() { + // Shortcuts + var S = this._S; + var i = this._i; + var j = this._j; + + // Generate keystream word + var keystreamWord = 0; + for (var n = 0; n < 4; n++) { + i = (i + 1) % 256; + j = (j + S[i]) % 256; + + // Swap + var t = S[i]; + S[i] = S[j]; + S[j] = t; + + keystreamWord |= S[(S[i] + S[j]) % 256] << (24 - n * 8); + } + + // Update counters + this._i = i; + this._j = j; + + return keystreamWord; + } + + /** + * Shortcut functions to the cipher's object interface. + * + * @example + * + * var ciphertext = CryptoJS.RC4.encrypt(message, key, cfg); + * var plaintext = CryptoJS.RC4.decrypt(ciphertext, key, cfg); + */ + C.RC4 = StreamCipher._createHelper(RC4); + + /** + * Modified RC4 stream cipher algorithm. + */ + var RC4Drop = C_algo.RC4Drop = RC4.extend({ + /** + * Configuration options. + * + * @property {number} drop The number of keystream words to drop. Default 192 + */ + cfg: RC4.cfg.extend({ + drop: 192 + }), + + _doReset: function () { + RC4._doReset.call(this); + + // Drop + for (var i = this.cfg.drop; i > 0; i--) { + generateKeystreamWord.call(this); + } + } + }); + + /** + * Shortcut functions to the cipher's object interface. + * + * @example + * + * var ciphertext = CryptoJS.RC4Drop.encrypt(message, key, cfg); + * var plaintext = CryptoJS.RC4Drop.decrypt(ciphertext, key, cfg); + */ + C.RC4Drop = StreamCipher._createHelper(RC4Drop); + }()); + + + (function () { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var StreamCipher = C_lib.StreamCipher; + var C_algo = C.algo; + + // Reusable objects + var S = []; + var C_ = []; + var G = []; + + /** + * Rabbit stream cipher algorithm + */ + var Rabbit = C_algo.Rabbit = StreamCipher.extend({ + _doReset: function () { + // Shortcuts + var K = this._key.words; + var iv = this.cfg.iv; + + // Swap endian + for (var i = 0; i < 4; i++) { + K[i] = (((K[i] << 8) | (K[i] >>> 24)) & 0x00ff00ff) | + (((K[i] << 24) | (K[i] >>> 8)) & 0xff00ff00); + } + + // Generate initial state values + var X = this._X = [ + K[0], (K[3] << 16) | (K[2] >>> 16), + K[1], (K[0] << 16) | (K[3] >>> 16), + K[2], (K[1] << 16) | (K[0] >>> 16), + K[3], (K[2] << 16) | (K[1] >>> 16) + ]; + + // Generate initial counter values + var C = this._C = [ + (K[2] << 16) | (K[2] >>> 16), (K[0] & 0xffff0000) | (K[1] & 0x0000ffff), + (K[3] << 16) | (K[3] >>> 16), (K[1] & 0xffff0000) | (K[2] & 0x0000ffff), + (K[0] << 16) | (K[0] >>> 16), (K[2] & 0xffff0000) | (K[3] & 0x0000ffff), + (K[1] << 16) | (K[1] >>> 16), (K[3] & 0xffff0000) | (K[0] & 0x0000ffff) + ]; + + // Carry bit + this._b = 0; + + // Iterate the system four times + for (var i = 0; i < 4; i++) { + nextState.call(this); + } + + // Modify the counters + for (var i = 0; i < 8; i++) { + C[i] ^= X[(i + 4) & 7]; + } + + // IV setup + if (iv) { + // Shortcuts + var IV = iv.words; + var IV_0 = IV[0]; + var IV_1 = IV[1]; + + // Generate four subvectors + var i0 = (((IV_0 << 8) | (IV_0 >>> 24)) & 0x00ff00ff) | (((IV_0 << 24) | (IV_0 >>> 8)) & 0xff00ff00); + var i2 = (((IV_1 << 8) | (IV_1 >>> 24)) & 0x00ff00ff) | (((IV_1 << 24) | (IV_1 >>> 8)) & 0xff00ff00); + var i1 = (i0 >>> 16) | (i2 & 0xffff0000); + var i3 = (i2 << 16) | (i0 & 0x0000ffff); + + // Modify counter values + C[0] ^= i0; + C[1] ^= i1; + C[2] ^= i2; + C[3] ^= i3; + C[4] ^= i0; + C[5] ^= i1; + C[6] ^= i2; + C[7] ^= i3; + + // Iterate the system four times + for (var i = 0; i < 4; i++) { + nextState.call(this); + } + } + }, + + _doProcessBlock: function (M, offset) { + // Shortcut + var X = this._X; + + // Iterate the system + nextState.call(this); + + // Generate four keystream words + S[0] = X[0] ^ (X[5] >>> 16) ^ (X[3] << 16); + S[1] = X[2] ^ (X[7] >>> 16) ^ (X[5] << 16); + S[2] = X[4] ^ (X[1] >>> 16) ^ (X[7] << 16); + S[3] = X[6] ^ (X[3] >>> 16) ^ (X[1] << 16); + + for (var i = 0; i < 4; i++) { + // Swap endian + S[i] = (((S[i] << 8) | (S[i] >>> 24)) & 0x00ff00ff) | + (((S[i] << 24) | (S[i] >>> 8)) & 0xff00ff00); + + // Encrypt + M[offset + i] ^= S[i]; + } + }, + + blockSize: 128/32, + + ivSize: 64/32 + }); + + function nextState() { + // Shortcuts + var X = this._X; + var C = this._C; + + // Save old counter values + for (var i = 0; i < 8; i++) { + C_[i] = C[i]; + } + + // Calculate new counter values + C[0] = (C[0] + 0x4d34d34d + this._b) | 0; + C[1] = (C[1] + 0xd34d34d3 + ((C[0] >>> 0) < (C_[0] >>> 0) ? 1 : 0)) | 0; + C[2] = (C[2] + 0x34d34d34 + ((C[1] >>> 0) < (C_[1] >>> 0) ? 1 : 0)) | 0; + C[3] = (C[3] + 0x4d34d34d + ((C[2] >>> 0) < (C_[2] >>> 0) ? 1 : 0)) | 0; + C[4] = (C[4] + 0xd34d34d3 + ((C[3] >>> 0) < (C_[3] >>> 0) ? 1 : 0)) | 0; + C[5] = (C[5] + 0x34d34d34 + ((C[4] >>> 0) < (C_[4] >>> 0) ? 1 : 0)) | 0; + C[6] = (C[6] + 0x4d34d34d + ((C[5] >>> 0) < (C_[5] >>> 0) ? 1 : 0)) | 0; + C[7] = (C[7] + 0xd34d34d3 + ((C[6] >>> 0) < (C_[6] >>> 0) ? 1 : 0)) | 0; + this._b = (C[7] >>> 0) < (C_[7] >>> 0) ? 1 : 0; + + // Calculate the g-values + for (var i = 0; i < 8; i++) { + var gx = X[i] + C[i]; + + // Construct high and low argument for squaring + var ga = gx & 0xffff; + var gb = gx >>> 16; + + // Calculate high and low result of squaring + var gh = ((((ga * ga) >>> 17) + ga * gb) >>> 15) + gb * gb; + var gl = (((gx & 0xffff0000) * gx) | 0) + (((gx & 0x0000ffff) * gx) | 0); + + // High XOR low + G[i] = gh ^ gl; + } + + // Calculate new state values + X[0] = (G[0] + ((G[7] << 16) | (G[7] >>> 16)) + ((G[6] << 16) | (G[6] >>> 16))) | 0; + X[1] = (G[1] + ((G[0] << 8) | (G[0] >>> 24)) + G[7]) | 0; + X[2] = (G[2] + ((G[1] << 16) | (G[1] >>> 16)) + ((G[0] << 16) | (G[0] >>> 16))) | 0; + X[3] = (G[3] + ((G[2] << 8) | (G[2] >>> 24)) + G[1]) | 0; + X[4] = (G[4] + ((G[3] << 16) | (G[3] >>> 16)) + ((G[2] << 16) | (G[2] >>> 16))) | 0; + X[5] = (G[5] + ((G[4] << 8) | (G[4] >>> 24)) + G[3]) | 0; + X[6] = (G[6] + ((G[5] << 16) | (G[5] >>> 16)) + ((G[4] << 16) | (G[4] >>> 16))) | 0; + X[7] = (G[7] + ((G[6] << 8) | (G[6] >>> 24)) + G[5]) | 0; + } + + /** + * Shortcut functions to the cipher's object interface. + * + * @example + * + * var ciphertext = CryptoJS.Rabbit.encrypt(message, key, cfg); + * var plaintext = CryptoJS.Rabbit.decrypt(ciphertext, key, cfg); + */ + C.Rabbit = StreamCipher._createHelper(Rabbit); + }()); + + + (function () { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var StreamCipher = C_lib.StreamCipher; + var C_algo = C.algo; + + // Reusable objects + var S = []; + var C_ = []; + var G = []; + + /** + * Rabbit stream cipher algorithm. + * + * This is a legacy version that neglected to convert the key to little-endian. + * This error doesn't affect the cipher's security, + * but it does affect its compatibility with other implementations. + */ + var RabbitLegacy = C_algo.RabbitLegacy = StreamCipher.extend({ + _doReset: function () { + // Shortcuts + var K = this._key.words; + var iv = this.cfg.iv; + + // Generate initial state values + var X = this._X = [ + K[0], (K[3] << 16) | (K[2] >>> 16), + K[1], (K[0] << 16) | (K[3] >>> 16), + K[2], (K[1] << 16) | (K[0] >>> 16), + K[3], (K[2] << 16) | (K[1] >>> 16) + ]; + + // Generate initial counter values + var C = this._C = [ + (K[2] << 16) | (K[2] >>> 16), (K[0] & 0xffff0000) | (K[1] & 0x0000ffff), + (K[3] << 16) | (K[3] >>> 16), (K[1] & 0xffff0000) | (K[2] & 0x0000ffff), + (K[0] << 16) | (K[0] >>> 16), (K[2] & 0xffff0000) | (K[3] & 0x0000ffff), + (K[1] << 16) | (K[1] >>> 16), (K[3] & 0xffff0000) | (K[0] & 0x0000ffff) + ]; + + // Carry bit + this._b = 0; + + // Iterate the system four times + for (var i = 0; i < 4; i++) { + nextState.call(this); + } + + // Modify the counters + for (var i = 0; i < 8; i++) { + C[i] ^= X[(i + 4) & 7]; + } + + // IV setup + if (iv) { + // Shortcuts + var IV = iv.words; + var IV_0 = IV[0]; + var IV_1 = IV[1]; + + // Generate four subvectors + var i0 = (((IV_0 << 8) | (IV_0 >>> 24)) & 0x00ff00ff) | (((IV_0 << 24) | (IV_0 >>> 8)) & 0xff00ff00); + var i2 = (((IV_1 << 8) | (IV_1 >>> 24)) & 0x00ff00ff) | (((IV_1 << 24) | (IV_1 >>> 8)) & 0xff00ff00); + var i1 = (i0 >>> 16) | (i2 & 0xffff0000); + var i3 = (i2 << 16) | (i0 & 0x0000ffff); + + // Modify counter values + C[0] ^= i0; + C[1] ^= i1; + C[2] ^= i2; + C[3] ^= i3; + C[4] ^= i0; + C[5] ^= i1; + C[6] ^= i2; + C[7] ^= i3; + + // Iterate the system four times + for (var i = 0; i < 4; i++) { + nextState.call(this); + } + } + }, + + _doProcessBlock: function (M, offset) { + // Shortcut + var X = this._X; + + // Iterate the system + nextState.call(this); + + // Generate four keystream words + S[0] = X[0] ^ (X[5] >>> 16) ^ (X[3] << 16); + S[1] = X[2] ^ (X[7] >>> 16) ^ (X[5] << 16); + S[2] = X[4] ^ (X[1] >>> 16) ^ (X[7] << 16); + S[3] = X[6] ^ (X[3] >>> 16) ^ (X[1] << 16); + + for (var i = 0; i < 4; i++) { + // Swap endian + S[i] = (((S[i] << 8) | (S[i] >>> 24)) & 0x00ff00ff) | + (((S[i] << 24) | (S[i] >>> 8)) & 0xff00ff00); + + // Encrypt + M[offset + i] ^= S[i]; + } + }, + + blockSize: 128/32, + + ivSize: 64/32 + }); + + function nextState() { + // Shortcuts + var X = this._X; + var C = this._C; + + // Save old counter values + for (var i = 0; i < 8; i++) { + C_[i] = C[i]; + } + + // Calculate new counter values + C[0] = (C[0] + 0x4d34d34d + this._b) | 0; + C[1] = (C[1] + 0xd34d34d3 + ((C[0] >>> 0) < (C_[0] >>> 0) ? 1 : 0)) | 0; + C[2] = (C[2] + 0x34d34d34 + ((C[1] >>> 0) < (C_[1] >>> 0) ? 1 : 0)) | 0; + C[3] = (C[3] + 0x4d34d34d + ((C[2] >>> 0) < (C_[2] >>> 0) ? 1 : 0)) | 0; + C[4] = (C[4] + 0xd34d34d3 + ((C[3] >>> 0) < (C_[3] >>> 0) ? 1 : 0)) | 0; + C[5] = (C[5] + 0x34d34d34 + ((C[4] >>> 0) < (C_[4] >>> 0) ? 1 : 0)) | 0; + C[6] = (C[6] + 0x4d34d34d + ((C[5] >>> 0) < (C_[5] >>> 0) ? 1 : 0)) | 0; + C[7] = (C[7] + 0xd34d34d3 + ((C[6] >>> 0) < (C_[6] >>> 0) ? 1 : 0)) | 0; + this._b = (C[7] >>> 0) < (C_[7] >>> 0) ? 1 : 0; + + // Calculate the g-values + for (var i = 0; i < 8; i++) { + var gx = X[i] + C[i]; + + // Construct high and low argument for squaring + var ga = gx & 0xffff; + var gb = gx >>> 16; + + // Calculate high and low result of squaring + var gh = ((((ga * ga) >>> 17) + ga * gb) >>> 15) + gb * gb; + var gl = (((gx & 0xffff0000) * gx) | 0) + (((gx & 0x0000ffff) * gx) | 0); + + // High XOR low + G[i] = gh ^ gl; + } + + // Calculate new state values + X[0] = (G[0] + ((G[7] << 16) | (G[7] >>> 16)) + ((G[6] << 16) | (G[6] >>> 16))) | 0; + X[1] = (G[1] + ((G[0] << 8) | (G[0] >>> 24)) + G[7]) | 0; + X[2] = (G[2] + ((G[1] << 16) | (G[1] >>> 16)) + ((G[0] << 16) | (G[0] >>> 16))) | 0; + X[3] = (G[3] + ((G[2] << 8) | (G[2] >>> 24)) + G[1]) | 0; + X[4] = (G[4] + ((G[3] << 16) | (G[3] >>> 16)) + ((G[2] << 16) | (G[2] >>> 16))) | 0; + X[5] = (G[5] + ((G[4] << 8) | (G[4] >>> 24)) + G[3]) | 0; + X[6] = (G[6] + ((G[5] << 16) | (G[5] >>> 16)) + ((G[4] << 16) | (G[4] >>> 16))) | 0; + X[7] = (G[7] + ((G[6] << 8) | (G[6] >>> 24)) + G[5]) | 0; + } + + /** + * Shortcut functions to the cipher's object interface. + * + * @example + * + * var ciphertext = CryptoJS.RabbitLegacy.encrypt(message, key, cfg); + * var plaintext = CryptoJS.RabbitLegacy.decrypt(ciphertext, key, cfg); + */ + C.RabbitLegacy = StreamCipher._createHelper(RabbitLegacy); + }()); + + + (function () { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var BlockCipher = C_lib.BlockCipher; + var C_algo = C.algo; + + const N = 16; + + //Origin pbox and sbox, derived from PI + const ORIG_P = [ + 0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344, + 0xA4093822, 0x299F31D0, 0x082EFA98, 0xEC4E6C89, + 0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C, + 0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917, + 0x9216D5D9, 0x8979FB1B + ]; + + const ORIG_S = [ + [ 0xD1310BA6, 0x98DFB5AC, 0x2FFD72DB, 0xD01ADFB7, + 0xB8E1AFED, 0x6A267E96, 0xBA7C9045, 0xF12C7F99, + 0x24A19947, 0xB3916CF7, 0x0801F2E2, 0x858EFC16, + 0x636920D8, 0x71574E69, 0xA458FEA3, 0xF4933D7E, + 0x0D95748F, 0x728EB658, 0x718BCD58, 0x82154AEE, + 0x7B54A41D, 0xC25A59B5, 0x9C30D539, 0x2AF26013, + 0xC5D1B023, 0x286085F0, 0xCA417918, 0xB8DB38EF, + 0x8E79DCB0, 0x603A180E, 0x6C9E0E8B, 0xB01E8A3E, + 0xD71577C1, 0xBD314B27, 0x78AF2FDA, 0x55605C60, + 0xE65525F3, 0xAA55AB94, 0x57489862, 0x63E81440, + 0x55CA396A, 0x2AAB10B6, 0xB4CC5C34, 0x1141E8CE, + 0xA15486AF, 0x7C72E993, 0xB3EE1411, 0x636FBC2A, + 0x2BA9C55D, 0x741831F6, 0xCE5C3E16, 0x9B87931E, + 0xAFD6BA33, 0x6C24CF5C, 0x7A325381, 0x28958677, + 0x3B8F4898, 0x6B4BB9AF, 0xC4BFE81B, 0x66282193, + 0x61D809CC, 0xFB21A991, 0x487CAC60, 0x5DEC8032, + 0xEF845D5D, 0xE98575B1, 0xDC262302, 0xEB651B88, + 0x23893E81, 0xD396ACC5, 0x0F6D6FF3, 0x83F44239, + 0x2E0B4482, 0xA4842004, 0x69C8F04A, 0x9E1F9B5E, + 0x21C66842, 0xF6E96C9A, 0x670C9C61, 0xABD388F0, + 0x6A51A0D2, 0xD8542F68, 0x960FA728, 0xAB5133A3, + 0x6EEF0B6C, 0x137A3BE4, 0xBA3BF050, 0x7EFB2A98, + 0xA1F1651D, 0x39AF0176, 0x66CA593E, 0x82430E88, + 0x8CEE8619, 0x456F9FB4, 0x7D84A5C3, 0x3B8B5EBE, + 0xE06F75D8, 0x85C12073, 0x401A449F, 0x56C16AA6, + 0x4ED3AA62, 0x363F7706, 0x1BFEDF72, 0x429B023D, + 0x37D0D724, 0xD00A1248, 0xDB0FEAD3, 0x49F1C09B, + 0x075372C9, 0x80991B7B, 0x25D479D8, 0xF6E8DEF7, + 0xE3FE501A, 0xB6794C3B, 0x976CE0BD, 0x04C006BA, + 0xC1A94FB6, 0x409F60C4, 0x5E5C9EC2, 0x196A2463, + 0x68FB6FAF, 0x3E6C53B5, 0x1339B2EB, 0x3B52EC6F, + 0x6DFC511F, 0x9B30952C, 0xCC814544, 0xAF5EBD09, + 0xBEE3D004, 0xDE334AFD, 0x660F2807, 0x192E4BB3, + 0xC0CBA857, 0x45C8740F, 0xD20B5F39, 0xB9D3FBDB, + 0x5579C0BD, 0x1A60320A, 0xD6A100C6, 0x402C7279, + 0x679F25FE, 0xFB1FA3CC, 0x8EA5E9F8, 0xDB3222F8, + 0x3C7516DF, 0xFD616B15, 0x2F501EC8, 0xAD0552AB, + 0x323DB5FA, 0xFD238760, 0x53317B48, 0x3E00DF82, + 0x9E5C57BB, 0xCA6F8CA0, 0x1A87562E, 0xDF1769DB, + 0xD542A8F6, 0x287EFFC3, 0xAC6732C6, 0x8C4F5573, + 0x695B27B0, 0xBBCA58C8, 0xE1FFA35D, 0xB8F011A0, + 0x10FA3D98, 0xFD2183B8, 0x4AFCB56C, 0x2DD1D35B, + 0x9A53E479, 0xB6F84565, 0xD28E49BC, 0x4BFB9790, + 0xE1DDF2DA, 0xA4CB7E33, 0x62FB1341, 0xCEE4C6E8, + 0xEF20CADA, 0x36774C01, 0xD07E9EFE, 0x2BF11FB4, + 0x95DBDA4D, 0xAE909198, 0xEAAD8E71, 0x6B93D5A0, + 0xD08ED1D0, 0xAFC725E0, 0x8E3C5B2F, 0x8E7594B7, + 0x8FF6E2FB, 0xF2122B64, 0x8888B812, 0x900DF01C, + 0x4FAD5EA0, 0x688FC31C, 0xD1CFF191, 0xB3A8C1AD, + 0x2F2F2218, 0xBE0E1777, 0xEA752DFE, 0x8B021FA1, + 0xE5A0CC0F, 0xB56F74E8, 0x18ACF3D6, 0xCE89E299, + 0xB4A84FE0, 0xFD13E0B7, 0x7CC43B81, 0xD2ADA8D9, + 0x165FA266, 0x80957705, 0x93CC7314, 0x211A1477, + 0xE6AD2065, 0x77B5FA86, 0xC75442F5, 0xFB9D35CF, + 0xEBCDAF0C, 0x7B3E89A0, 0xD6411BD3, 0xAE1E7E49, + 0x00250E2D, 0x2071B35E, 0x226800BB, 0x57B8E0AF, + 0x2464369B, 0xF009B91E, 0x5563911D, 0x59DFA6AA, + 0x78C14389, 0xD95A537F, 0x207D5BA2, 0x02E5B9C5, + 0x83260376, 0x6295CFA9, 0x11C81968, 0x4E734A41, + 0xB3472DCA, 0x7B14A94A, 0x1B510052, 0x9A532915, + 0xD60F573F, 0xBC9BC6E4, 0x2B60A476, 0x81E67400, + 0x08BA6FB5, 0x571BE91F, 0xF296EC6B, 0x2A0DD915, + 0xB6636521, 0xE7B9F9B6, 0xFF34052E, 0xC5855664, + 0x53B02D5D, 0xA99F8FA1, 0x08BA4799, 0x6E85076A ], + [ 0x4B7A70E9, 0xB5B32944, 0xDB75092E, 0xC4192623, + 0xAD6EA6B0, 0x49A7DF7D, 0x9CEE60B8, 0x8FEDB266, + 0xECAA8C71, 0x699A17FF, 0x5664526C, 0xC2B19EE1, + 0x193602A5, 0x75094C29, 0xA0591340, 0xE4183A3E, + 0x3F54989A, 0x5B429D65, 0x6B8FE4D6, 0x99F73FD6, + 0xA1D29C07, 0xEFE830F5, 0x4D2D38E6, 0xF0255DC1, + 0x4CDD2086, 0x8470EB26, 0x6382E9C6, 0x021ECC5E, + 0x09686B3F, 0x3EBAEFC9, 0x3C971814, 0x6B6A70A1, + 0x687F3584, 0x52A0E286, 0xB79C5305, 0xAA500737, + 0x3E07841C, 0x7FDEAE5C, 0x8E7D44EC, 0x5716F2B8, + 0xB03ADA37, 0xF0500C0D, 0xF01C1F04, 0x0200B3FF, + 0xAE0CF51A, 0x3CB574B2, 0x25837A58, 0xDC0921BD, + 0xD19113F9, 0x7CA92FF6, 0x94324773, 0x22F54701, + 0x3AE5E581, 0x37C2DADC, 0xC8B57634, 0x9AF3DDA7, + 0xA9446146, 0x0FD0030E, 0xECC8C73E, 0xA4751E41, + 0xE238CD99, 0x3BEA0E2F, 0x3280BBA1, 0x183EB331, + 0x4E548B38, 0x4F6DB908, 0x6F420D03, 0xF60A04BF, + 0x2CB81290, 0x24977C79, 0x5679B072, 0xBCAF89AF, + 0xDE9A771F, 0xD9930810, 0xB38BAE12, 0xDCCF3F2E, + 0x5512721F, 0x2E6B7124, 0x501ADDE6, 0x9F84CD87, + 0x7A584718, 0x7408DA17, 0xBC9F9ABC, 0xE94B7D8C, + 0xEC7AEC3A, 0xDB851DFA, 0x63094366, 0xC464C3D2, + 0xEF1C1847, 0x3215D908, 0xDD433B37, 0x24C2BA16, + 0x12A14D43, 0x2A65C451, 0x50940002, 0x133AE4DD, + 0x71DFF89E, 0x10314E55, 0x81AC77D6, 0x5F11199B, + 0x043556F1, 0xD7A3C76B, 0x3C11183B, 0x5924A509, + 0xF28FE6ED, 0x97F1FBFA, 0x9EBABF2C, 0x1E153C6E, + 0x86E34570, 0xEAE96FB1, 0x860E5E0A, 0x5A3E2AB3, + 0x771FE71C, 0x4E3D06FA, 0x2965DCB9, 0x99E71D0F, + 0x803E89D6, 0x5266C825, 0x2E4CC978, 0x9C10B36A, + 0xC6150EBA, 0x94E2EA78, 0xA5FC3C53, 0x1E0A2DF4, + 0xF2F74EA7, 0x361D2B3D, 0x1939260F, 0x19C27960, + 0x5223A708, 0xF71312B6, 0xEBADFE6E, 0xEAC31F66, + 0xE3BC4595, 0xA67BC883, 0xB17F37D1, 0x018CFF28, + 0xC332DDEF, 0xBE6C5AA5, 0x65582185, 0x68AB9802, + 0xEECEA50F, 0xDB2F953B, 0x2AEF7DAD, 0x5B6E2F84, + 0x1521B628, 0x29076170, 0xECDD4775, 0x619F1510, + 0x13CCA830, 0xEB61BD96, 0x0334FE1E, 0xAA0363CF, + 0xB5735C90, 0x4C70A239, 0xD59E9E0B, 0xCBAADE14, + 0xEECC86BC, 0x60622CA7, 0x9CAB5CAB, 0xB2F3846E, + 0x648B1EAF, 0x19BDF0CA, 0xA02369B9, 0x655ABB50, + 0x40685A32, 0x3C2AB4B3, 0x319EE9D5, 0xC021B8F7, + 0x9B540B19, 0x875FA099, 0x95F7997E, 0x623D7DA8, + 0xF837889A, 0x97E32D77, 0x11ED935F, 0x16681281, + 0x0E358829, 0xC7E61FD6, 0x96DEDFA1, 0x7858BA99, + 0x57F584A5, 0x1B227263, 0x9B83C3FF, 0x1AC24696, + 0xCDB30AEB, 0x532E3054, 0x8FD948E4, 0x6DBC3128, + 0x58EBF2EF, 0x34C6FFEA, 0xFE28ED61, 0xEE7C3C73, + 0x5D4A14D9, 0xE864B7E3, 0x42105D14, 0x203E13E0, + 0x45EEE2B6, 0xA3AAABEA, 0xDB6C4F15, 0xFACB4FD0, + 0xC742F442, 0xEF6ABBB5, 0x654F3B1D, 0x41CD2105, + 0xD81E799E, 0x86854DC7, 0xE44B476A, 0x3D816250, + 0xCF62A1F2, 0x5B8D2646, 0xFC8883A0, 0xC1C7B6A3, + 0x7F1524C3, 0x69CB7492, 0x47848A0B, 0x5692B285, + 0x095BBF00, 0xAD19489D, 0x1462B174, 0x23820E00, + 0x58428D2A, 0x0C55F5EA, 0x1DADF43E, 0x233F7061, + 0x3372F092, 0x8D937E41, 0xD65FECF1, 0x6C223BDB, + 0x7CDE3759, 0xCBEE7460, 0x4085F2A7, 0xCE77326E, + 0xA6078084, 0x19F8509E, 0xE8EFD855, 0x61D99735, + 0xA969A7AA, 0xC50C06C2, 0x5A04ABFC, 0x800BCADC, + 0x9E447A2E, 0xC3453484, 0xFDD56705, 0x0E1E9EC9, + 0xDB73DBD3, 0x105588CD, 0x675FDA79, 0xE3674340, + 0xC5C43465, 0x713E38D8, 0x3D28F89E, 0xF16DFF20, + 0x153E21E7, 0x8FB03D4A, 0xE6E39F2B, 0xDB83ADF7 ], + [ 0xE93D5A68, 0x948140F7, 0xF64C261C, 0x94692934, + 0x411520F7, 0x7602D4F7, 0xBCF46B2E, 0xD4A20068, + 0xD4082471, 0x3320F46A, 0x43B7D4B7, 0x500061AF, + 0x1E39F62E, 0x97244546, 0x14214F74, 0xBF8B8840, + 0x4D95FC1D, 0x96B591AF, 0x70F4DDD3, 0x66A02F45, + 0xBFBC09EC, 0x03BD9785, 0x7FAC6DD0, 0x31CB8504, + 0x96EB27B3, 0x55FD3941, 0xDA2547E6, 0xABCA0A9A, + 0x28507825, 0x530429F4, 0x0A2C86DA, 0xE9B66DFB, + 0x68DC1462, 0xD7486900, 0x680EC0A4, 0x27A18DEE, + 0x4F3FFEA2, 0xE887AD8C, 0xB58CE006, 0x7AF4D6B6, + 0xAACE1E7C, 0xD3375FEC, 0xCE78A399, 0x406B2A42, + 0x20FE9E35, 0xD9F385B9, 0xEE39D7AB, 0x3B124E8B, + 0x1DC9FAF7, 0x4B6D1856, 0x26A36631, 0xEAE397B2, + 0x3A6EFA74, 0xDD5B4332, 0x6841E7F7, 0xCA7820FB, + 0xFB0AF54E, 0xD8FEB397, 0x454056AC, 0xBA489527, + 0x55533A3A, 0x20838D87, 0xFE6BA9B7, 0xD096954B, + 0x55A867BC, 0xA1159A58, 0xCCA92963, 0x99E1DB33, + 0xA62A4A56, 0x3F3125F9, 0x5EF47E1C, 0x9029317C, + 0xFDF8E802, 0x04272F70, 0x80BB155C, 0x05282CE3, + 0x95C11548, 0xE4C66D22, 0x48C1133F, 0xC70F86DC, + 0x07F9C9EE, 0x41041F0F, 0x404779A4, 0x5D886E17, + 0x325F51EB, 0xD59BC0D1, 0xF2BCC18F, 0x41113564, + 0x257B7834, 0x602A9C60, 0xDFF8E8A3, 0x1F636C1B, + 0x0E12B4C2, 0x02E1329E, 0xAF664FD1, 0xCAD18115, + 0x6B2395E0, 0x333E92E1, 0x3B240B62, 0xEEBEB922, + 0x85B2A20E, 0xE6BA0D99, 0xDE720C8C, 0x2DA2F728, + 0xD0127845, 0x95B794FD, 0x647D0862, 0xE7CCF5F0, + 0x5449A36F, 0x877D48FA, 0xC39DFD27, 0xF33E8D1E, + 0x0A476341, 0x992EFF74, 0x3A6F6EAB, 0xF4F8FD37, + 0xA812DC60, 0xA1EBDDF8, 0x991BE14C, 0xDB6E6B0D, + 0xC67B5510, 0x6D672C37, 0x2765D43B, 0xDCD0E804, + 0xF1290DC7, 0xCC00FFA3, 0xB5390F92, 0x690FED0B, + 0x667B9FFB, 0xCEDB7D9C, 0xA091CF0B, 0xD9155EA3, + 0xBB132F88, 0x515BAD24, 0x7B9479BF, 0x763BD6EB, + 0x37392EB3, 0xCC115979, 0x8026E297, 0xF42E312D, + 0x6842ADA7, 0xC66A2B3B, 0x12754CCC, 0x782EF11C, + 0x6A124237, 0xB79251E7, 0x06A1BBE6, 0x4BFB6350, + 0x1A6B1018, 0x11CAEDFA, 0x3D25BDD8, 0xE2E1C3C9, + 0x44421659, 0x0A121386, 0xD90CEC6E, 0xD5ABEA2A, + 0x64AF674E, 0xDA86A85F, 0xBEBFE988, 0x64E4C3FE, + 0x9DBC8057, 0xF0F7C086, 0x60787BF8, 0x6003604D, + 0xD1FD8346, 0xF6381FB0, 0x7745AE04, 0xD736FCCC, + 0x83426B33, 0xF01EAB71, 0xB0804187, 0x3C005E5F, + 0x77A057BE, 0xBDE8AE24, 0x55464299, 0xBF582E61, + 0x4E58F48F, 0xF2DDFDA2, 0xF474EF38, 0x8789BDC2, + 0x5366F9C3, 0xC8B38E74, 0xB475F255, 0x46FCD9B9, + 0x7AEB2661, 0x8B1DDF84, 0x846A0E79, 0x915F95E2, + 0x466E598E, 0x20B45770, 0x8CD55591, 0xC902DE4C, + 0xB90BACE1, 0xBB8205D0, 0x11A86248, 0x7574A99E, + 0xB77F19B6, 0xE0A9DC09, 0x662D09A1, 0xC4324633, + 0xE85A1F02, 0x09F0BE8C, 0x4A99A025, 0x1D6EFE10, + 0x1AB93D1D, 0x0BA5A4DF, 0xA186F20F, 0x2868F169, + 0xDCB7DA83, 0x573906FE, 0xA1E2CE9B, 0x4FCD7F52, + 0x50115E01, 0xA70683FA, 0xA002B5C4, 0x0DE6D027, + 0x9AF88C27, 0x773F8641, 0xC3604C06, 0x61A806B5, + 0xF0177A28, 0xC0F586E0, 0x006058AA, 0x30DC7D62, + 0x11E69ED7, 0x2338EA63, 0x53C2DD94, 0xC2C21634, + 0xBBCBEE56, 0x90BCB6DE, 0xEBFC7DA1, 0xCE591D76, + 0x6F05E409, 0x4B7C0188, 0x39720A3D, 0x7C927C24, + 0x86E3725F, 0x724D9DB9, 0x1AC15BB4, 0xD39EB8FC, + 0xED545578, 0x08FCA5B5, 0xD83D7CD3, 0x4DAD0FC4, + 0x1E50EF5E, 0xB161E6F8, 0xA28514D9, 0x6C51133C, + 0x6FD5C7E7, 0x56E14EC4, 0x362ABFCE, 0xDDC6C837, + 0xD79A3234, 0x92638212, 0x670EFA8E, 0x406000E0 ], + [ 0x3A39CE37, 0xD3FAF5CF, 0xABC27737, 0x5AC52D1B, + 0x5CB0679E, 0x4FA33742, 0xD3822740, 0x99BC9BBE, + 0xD5118E9D, 0xBF0F7315, 0xD62D1C7E, 0xC700C47B, + 0xB78C1B6B, 0x21A19045, 0xB26EB1BE, 0x6A366EB4, + 0x5748AB2F, 0xBC946E79, 0xC6A376D2, 0x6549C2C8, + 0x530FF8EE, 0x468DDE7D, 0xD5730A1D, 0x4CD04DC6, + 0x2939BBDB, 0xA9BA4650, 0xAC9526E8, 0xBE5EE304, + 0xA1FAD5F0, 0x6A2D519A, 0x63EF8CE2, 0x9A86EE22, + 0xC089C2B8, 0x43242EF6, 0xA51E03AA, 0x9CF2D0A4, + 0x83C061BA, 0x9BE96A4D, 0x8FE51550, 0xBA645BD6, + 0x2826A2F9, 0xA73A3AE1, 0x4BA99586, 0xEF5562E9, + 0xC72FEFD3, 0xF752F7DA, 0x3F046F69, 0x77FA0A59, + 0x80E4A915, 0x87B08601, 0x9B09E6AD, 0x3B3EE593, + 0xE990FD5A, 0x9E34D797, 0x2CF0B7D9, 0x022B8B51, + 0x96D5AC3A, 0x017DA67D, 0xD1CF3ED6, 0x7C7D2D28, + 0x1F9F25CF, 0xADF2B89B, 0x5AD6B472, 0x5A88F54C, + 0xE029AC71, 0xE019A5E6, 0x47B0ACFD, 0xED93FA9B, + 0xE8D3C48D, 0x283B57CC, 0xF8D56629, 0x79132E28, + 0x785F0191, 0xED756055, 0xF7960E44, 0xE3D35E8C, + 0x15056DD4, 0x88F46DBA, 0x03A16125, 0x0564F0BD, + 0xC3EB9E15, 0x3C9057A2, 0x97271AEC, 0xA93A072A, + 0x1B3F6D9B, 0x1E6321F5, 0xF59C66FB, 0x26DCF319, + 0x7533D928, 0xB155FDF5, 0x03563482, 0x8ABA3CBB, + 0x28517711, 0xC20AD9F8, 0xABCC5167, 0xCCAD925F, + 0x4DE81751, 0x3830DC8E, 0x379D5862, 0x9320F991, + 0xEA7A90C2, 0xFB3E7BCE, 0x5121CE64, 0x774FBE32, + 0xA8B6E37E, 0xC3293D46, 0x48DE5369, 0x6413E680, + 0xA2AE0810, 0xDD6DB224, 0x69852DFD, 0x09072166, + 0xB39A460A, 0x6445C0DD, 0x586CDECF, 0x1C20C8AE, + 0x5BBEF7DD, 0x1B588D40, 0xCCD2017F, 0x6BB4E3BB, + 0xDDA26A7E, 0x3A59FF45, 0x3E350A44, 0xBCB4CDD5, + 0x72EACEA8, 0xFA6484BB, 0x8D6612AE, 0xBF3C6F47, + 0xD29BE463, 0x542F5D9E, 0xAEC2771B, 0xF64E6370, + 0x740E0D8D, 0xE75B1357, 0xF8721671, 0xAF537D5D, + 0x4040CB08, 0x4EB4E2CC, 0x34D2466A, 0x0115AF84, + 0xE1B00428, 0x95983A1D, 0x06B89FB4, 0xCE6EA048, + 0x6F3F3B82, 0x3520AB82, 0x011A1D4B, 0x277227F8, + 0x611560B1, 0xE7933FDC, 0xBB3A792B, 0x344525BD, + 0xA08839E1, 0x51CE794B, 0x2F32C9B7, 0xA01FBAC9, + 0xE01CC87E, 0xBCC7D1F6, 0xCF0111C3, 0xA1E8AAC7, + 0x1A908749, 0xD44FBD9A, 0xD0DADECB, 0xD50ADA38, + 0x0339C32A, 0xC6913667, 0x8DF9317C, 0xE0B12B4F, + 0xF79E59B7, 0x43F5BB3A, 0xF2D519FF, 0x27D9459C, + 0xBF97222C, 0x15E6FC2A, 0x0F91FC71, 0x9B941525, + 0xFAE59361, 0xCEB69CEB, 0xC2A86459, 0x12BAA8D1, + 0xB6C1075E, 0xE3056A0C, 0x10D25065, 0xCB03A442, + 0xE0EC6E0E, 0x1698DB3B, 0x4C98A0BE, 0x3278E964, + 0x9F1F9532, 0xE0D392DF, 0xD3A0342B, 0x8971F21E, + 0x1B0A7441, 0x4BA3348C, 0xC5BE7120, 0xC37632D8, + 0xDF359F8D, 0x9B992F2E, 0xE60B6F47, 0x0FE3F11D, + 0xE54CDA54, 0x1EDAD891, 0xCE6279CF, 0xCD3E7E6F, + 0x1618B166, 0xFD2C1D05, 0x848FD2C5, 0xF6FB2299, + 0xF523F357, 0xA6327623, 0x93A83531, 0x56CCCD02, + 0xACF08162, 0x5A75EBB5, 0x6E163697, 0x88D273CC, + 0xDE966292, 0x81B949D0, 0x4C50901B, 0x71C65614, + 0xE6C6C7BD, 0x327A140A, 0x45E1D006, 0xC3F27B9A, + 0xC9AA53FD, 0x62A80F00, 0xBB25BFE2, 0x35BDD2F6, + 0x71126905, 0xB2040222, 0xB6CBCF7C, 0xCD769C2B, + 0x53113EC0, 0x1640E3D3, 0x38ABBD60, 0x2547ADF0, + 0xBA38209C, 0xF746CE76, 0x77AFA1C5, 0x20756060, + 0x85CBFE4E, 0x8AE88DD8, 0x7AAAF9B0, 0x4CF9AA7E, + 0x1948C25C, 0x02FB8A8C, 0x01C36AE4, 0xD6EBE1F9, + 0x90D4F869, 0xA65CDEA0, 0x3F09252D, 0xC208E69F, + 0xB74E6132, 0xCE77E25B, 0x578FDFE3, 0x3AC372E6 ] + ]; + + var BLOWFISH_CTX = { + pbox: [], + sbox: [] + } + + function F(ctx, x){ + let a = (x >> 24) & 0xFF; + let b = (x >> 16) & 0xFF; + let c = (x >> 8) & 0xFF; + let d = x & 0xFF; + + let y = ctx.sbox[0][a] + ctx.sbox[1][b]; + y = y ^ ctx.sbox[2][c]; + y = y + ctx.sbox[3][d]; + + return y; + } + + function BlowFish_Encrypt(ctx, left, right){ + let Xl = left; + let Xr = right; + let temp; + + for(let i = 0; i < N; ++i){ + Xl = Xl ^ ctx.pbox[i]; + Xr = F(ctx, Xl) ^ Xr; + + temp = Xl; + Xl = Xr; + Xr = temp; + } + + temp = Xl; + Xl = Xr; + Xr = temp; + + Xr = Xr ^ ctx.pbox[N]; + Xl = Xl ^ ctx.pbox[N + 1]; + + return {left: Xl, right: Xr}; + } + + function BlowFish_Decrypt(ctx, left, right){ + let Xl = left; + let Xr = right; + let temp; + + for(let i = N + 1; i > 1; --i){ + Xl = Xl ^ ctx.pbox[i]; + Xr = F(ctx, Xl) ^ Xr; + + temp = Xl; + Xl = Xr; + Xr = temp; + } + + temp = Xl; + Xl = Xr; + Xr = temp; + + Xr = Xr ^ ctx.pbox[1]; + Xl = Xl ^ ctx.pbox[0]; + + return {left: Xl, right: Xr}; + } + + /** + * Initialization ctx's pbox and sbox. + * + * @param {Object} ctx The object has pbox and sbox. + * @param {Array} key An array of 32-bit words. + * @param {int} keysize The length of the key. + * + * @example + * + * BlowFishInit(BLOWFISH_CTX, key, 128/32); + */ + function BlowFishInit(ctx, key, keysize) + { + for(let Row = 0; Row < 4; Row++) + { + ctx.sbox[Row] = []; + for(let Col = 0; Col < 256; Col++) + { + ctx.sbox[Row][Col] = ORIG_S[Row][Col]; + } + } + + let keyIndex = 0; + for(let index = 0; index < N + 2; index++) + { + ctx.pbox[index] = ORIG_P[index] ^ key[keyIndex]; + keyIndex++; + if(keyIndex >= keysize) + { + keyIndex = 0; + } + } + + let Data1 = 0; + let Data2 = 0; + let res = 0; + for(let i = 0; i < N + 2; i += 2) + { + res = BlowFish_Encrypt(ctx, Data1, Data2); + Data1 = res.left; + Data2 = res.right; + ctx.pbox[i] = Data1; + ctx.pbox[i + 1] = Data2; + } + + for(let i = 0; i < 4; i++) + { + for(let j = 0; j < 256; j += 2) + { + res = BlowFish_Encrypt(ctx, Data1, Data2); + Data1 = res.left; + Data2 = res.right; + ctx.sbox[i][j] = Data1; + ctx.sbox[i][j + 1] = Data2; + } + } + + return true; + } + + /** + * Blowfish block cipher algorithm. + */ + var Blowfish = C_algo.Blowfish = BlockCipher.extend({ + _doReset: function () { + // Skip reset of nRounds has been set before and key did not change + if (this._keyPriorReset === this._key) { + return; + } + + // Shortcuts + var key = this._keyPriorReset = this._key; + var keyWords = key.words; + var keySize = key.sigBytes / 4; + + //Initialization pbox and sbox + BlowFishInit(BLOWFISH_CTX, keyWords, keySize); + }, + + encryptBlock: function (M, offset) { + var res = BlowFish_Encrypt(BLOWFISH_CTX, M[offset], M[offset + 1]); + M[offset] = res.left; + M[offset + 1] = res.right; + }, + + decryptBlock: function (M, offset) { + var res = BlowFish_Decrypt(BLOWFISH_CTX, M[offset], M[offset + 1]); + M[offset] = res.left; + M[offset + 1] = res.right; + }, + + blockSize: 64/32, + + keySize: 128/32, + + ivSize: 64/32 + }); + + /** + * Shortcut functions to the cipher's object interface. + * + * @example + * + * var ciphertext = CryptoJS.Blowfish.encrypt(message, key, cfg); + * var plaintext = CryptoJS.Blowfish.decrypt(ciphertext, key, cfg); + */ + C.Blowfish = BlockCipher._createHelper(Blowfish); + }()); + + + return CryptoJS; + +})); \ No newline at end of file diff --git a/node_modules/crypto-js/docs/QuickStartGuide.wiki b/node_modules/crypto-js/docs/QuickStartGuide.wiki new file mode 100644 index 0000000..2bee35d --- /dev/null +++ b/node_modules/crypto-js/docs/QuickStartGuide.wiki @@ -0,0 +1,470 @@ + + +---- + += Quick-start Guide = + +== Hashers == + +=== The Hasher Algorithms === + +==== MD5 ==== + +MD5 is a widely used hash function. It's been used in a variety of security applications and is also commonly used to check the integrity of files. Though, MD5 is not collision resistant, and it isn't suitable for applications like SSL certificates or digital signatures that rely on this property. + +{{{ + + +}}} + +==== SHA-1 ==== + +The SHA hash functions were designed by the National Security Agency (NSA). SHA-1 is the most established of the existing SHA hash functions, and it's used in a variety of security applications and protocols. Though, SHA-1's collision resistance has been weakening as new attacks are discovered or improved. + +{{{ + + +}}} + +==== SHA-2 ==== + +SHA-256 is one of the four variants in the SHA-2 set. It isn't as widely used as SHA-1, though it appears to provide much better security. + +{{{ + + +}}} + +SHA-512 is largely identical to SHA-256 but operates on 64-bit words rather than 32. + +{{{ + + +}}} + +CryptoJS also supports SHA-224 and SHA-384, which are largely identical but truncated versions of SHA-256 and SHA-512 respectively. + +==== SHA-3 ==== + +SHA-3 is the winner of a five-year competition to select a new cryptographic hash algorithm where 64 competing designs were evaluated. + +{{{ + + +}}} + +SHA-3 can be configured to output hash lengths of one of 224, 256, 384, or 512 bits. The default is 512 bits. + +{{{ + + +}}} + +==== RIPEMD-160 ==== + +{{{ + + +}}} + +=== The Hasher Input === + +The hash algorithms accept either strings or instances of CryptoJS.lib.WordArray. A WordArray object represents an array of 32-bit words. When you pass a string, it's automatically converted to a WordArray encoded as UTF-8. + +=== The Hasher Output === + +The hash you get back isn't a string yet. It's a WordArray object. When you use a WordArray object in a string context, it's automatically converted to a hex string. + +{{{ + + +}}} + +You can convert a WordArray object to other formats by explicitly calling the toString method and passing an encoder. + +{{{ + + + +}}} + +=== Progressive Hashing === + +{{{ + + +}}} + +== HMAC == + +Keyed-hash message authentication codes (HMAC) is a mechanism for message authentication using cryptographic hash functions. + +HMAC can be used in combination with any iterated cryptographic hash function. + +{{{ + + + + + +}}} + +=== Progressive HMAC Hashing === + +{{{ + + +}}} + +== PBKDF2 == + +PBKDF2 is a password-based key derivation function. In many applications of cryptography, user security is ultimately dependent on a password, and because a password usually can't be used directly as a cryptographic key, some processing is required. + +A salt provides a large set of keys for any given password, and an iteration count increases the cost of producing keys from a password, thereby also increasing the difficulty of attack. + +{{{ + + +}}} + +== Ciphers == + +=== The Cipher Algorithms === + +==== AES ==== + +The Advanced Encryption Standard (AES) is a U.S. Federal Information Processing Standard (FIPS). It was selected after a 5-year process where 15 competing designs were evaluated. + +{{{ + + +}}} + +CryptoJS supports AES-128, AES-192, and AES-256. It will pick the variant by the size of the key you pass in. If you use a passphrase, then it will generate a 256-bit key. + +==== DES, Triple DES ==== + +DES is a previously dominant algorithm for encryption, and was published as an official Federal Information Processing Standard (FIPS). DES is now considered to be insecure due to the small key size. + +{{{ + + +}}} + +Triple DES applies DES three times to each block to increase the key size. The algorithm is believed to be secure in this form. + +{{{ + + +}}} + +==== Rabbit ==== + +Rabbit is a high-performance stream cipher and a finalist in the eSTREAM Portfolio. It is one of the four designs selected after a 3 1/2-year process where 22 designs were evaluated. + +{{{ + + +}}} + +==== RC4, RC4Drop ==== + +RC4 is a widely-used stream cipher. It's used in popular protocols such as SSL and WEP. Although remarkable for its simplicity and speed, the algorithm's history doesn't inspire confidence in its security. + +{{{ + + +}}} + +It was discovered that the first few bytes of keystream are strongly non-random and leak information about the key. We can defend against this attack by discarding the initial portion of the keystream. This modified algorithm is traditionally called RC4-drop. + +By default, 192 words (768 bytes) are dropped, but you can configure the algorithm to drop any number of words. + +{{{ + + +}}} + +=== Custom Key and IV === + +{{{ + + +}}} + +=== Block Modes and Padding === + +{{{ + + + + +}}} + +CryptoJS supports the following modes: + + * CBC (the default) + * CFB + * CTR + * OFB + * ECB + +And CryptoJS supports the following padding schemes: + + * Pkcs7 (the default) + * Iso97971 + * AnsiX923 + * Iso10126 + * ZeroPadding + * NoPadding + +=== The Cipher Input === + +For the plaintext message, the cipher algorithms accept either strings or instances of CryptoJS.lib.WordArray. + +For the key, when you pass a string, it's treated as a passphrase and used to derive an actual key and IV. Or you can pass a WordArray that represents the actual key. If you pass the actual key, you must also pass the actual IV. + +For the ciphertext, the cipher algorithms accept either strings or instances of CryptoJS.lib.CipherParams. A CipherParams object represents a collection of parameters such as the IV, a salt, and the raw ciphertext itself. When you pass a string, it's automatically converted to a CipherParams object according to a configurable format strategy. + +=== The Cipher Output === + +The plaintext you get back after decryption is a WordArray object. See Hashers' Output for more detail. + +The ciphertext you get back after encryption isn't a string yet. It's a CipherParams object. A CipherParams object gives you access to all the parameters used during encryption. When you use a CipherParams object in a string context, it's automatically converted to a string according to a format strategy. The default is an OpenSSL-compatible format. + +{{{ + + +}}} + +You can define your own formats in order to be compatible with other crypto implementations. A format is an object with two methods—stringify and parse—that converts between CipherParams objects and ciphertext strings. + +Here's how you might write a JSON formatter: + +{{{ + + +}}} + +=== Progressive Ciphering === + +{{{ + + +}}} + +=== Interoperability === + +==== With OpenSSL ==== + +Encrypt with OpenSSL: + +{{{ +openssl enc -aes-256-cbc -in infile -out outfile -pass pass:"Secret Passphrase" -e -base64 +}}} + +Decrypt with CryptoJS: + +{{{ + + +}}} + +== Encoders == + +CryptoJS can convert from encoding formats such as Base64, Latin1 or Hex to WordArray objects and vica versa. + +{{{ + + + + +}}} \ No newline at end of file diff --git a/node_modules/crypto-js/enc-base64.js b/node_modules/crypto-js/enc-base64.js new file mode 100644 index 0000000..0ffcd53 --- /dev/null +++ b/node_modules/crypto-js/enc-base64.js @@ -0,0 +1,136 @@ +;(function (root, factory) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require("./core")); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + (function () { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var WordArray = C_lib.WordArray; + var C_enc = C.enc; + + /** + * Base64 encoding strategy. + */ + var Base64 = C_enc.Base64 = { + /** + * Converts a word array to a Base64 string. + * + * @param {WordArray} wordArray The word array. + * + * @return {string} The Base64 string. + * + * @static + * + * @example + * + * var base64String = CryptoJS.enc.Base64.stringify(wordArray); + */ + stringify: function (wordArray) { + // Shortcuts + var words = wordArray.words; + var sigBytes = wordArray.sigBytes; + var map = this._map; + + // Clamp excess bits + wordArray.clamp(); + + // Convert + var base64Chars = []; + for (var i = 0; i < sigBytes; i += 3) { + var byte1 = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; + var byte2 = (words[(i + 1) >>> 2] >>> (24 - ((i + 1) % 4) * 8)) & 0xff; + var byte3 = (words[(i + 2) >>> 2] >>> (24 - ((i + 2) % 4) * 8)) & 0xff; + + var triplet = (byte1 << 16) | (byte2 << 8) | byte3; + + for (var j = 0; (j < 4) && (i + j * 0.75 < sigBytes); j++) { + base64Chars.push(map.charAt((triplet >>> (6 * (3 - j))) & 0x3f)); + } + } + + // Add padding + var paddingChar = map.charAt(64); + if (paddingChar) { + while (base64Chars.length % 4) { + base64Chars.push(paddingChar); + } + } + + return base64Chars.join(''); + }, + + /** + * Converts a Base64 string to a word array. + * + * @param {string} base64Str The Base64 string. + * + * @return {WordArray} The word array. + * + * @static + * + * @example + * + * var wordArray = CryptoJS.enc.Base64.parse(base64String); + */ + parse: function (base64Str) { + // Shortcuts + var base64StrLength = base64Str.length; + var map = this._map; + var reverseMap = this._reverseMap; + + if (!reverseMap) { + reverseMap = this._reverseMap = []; + for (var j = 0; j < map.length; j++) { + reverseMap[map.charCodeAt(j)] = j; + } + } + + // Ignore padding + var paddingChar = map.charAt(64); + if (paddingChar) { + var paddingIndex = base64Str.indexOf(paddingChar); + if (paddingIndex !== -1) { + base64StrLength = paddingIndex; + } + } + + // Convert + return parseLoop(base64Str, base64StrLength, reverseMap); + + }, + + _map: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=' + }; + + function parseLoop(base64Str, base64StrLength, reverseMap) { + var words = []; + var nBytes = 0; + for (var i = 0; i < base64StrLength; i++) { + if (i % 4) { + var bits1 = reverseMap[base64Str.charCodeAt(i - 1)] << ((i % 4) * 2); + var bits2 = reverseMap[base64Str.charCodeAt(i)] >>> (6 - (i % 4) * 2); + var bitsCombined = bits1 | bits2; + words[nBytes >>> 2] |= bitsCombined << (24 - (nBytes % 4) * 8); + nBytes++; + } + } + return WordArray.create(words, nBytes); + } + }()); + + + return CryptoJS.enc.Base64; + +})); \ No newline at end of file diff --git a/node_modules/crypto-js/enc-base64url.js b/node_modules/crypto-js/enc-base64url.js new file mode 100644 index 0000000..af682e3 --- /dev/null +++ b/node_modules/crypto-js/enc-base64url.js @@ -0,0 +1,148 @@ +;(function (root, factory) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require("./core")); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + (function () { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var WordArray = C_lib.WordArray; + var C_enc = C.enc; + + /** + * Base64url encoding strategy. + */ + var Base64url = C_enc.Base64url = { + /** + * Converts a word array to a Base64url string. + * + * @param {WordArray} wordArray The word array. + * + * @param {boolean} urlSafe Whether to use url safe + * + * @return {string} The Base64url string. + * + * @static + * + * @example + * + * var base64String = CryptoJS.enc.Base64url.stringify(wordArray); + */ + stringify: function (wordArray, urlSafe) { + if (urlSafe === undefined) { + urlSafe = true + } + // Shortcuts + var words = wordArray.words; + var sigBytes = wordArray.sigBytes; + var map = urlSafe ? this._safe_map : this._map; + + // Clamp excess bits + wordArray.clamp(); + + // Convert + var base64Chars = []; + for (var i = 0; i < sigBytes; i += 3) { + var byte1 = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; + var byte2 = (words[(i + 1) >>> 2] >>> (24 - ((i + 1) % 4) * 8)) & 0xff; + var byte3 = (words[(i + 2) >>> 2] >>> (24 - ((i + 2) % 4) * 8)) & 0xff; + + var triplet = (byte1 << 16) | (byte2 << 8) | byte3; + + for (var j = 0; (j < 4) && (i + j * 0.75 < sigBytes); j++) { + base64Chars.push(map.charAt((triplet >>> (6 * (3 - j))) & 0x3f)); + } + } + + // Add padding + var paddingChar = map.charAt(64); + if (paddingChar) { + while (base64Chars.length % 4) { + base64Chars.push(paddingChar); + } + } + + return base64Chars.join(''); + }, + + /** + * Converts a Base64url string to a word array. + * + * @param {string} base64Str The Base64url string. + * + * @param {boolean} urlSafe Whether to use url safe + * + * @return {WordArray} The word array. + * + * @static + * + * @example + * + * var wordArray = CryptoJS.enc.Base64url.parse(base64String); + */ + parse: function (base64Str, urlSafe) { + if (urlSafe === undefined) { + urlSafe = true + } + + // Shortcuts + var base64StrLength = base64Str.length; + var map = urlSafe ? this._safe_map : this._map; + var reverseMap = this._reverseMap; + + if (!reverseMap) { + reverseMap = this._reverseMap = []; + for (var j = 0; j < map.length; j++) { + reverseMap[map.charCodeAt(j)] = j; + } + } + + // Ignore padding + var paddingChar = map.charAt(64); + if (paddingChar) { + var paddingIndex = base64Str.indexOf(paddingChar); + if (paddingIndex !== -1) { + base64StrLength = paddingIndex; + } + } + + // Convert + return parseLoop(base64Str, base64StrLength, reverseMap); + + }, + + _map: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=', + _safe_map: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_', + }; + + function parseLoop(base64Str, base64StrLength, reverseMap) { + var words = []; + var nBytes = 0; + for (var i = 0; i < base64StrLength; i++) { + if (i % 4) { + var bits1 = reverseMap[base64Str.charCodeAt(i - 1)] << ((i % 4) * 2); + var bits2 = reverseMap[base64Str.charCodeAt(i)] >>> (6 - (i % 4) * 2); + var bitsCombined = bits1 | bits2; + words[nBytes >>> 2] |= bitsCombined << (24 - (nBytes % 4) * 8); + nBytes++; + } + } + return WordArray.create(words, nBytes); + } + }()); + + + return CryptoJS.enc.Base64url; + +})); \ No newline at end of file diff --git a/node_modules/crypto-js/enc-hex.js b/node_modules/crypto-js/enc-hex.js new file mode 100644 index 0000000..88161ff --- /dev/null +++ b/node_modules/crypto-js/enc-hex.js @@ -0,0 +1,18 @@ +;(function (root, factory) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require("./core")); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + return CryptoJS.enc.Hex; + +})); \ No newline at end of file diff --git a/node_modules/crypto-js/enc-latin1.js b/node_modules/crypto-js/enc-latin1.js new file mode 100644 index 0000000..ade56dc --- /dev/null +++ b/node_modules/crypto-js/enc-latin1.js @@ -0,0 +1,18 @@ +;(function (root, factory) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require("./core")); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + return CryptoJS.enc.Latin1; + +})); \ No newline at end of file diff --git a/node_modules/crypto-js/enc-utf16.js b/node_modules/crypto-js/enc-utf16.js new file mode 100644 index 0000000..7de6245 --- /dev/null +++ b/node_modules/crypto-js/enc-utf16.js @@ -0,0 +1,149 @@ +;(function (root, factory) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require("./core")); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + (function () { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var WordArray = C_lib.WordArray; + var C_enc = C.enc; + + /** + * UTF-16 BE encoding strategy. + */ + var Utf16BE = C_enc.Utf16 = C_enc.Utf16BE = { + /** + * Converts a word array to a UTF-16 BE string. + * + * @param {WordArray} wordArray The word array. + * + * @return {string} The UTF-16 BE string. + * + * @static + * + * @example + * + * var utf16String = CryptoJS.enc.Utf16.stringify(wordArray); + */ + stringify: function (wordArray) { + // Shortcuts + var words = wordArray.words; + var sigBytes = wordArray.sigBytes; + + // Convert + var utf16Chars = []; + for (var i = 0; i < sigBytes; i += 2) { + var codePoint = (words[i >>> 2] >>> (16 - (i % 4) * 8)) & 0xffff; + utf16Chars.push(String.fromCharCode(codePoint)); + } + + return utf16Chars.join(''); + }, + + /** + * Converts a UTF-16 BE string to a word array. + * + * @param {string} utf16Str The UTF-16 BE string. + * + * @return {WordArray} The word array. + * + * @static + * + * @example + * + * var wordArray = CryptoJS.enc.Utf16.parse(utf16String); + */ + parse: function (utf16Str) { + // Shortcut + var utf16StrLength = utf16Str.length; + + // Convert + var words = []; + for (var i = 0; i < utf16StrLength; i++) { + words[i >>> 1] |= utf16Str.charCodeAt(i) << (16 - (i % 2) * 16); + } + + return WordArray.create(words, utf16StrLength * 2); + } + }; + + /** + * UTF-16 LE encoding strategy. + */ + C_enc.Utf16LE = { + /** + * Converts a word array to a UTF-16 LE string. + * + * @param {WordArray} wordArray The word array. + * + * @return {string} The UTF-16 LE string. + * + * @static + * + * @example + * + * var utf16Str = CryptoJS.enc.Utf16LE.stringify(wordArray); + */ + stringify: function (wordArray) { + // Shortcuts + var words = wordArray.words; + var sigBytes = wordArray.sigBytes; + + // Convert + var utf16Chars = []; + for (var i = 0; i < sigBytes; i += 2) { + var codePoint = swapEndian((words[i >>> 2] >>> (16 - (i % 4) * 8)) & 0xffff); + utf16Chars.push(String.fromCharCode(codePoint)); + } + + return utf16Chars.join(''); + }, + + /** + * Converts a UTF-16 LE string to a word array. + * + * @param {string} utf16Str The UTF-16 LE string. + * + * @return {WordArray} The word array. + * + * @static + * + * @example + * + * var wordArray = CryptoJS.enc.Utf16LE.parse(utf16Str); + */ + parse: function (utf16Str) { + // Shortcut + var utf16StrLength = utf16Str.length; + + // Convert + var words = []; + for (var i = 0; i < utf16StrLength; i++) { + words[i >>> 1] |= swapEndian(utf16Str.charCodeAt(i) << (16 - (i % 2) * 16)); + } + + return WordArray.create(words, utf16StrLength * 2); + } + }; + + function swapEndian(word) { + return ((word << 8) & 0xff00ff00) | ((word >>> 8) & 0x00ff00ff); + } + }()); + + + return CryptoJS.enc.Utf16; + +})); \ No newline at end of file diff --git a/node_modules/crypto-js/enc-utf8.js b/node_modules/crypto-js/enc-utf8.js new file mode 100644 index 0000000..e7a251d --- /dev/null +++ b/node_modules/crypto-js/enc-utf8.js @@ -0,0 +1,18 @@ +;(function (root, factory) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require("./core")); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + return CryptoJS.enc.Utf8; + +})); \ No newline at end of file diff --git a/node_modules/crypto-js/evpkdf.js b/node_modules/crypto-js/evpkdf.js new file mode 100644 index 0000000..578974a --- /dev/null +++ b/node_modules/crypto-js/evpkdf.js @@ -0,0 +1,134 @@ +;(function (root, factory, undef) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require("./core"), require("./sha1"), require("./hmac")); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core", "./sha1", "./hmac"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + (function () { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var Base = C_lib.Base; + var WordArray = C_lib.WordArray; + var C_algo = C.algo; + var MD5 = C_algo.MD5; + + /** + * This key derivation function is meant to conform with EVP_BytesToKey. + * www.openssl.org/docs/crypto/EVP_BytesToKey.html + */ + var EvpKDF = C_algo.EvpKDF = Base.extend({ + /** + * Configuration options. + * + * @property {number} keySize The key size in words to generate. Default: 4 (128 bits) + * @property {Hasher} hasher The hash algorithm to use. Default: MD5 + * @property {number} iterations The number of iterations to perform. Default: 1 + */ + cfg: Base.extend({ + keySize: 128/32, + hasher: MD5, + iterations: 1 + }), + + /** + * Initializes a newly created key derivation function. + * + * @param {Object} cfg (Optional) The configuration options to use for the derivation. + * + * @example + * + * var kdf = CryptoJS.algo.EvpKDF.create(); + * var kdf = CryptoJS.algo.EvpKDF.create({ keySize: 8 }); + * var kdf = CryptoJS.algo.EvpKDF.create({ keySize: 8, iterations: 1000 }); + */ + init: function (cfg) { + this.cfg = this.cfg.extend(cfg); + }, + + /** + * Derives a key from a password. + * + * @param {WordArray|string} password The password. + * @param {WordArray|string} salt A salt. + * + * @return {WordArray} The derived key. + * + * @example + * + * var key = kdf.compute(password, salt); + */ + compute: function (password, salt) { + var block; + + // Shortcut + var cfg = this.cfg; + + // Init hasher + var hasher = cfg.hasher.create(); + + // Initial values + var derivedKey = WordArray.create(); + + // Shortcuts + var derivedKeyWords = derivedKey.words; + var keySize = cfg.keySize; + var iterations = cfg.iterations; + + // Generate key + while (derivedKeyWords.length < keySize) { + if (block) { + hasher.update(block); + } + block = hasher.update(password).finalize(salt); + hasher.reset(); + + // Iterations + for (var i = 1; i < iterations; i++) { + block = hasher.finalize(block); + hasher.reset(); + } + + derivedKey.concat(block); + } + derivedKey.sigBytes = keySize * 4; + + return derivedKey; + } + }); + + /** + * Derives a key from a password. + * + * @param {WordArray|string} password The password. + * @param {WordArray|string} salt A salt. + * @param {Object} cfg (Optional) The configuration options to use for this computation. + * + * @return {WordArray} The derived key. + * + * @static + * + * @example + * + * var key = CryptoJS.EvpKDF(password, salt); + * var key = CryptoJS.EvpKDF(password, salt, { keySize: 8 }); + * var key = CryptoJS.EvpKDF(password, salt, { keySize: 8, iterations: 1000 }); + */ + C.EvpKDF = function (password, salt, cfg) { + return EvpKDF.create(cfg).compute(password, salt); + }; + }()); + + + return CryptoJS.EvpKDF; + +})); \ No newline at end of file diff --git a/node_modules/crypto-js/format-hex.js b/node_modules/crypto-js/format-hex.js new file mode 100644 index 0000000..2e9a861 --- /dev/null +++ b/node_modules/crypto-js/format-hex.js @@ -0,0 +1,66 @@ +;(function (root, factory, undef) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require("./core"), require("./cipher-core")); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core", "./cipher-core"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + (function (undefined) { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var CipherParams = C_lib.CipherParams; + var C_enc = C.enc; + var Hex = C_enc.Hex; + var C_format = C.format; + + var HexFormatter = C_format.Hex = { + /** + * Converts the ciphertext of a cipher params object to a hexadecimally encoded string. + * + * @param {CipherParams} cipherParams The cipher params object. + * + * @return {string} The hexadecimally encoded string. + * + * @static + * + * @example + * + * var hexString = CryptoJS.format.Hex.stringify(cipherParams); + */ + stringify: function (cipherParams) { + return cipherParams.ciphertext.toString(Hex); + }, + + /** + * Converts a hexadecimally encoded ciphertext string to a cipher params object. + * + * @param {string} input The hexadecimally encoded string. + * + * @return {CipherParams} The cipher params object. + * + * @static + * + * @example + * + * var cipherParams = CryptoJS.format.Hex.parse(hexString); + */ + parse: function (input) { + var ciphertext = Hex.parse(input); + return CipherParams.create({ ciphertext: ciphertext }); + } + }; + }()); + + + return CryptoJS.format.Hex; + +})); \ No newline at end of file diff --git a/node_modules/crypto-js/format-openssl.js b/node_modules/crypto-js/format-openssl.js new file mode 100644 index 0000000..3373edc --- /dev/null +++ b/node_modules/crypto-js/format-openssl.js @@ -0,0 +1,18 @@ +;(function (root, factory, undef) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require("./core"), require("./cipher-core")); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core", "./cipher-core"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + return CryptoJS.format.OpenSSL; + +})); \ No newline at end of file diff --git a/node_modules/crypto-js/hmac-md5.js b/node_modules/crypto-js/hmac-md5.js new file mode 100644 index 0000000..ad7a90a --- /dev/null +++ b/node_modules/crypto-js/hmac-md5.js @@ -0,0 +1,18 @@ +;(function (root, factory, undef) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require("./core"), require("./md5"), require("./hmac")); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core", "./md5", "./hmac"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + return CryptoJS.HmacMD5; + +})); \ No newline at end of file diff --git a/node_modules/crypto-js/hmac-ripemd160.js b/node_modules/crypto-js/hmac-ripemd160.js new file mode 100644 index 0000000..73d55a7 --- /dev/null +++ b/node_modules/crypto-js/hmac-ripemd160.js @@ -0,0 +1,18 @@ +;(function (root, factory, undef) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require("./core"), require("./ripemd160"), require("./hmac")); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core", "./ripemd160", "./hmac"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + return CryptoJS.HmacRIPEMD160; + +})); \ No newline at end of file diff --git a/node_modules/crypto-js/hmac-sha1.js b/node_modules/crypto-js/hmac-sha1.js new file mode 100644 index 0000000..0b570cb --- /dev/null +++ b/node_modules/crypto-js/hmac-sha1.js @@ -0,0 +1,18 @@ +;(function (root, factory, undef) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require("./core"), require("./sha1"), require("./hmac")); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core", "./sha1", "./hmac"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + return CryptoJS.HmacSHA1; + +})); \ No newline at end of file diff --git a/node_modules/crypto-js/hmac-sha224.js b/node_modules/crypto-js/hmac-sha224.js new file mode 100644 index 0000000..3778863 --- /dev/null +++ b/node_modules/crypto-js/hmac-sha224.js @@ -0,0 +1,18 @@ +;(function (root, factory, undef) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require("./core"), require("./sha256"), require("./sha224"), require("./hmac")); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core", "./sha256", "./sha224", "./hmac"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + return CryptoJS.HmacSHA224; + +})); \ No newline at end of file diff --git a/node_modules/crypto-js/hmac-sha256.js b/node_modules/crypto-js/hmac-sha256.js new file mode 100644 index 0000000..33b0c9f --- /dev/null +++ b/node_modules/crypto-js/hmac-sha256.js @@ -0,0 +1,18 @@ +;(function (root, factory, undef) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require("./core"), require("./sha256"), require("./hmac")); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core", "./sha256", "./hmac"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + return CryptoJS.HmacSHA256; + +})); \ No newline at end of file diff --git a/node_modules/crypto-js/hmac-sha3.js b/node_modules/crypto-js/hmac-sha3.js new file mode 100644 index 0000000..1248804 --- /dev/null +++ b/node_modules/crypto-js/hmac-sha3.js @@ -0,0 +1,18 @@ +;(function (root, factory, undef) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require("./core"), require("./x64-core"), require("./sha3"), require("./hmac")); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core", "./x64-core", "./sha3", "./hmac"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + return CryptoJS.HmacSHA3; + +})); \ No newline at end of file diff --git a/node_modules/crypto-js/hmac-sha384.js b/node_modules/crypto-js/hmac-sha384.js new file mode 100644 index 0000000..0036e2b --- /dev/null +++ b/node_modules/crypto-js/hmac-sha384.js @@ -0,0 +1,18 @@ +;(function (root, factory, undef) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require("./core"), require("./x64-core"), require("./sha512"), require("./sha384"), require("./hmac")); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core", "./x64-core", "./sha512", "./sha384", "./hmac"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + return CryptoJS.HmacSHA384; + +})); \ No newline at end of file diff --git a/node_modules/crypto-js/hmac-sha512.js b/node_modules/crypto-js/hmac-sha512.js new file mode 100644 index 0000000..c1005b6 --- /dev/null +++ b/node_modules/crypto-js/hmac-sha512.js @@ -0,0 +1,18 @@ +;(function (root, factory, undef) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require("./core"), require("./x64-core"), require("./sha512"), require("./hmac")); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core", "./x64-core", "./sha512", "./hmac"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + return CryptoJS.HmacSHA512; + +})); \ No newline at end of file diff --git a/node_modules/crypto-js/hmac.js b/node_modules/crypto-js/hmac.js new file mode 100644 index 0000000..8c09851 --- /dev/null +++ b/node_modules/crypto-js/hmac.js @@ -0,0 +1,143 @@ +;(function (root, factory) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require("./core")); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + (function () { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var Base = C_lib.Base; + var C_enc = C.enc; + var Utf8 = C_enc.Utf8; + var C_algo = C.algo; + + /** + * HMAC algorithm. + */ + var HMAC = C_algo.HMAC = Base.extend({ + /** + * Initializes a newly created HMAC. + * + * @param {Hasher} hasher The hash algorithm to use. + * @param {WordArray|string} key The secret key. + * + * @example + * + * var hmacHasher = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA256, key); + */ + init: function (hasher, key) { + // Init hasher + hasher = this._hasher = new hasher.init(); + + // Convert string to WordArray, else assume WordArray already + if (typeof key == 'string') { + key = Utf8.parse(key); + } + + // Shortcuts + var hasherBlockSize = hasher.blockSize; + var hasherBlockSizeBytes = hasherBlockSize * 4; + + // Allow arbitrary length keys + if (key.sigBytes > hasherBlockSizeBytes) { + key = hasher.finalize(key); + } + + // Clamp excess bits + key.clamp(); + + // Clone key for inner and outer pads + var oKey = this._oKey = key.clone(); + var iKey = this._iKey = key.clone(); + + // Shortcuts + var oKeyWords = oKey.words; + var iKeyWords = iKey.words; + + // XOR keys with pad constants + for (var i = 0; i < hasherBlockSize; i++) { + oKeyWords[i] ^= 0x5c5c5c5c; + iKeyWords[i] ^= 0x36363636; + } + oKey.sigBytes = iKey.sigBytes = hasherBlockSizeBytes; + + // Set initial values + this.reset(); + }, + + /** + * Resets this HMAC to its initial state. + * + * @example + * + * hmacHasher.reset(); + */ + reset: function () { + // Shortcut + var hasher = this._hasher; + + // Reset + hasher.reset(); + hasher.update(this._iKey); + }, + + /** + * Updates this HMAC with a message. + * + * @param {WordArray|string} messageUpdate The message to append. + * + * @return {HMAC} This HMAC instance. + * + * @example + * + * hmacHasher.update('message'); + * hmacHasher.update(wordArray); + */ + update: function (messageUpdate) { + this._hasher.update(messageUpdate); + + // Chainable + return this; + }, + + /** + * Finalizes the HMAC computation. + * Note that the finalize operation is effectively a destructive, read-once operation. + * + * @param {WordArray|string} messageUpdate (Optional) A final message update. + * + * @return {WordArray} The HMAC. + * + * @example + * + * var hmac = hmacHasher.finalize(); + * var hmac = hmacHasher.finalize('message'); + * var hmac = hmacHasher.finalize(wordArray); + */ + finalize: function (messageUpdate) { + // Shortcut + var hasher = this._hasher; + + // Compute HMAC + var innerHash = hasher.finalize(messageUpdate); + hasher.reset(); + var hmac = hasher.finalize(this._oKey.clone().concat(innerHash)); + + return hmac; + } + }); + }()); + + +})); \ No newline at end of file diff --git a/node_modules/crypto-js/index.js b/node_modules/crypto-js/index.js new file mode 100644 index 0000000..b696646 --- /dev/null +++ b/node_modules/crypto-js/index.js @@ -0,0 +1,18 @@ +;(function (root, factory, undef) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require("./core"), require("./x64-core"), require("./lib-typedarrays"), require("./enc-utf16"), require("./enc-base64"), require("./enc-base64url"), require("./md5"), require("./sha1"), require("./sha256"), require("./sha224"), require("./sha512"), require("./sha384"), require("./sha3"), require("./ripemd160"), require("./hmac"), require("./pbkdf2"), require("./evpkdf"), require("./cipher-core"), require("./mode-cfb"), require("./mode-ctr"), require("./mode-ctr-gladman"), require("./mode-ofb"), require("./mode-ecb"), require("./pad-ansix923"), require("./pad-iso10126"), require("./pad-iso97971"), require("./pad-zeropadding"), require("./pad-nopadding"), require("./format-hex"), require("./aes"), require("./tripledes"), require("./rc4"), require("./rabbit"), require("./rabbit-legacy"), require("./blowfish")); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core", "./x64-core", "./lib-typedarrays", "./enc-utf16", "./enc-base64", "./enc-base64url", "./md5", "./sha1", "./sha256", "./sha224", "./sha512", "./sha384", "./sha3", "./ripemd160", "./hmac", "./pbkdf2", "./evpkdf", "./cipher-core", "./mode-cfb", "./mode-ctr", "./mode-ctr-gladman", "./mode-ofb", "./mode-ecb", "./pad-ansix923", "./pad-iso10126", "./pad-iso97971", "./pad-zeropadding", "./pad-nopadding", "./format-hex", "./aes", "./tripledes", "./rc4", "./rabbit", "./rabbit-legacy", "./blowfish"], factory); + } + else { + // Global (browser) + root.CryptoJS = factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + return CryptoJS; + +})); \ No newline at end of file diff --git a/node_modules/crypto-js/lib-typedarrays.js b/node_modules/crypto-js/lib-typedarrays.js new file mode 100644 index 0000000..264b210 --- /dev/null +++ b/node_modules/crypto-js/lib-typedarrays.js @@ -0,0 +1,76 @@ +;(function (root, factory) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require("./core")); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + (function () { + // Check if typed arrays are supported + if (typeof ArrayBuffer != 'function') { + return; + } + + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var WordArray = C_lib.WordArray; + + // Reference original init + var superInit = WordArray.init; + + // Augment WordArray.init to handle typed arrays + var subInit = WordArray.init = function (typedArray) { + // Convert buffers to uint8 + if (typedArray instanceof ArrayBuffer) { + typedArray = new Uint8Array(typedArray); + } + + // Convert other array views to uint8 + if ( + typedArray instanceof Int8Array || + (typeof Uint8ClampedArray !== "undefined" && typedArray instanceof Uint8ClampedArray) || + typedArray instanceof Int16Array || + typedArray instanceof Uint16Array || + typedArray instanceof Int32Array || + typedArray instanceof Uint32Array || + typedArray instanceof Float32Array || + typedArray instanceof Float64Array + ) { + typedArray = new Uint8Array(typedArray.buffer, typedArray.byteOffset, typedArray.byteLength); + } + + // Handle Uint8Array + if (typedArray instanceof Uint8Array) { + // Shortcut + var typedArrayByteLength = typedArray.byteLength; + + // Extract bytes + var words = []; + for (var i = 0; i < typedArrayByteLength; i++) { + words[i >>> 2] |= typedArray[i] << (24 - (i % 4) * 8); + } + + // Initialize this word array + superInit.call(this, words, typedArrayByteLength); + } else { + // Else call normal init + superInit.apply(this, arguments); + } + }; + + subInit.prototype = WordArray; + }()); + + + return CryptoJS.lib.WordArray; + +})); \ No newline at end of file diff --git a/node_modules/crypto-js/md5.js b/node_modules/crypto-js/md5.js new file mode 100644 index 0000000..72fce03 --- /dev/null +++ b/node_modules/crypto-js/md5.js @@ -0,0 +1,268 @@ +;(function (root, factory) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require("./core")); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + (function (Math) { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var WordArray = C_lib.WordArray; + var Hasher = C_lib.Hasher; + var C_algo = C.algo; + + // Constants table + var T = []; + + // Compute constants + (function () { + for (var i = 0; i < 64; i++) { + T[i] = (Math.abs(Math.sin(i + 1)) * 0x100000000) | 0; + } + }()); + + /** + * MD5 hash algorithm. + */ + var MD5 = C_algo.MD5 = Hasher.extend({ + _doReset: function () { + this._hash = new WordArray.init([ + 0x67452301, 0xefcdab89, + 0x98badcfe, 0x10325476 + ]); + }, + + _doProcessBlock: function (M, offset) { + // Swap endian + for (var i = 0; i < 16; i++) { + // Shortcuts + var offset_i = offset + i; + var M_offset_i = M[offset_i]; + + M[offset_i] = ( + (((M_offset_i << 8) | (M_offset_i >>> 24)) & 0x00ff00ff) | + (((M_offset_i << 24) | (M_offset_i >>> 8)) & 0xff00ff00) + ); + } + + // Shortcuts + var H = this._hash.words; + + var M_offset_0 = M[offset + 0]; + var M_offset_1 = M[offset + 1]; + var M_offset_2 = M[offset + 2]; + var M_offset_3 = M[offset + 3]; + var M_offset_4 = M[offset + 4]; + var M_offset_5 = M[offset + 5]; + var M_offset_6 = M[offset + 6]; + var M_offset_7 = M[offset + 7]; + var M_offset_8 = M[offset + 8]; + var M_offset_9 = M[offset + 9]; + var M_offset_10 = M[offset + 10]; + var M_offset_11 = M[offset + 11]; + var M_offset_12 = M[offset + 12]; + var M_offset_13 = M[offset + 13]; + var M_offset_14 = M[offset + 14]; + var M_offset_15 = M[offset + 15]; + + // Working variables + var a = H[0]; + var b = H[1]; + var c = H[2]; + var d = H[3]; + + // Computation + a = FF(a, b, c, d, M_offset_0, 7, T[0]); + d = FF(d, a, b, c, M_offset_1, 12, T[1]); + c = FF(c, d, a, b, M_offset_2, 17, T[2]); + b = FF(b, c, d, a, M_offset_3, 22, T[3]); + a = FF(a, b, c, d, M_offset_4, 7, T[4]); + d = FF(d, a, b, c, M_offset_5, 12, T[5]); + c = FF(c, d, a, b, M_offset_6, 17, T[6]); + b = FF(b, c, d, a, M_offset_7, 22, T[7]); + a = FF(a, b, c, d, M_offset_8, 7, T[8]); + d = FF(d, a, b, c, M_offset_9, 12, T[9]); + c = FF(c, d, a, b, M_offset_10, 17, T[10]); + b = FF(b, c, d, a, M_offset_11, 22, T[11]); + a = FF(a, b, c, d, M_offset_12, 7, T[12]); + d = FF(d, a, b, c, M_offset_13, 12, T[13]); + c = FF(c, d, a, b, M_offset_14, 17, T[14]); + b = FF(b, c, d, a, M_offset_15, 22, T[15]); + + a = GG(a, b, c, d, M_offset_1, 5, T[16]); + d = GG(d, a, b, c, M_offset_6, 9, T[17]); + c = GG(c, d, a, b, M_offset_11, 14, T[18]); + b = GG(b, c, d, a, M_offset_0, 20, T[19]); + a = GG(a, b, c, d, M_offset_5, 5, T[20]); + d = GG(d, a, b, c, M_offset_10, 9, T[21]); + c = GG(c, d, a, b, M_offset_15, 14, T[22]); + b = GG(b, c, d, a, M_offset_4, 20, T[23]); + a = GG(a, b, c, d, M_offset_9, 5, T[24]); + d = GG(d, a, b, c, M_offset_14, 9, T[25]); + c = GG(c, d, a, b, M_offset_3, 14, T[26]); + b = GG(b, c, d, a, M_offset_8, 20, T[27]); + a = GG(a, b, c, d, M_offset_13, 5, T[28]); + d = GG(d, a, b, c, M_offset_2, 9, T[29]); + c = GG(c, d, a, b, M_offset_7, 14, T[30]); + b = GG(b, c, d, a, M_offset_12, 20, T[31]); + + a = HH(a, b, c, d, M_offset_5, 4, T[32]); + d = HH(d, a, b, c, M_offset_8, 11, T[33]); + c = HH(c, d, a, b, M_offset_11, 16, T[34]); + b = HH(b, c, d, a, M_offset_14, 23, T[35]); + a = HH(a, b, c, d, M_offset_1, 4, T[36]); + d = HH(d, a, b, c, M_offset_4, 11, T[37]); + c = HH(c, d, a, b, M_offset_7, 16, T[38]); + b = HH(b, c, d, a, M_offset_10, 23, T[39]); + a = HH(a, b, c, d, M_offset_13, 4, T[40]); + d = HH(d, a, b, c, M_offset_0, 11, T[41]); + c = HH(c, d, a, b, M_offset_3, 16, T[42]); + b = HH(b, c, d, a, M_offset_6, 23, T[43]); + a = HH(a, b, c, d, M_offset_9, 4, T[44]); + d = HH(d, a, b, c, M_offset_12, 11, T[45]); + c = HH(c, d, a, b, M_offset_15, 16, T[46]); + b = HH(b, c, d, a, M_offset_2, 23, T[47]); + + a = II(a, b, c, d, M_offset_0, 6, T[48]); + d = II(d, a, b, c, M_offset_7, 10, T[49]); + c = II(c, d, a, b, M_offset_14, 15, T[50]); + b = II(b, c, d, a, M_offset_5, 21, T[51]); + a = II(a, b, c, d, M_offset_12, 6, T[52]); + d = II(d, a, b, c, M_offset_3, 10, T[53]); + c = II(c, d, a, b, M_offset_10, 15, T[54]); + b = II(b, c, d, a, M_offset_1, 21, T[55]); + a = II(a, b, c, d, M_offset_8, 6, T[56]); + d = II(d, a, b, c, M_offset_15, 10, T[57]); + c = II(c, d, a, b, M_offset_6, 15, T[58]); + b = II(b, c, d, a, M_offset_13, 21, T[59]); + a = II(a, b, c, d, M_offset_4, 6, T[60]); + d = II(d, a, b, c, M_offset_11, 10, T[61]); + c = II(c, d, a, b, M_offset_2, 15, T[62]); + b = II(b, c, d, a, M_offset_9, 21, T[63]); + + // Intermediate hash value + H[0] = (H[0] + a) | 0; + H[1] = (H[1] + b) | 0; + H[2] = (H[2] + c) | 0; + H[3] = (H[3] + d) | 0; + }, + + _doFinalize: function () { + // Shortcuts + var data = this._data; + var dataWords = data.words; + + var nBitsTotal = this._nDataBytes * 8; + var nBitsLeft = data.sigBytes * 8; + + // Add padding + dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32); + + var nBitsTotalH = Math.floor(nBitsTotal / 0x100000000); + var nBitsTotalL = nBitsTotal; + dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = ( + (((nBitsTotalH << 8) | (nBitsTotalH >>> 24)) & 0x00ff00ff) | + (((nBitsTotalH << 24) | (nBitsTotalH >>> 8)) & 0xff00ff00) + ); + dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = ( + (((nBitsTotalL << 8) | (nBitsTotalL >>> 24)) & 0x00ff00ff) | + (((nBitsTotalL << 24) | (nBitsTotalL >>> 8)) & 0xff00ff00) + ); + + data.sigBytes = (dataWords.length + 1) * 4; + + // Hash final blocks + this._process(); + + // Shortcuts + var hash = this._hash; + var H = hash.words; + + // Swap endian + for (var i = 0; i < 4; i++) { + // Shortcut + var H_i = H[i]; + + H[i] = (((H_i << 8) | (H_i >>> 24)) & 0x00ff00ff) | + (((H_i << 24) | (H_i >>> 8)) & 0xff00ff00); + } + + // Return final computed hash + return hash; + }, + + clone: function () { + var clone = Hasher.clone.call(this); + clone._hash = this._hash.clone(); + + return clone; + } + }); + + function FF(a, b, c, d, x, s, t) { + var n = a + ((b & c) | (~b & d)) + x + t; + return ((n << s) | (n >>> (32 - s))) + b; + } + + function GG(a, b, c, d, x, s, t) { + var n = a + ((b & d) | (c & ~d)) + x + t; + return ((n << s) | (n >>> (32 - s))) + b; + } + + function HH(a, b, c, d, x, s, t) { + var n = a + (b ^ c ^ d) + x + t; + return ((n << s) | (n >>> (32 - s))) + b; + } + + function II(a, b, c, d, x, s, t) { + var n = a + (c ^ (b | ~d)) + x + t; + return ((n << s) | (n >>> (32 - s))) + b; + } + + /** + * Shortcut function to the hasher's object interface. + * + * @param {WordArray|string} message The message to hash. + * + * @return {WordArray} The hash. + * + * @static + * + * @example + * + * var hash = CryptoJS.MD5('message'); + * var hash = CryptoJS.MD5(wordArray); + */ + C.MD5 = Hasher._createHelper(MD5); + + /** + * Shortcut function to the HMAC's object interface. + * + * @param {WordArray|string} message The message to hash. + * @param {WordArray|string} key The secret key. + * + * @return {WordArray} The HMAC. + * + * @static + * + * @example + * + * var hmac = CryptoJS.HmacMD5(message, key); + */ + C.HmacMD5 = Hasher._createHmacHelper(MD5); + }(Math)); + + + return CryptoJS.MD5; + +})); \ No newline at end of file diff --git a/node_modules/crypto-js/mode-cfb.js b/node_modules/crypto-js/mode-cfb.js new file mode 100644 index 0000000..444c9cb --- /dev/null +++ b/node_modules/crypto-js/mode-cfb.js @@ -0,0 +1,80 @@ +;(function (root, factory, undef) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require("./core"), require("./cipher-core")); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core", "./cipher-core"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + /** + * Cipher Feedback block mode. + */ + CryptoJS.mode.CFB = (function () { + var CFB = CryptoJS.lib.BlockCipherMode.extend(); + + CFB.Encryptor = CFB.extend({ + processBlock: function (words, offset) { + // Shortcuts + var cipher = this._cipher; + var blockSize = cipher.blockSize; + + generateKeystreamAndEncrypt.call(this, words, offset, blockSize, cipher); + + // Remember this block to use with next block + this._prevBlock = words.slice(offset, offset + blockSize); + } + }); + + CFB.Decryptor = CFB.extend({ + processBlock: function (words, offset) { + // Shortcuts + var cipher = this._cipher; + var blockSize = cipher.blockSize; + + // Remember this block to use with next block + var thisBlock = words.slice(offset, offset + blockSize); + + generateKeystreamAndEncrypt.call(this, words, offset, blockSize, cipher); + + // This block becomes the previous block + this._prevBlock = thisBlock; + } + }); + + function generateKeystreamAndEncrypt(words, offset, blockSize, cipher) { + var keystream; + + // Shortcut + var iv = this._iv; + + // Generate keystream + if (iv) { + keystream = iv.slice(0); + + // Remove IV for subsequent blocks + this._iv = undefined; + } else { + keystream = this._prevBlock; + } + cipher.encryptBlock(keystream, 0); + + // Encrypt + for (var i = 0; i < blockSize; i++) { + words[offset + i] ^= keystream[i]; + } + } + + return CFB; + }()); + + + return CryptoJS.mode.CFB; + +})); \ No newline at end of file diff --git a/node_modules/crypto-js/mode-ctr-gladman.js b/node_modules/crypto-js/mode-ctr-gladman.js new file mode 100644 index 0000000..bbc5687 --- /dev/null +++ b/node_modules/crypto-js/mode-ctr-gladman.js @@ -0,0 +1,116 @@ +;(function (root, factory, undef) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require("./core"), require("./cipher-core")); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core", "./cipher-core"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + /** @preserve + * Counter block mode compatible with Dr Brian Gladman fileenc.c + * derived from CryptoJS.mode.CTR + * Jan Hruby jhruby.web@gmail.com + */ + CryptoJS.mode.CTRGladman = (function () { + var CTRGladman = CryptoJS.lib.BlockCipherMode.extend(); + + function incWord(word) + { + if (((word >> 24) & 0xff) === 0xff) { //overflow + var b1 = (word >> 16)&0xff; + var b2 = (word >> 8)&0xff; + var b3 = word & 0xff; + + if (b1 === 0xff) // overflow b1 + { + b1 = 0; + if (b2 === 0xff) + { + b2 = 0; + if (b3 === 0xff) + { + b3 = 0; + } + else + { + ++b3; + } + } + else + { + ++b2; + } + } + else + { + ++b1; + } + + word = 0; + word += (b1 << 16); + word += (b2 << 8); + word += b3; + } + else + { + word += (0x01 << 24); + } + return word; + } + + function incCounter(counter) + { + if ((counter[0] = incWord(counter[0])) === 0) + { + // encr_data in fileenc.c from Dr Brian Gladman's counts only with DWORD j < 8 + counter[1] = incWord(counter[1]); + } + return counter; + } + + var Encryptor = CTRGladman.Encryptor = CTRGladman.extend({ + processBlock: function (words, offset) { + // Shortcuts + var cipher = this._cipher + var blockSize = cipher.blockSize; + var iv = this._iv; + var counter = this._counter; + + // Generate keystream + if (iv) { + counter = this._counter = iv.slice(0); + + // Remove IV for subsequent blocks + this._iv = undefined; + } + + incCounter(counter); + + var keystream = counter.slice(0); + cipher.encryptBlock(keystream, 0); + + // Encrypt + for (var i = 0; i < blockSize; i++) { + words[offset + i] ^= keystream[i]; + } + } + }); + + CTRGladman.Decryptor = Encryptor; + + return CTRGladman; + }()); + + + + + return CryptoJS.mode.CTRGladman; + +})); \ No newline at end of file diff --git a/node_modules/crypto-js/mode-ctr.js b/node_modules/crypto-js/mode-ctr.js new file mode 100644 index 0000000..c3d470a --- /dev/null +++ b/node_modules/crypto-js/mode-ctr.js @@ -0,0 +1,58 @@ +;(function (root, factory, undef) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require("./core"), require("./cipher-core")); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core", "./cipher-core"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + /** + * Counter block mode. + */ + CryptoJS.mode.CTR = (function () { + var CTR = CryptoJS.lib.BlockCipherMode.extend(); + + var Encryptor = CTR.Encryptor = CTR.extend({ + processBlock: function (words, offset) { + // Shortcuts + var cipher = this._cipher + var blockSize = cipher.blockSize; + var iv = this._iv; + var counter = this._counter; + + // Generate keystream + if (iv) { + counter = this._counter = iv.slice(0); + + // Remove IV for subsequent blocks + this._iv = undefined; + } + var keystream = counter.slice(0); + cipher.encryptBlock(keystream, 0); + + // Increment counter + counter[blockSize - 1] = (counter[blockSize - 1] + 1) | 0 + + // Encrypt + for (var i = 0; i < blockSize; i++) { + words[offset + i] ^= keystream[i]; + } + } + }); + + CTR.Decryptor = Encryptor; + + return CTR; + }()); + + + return CryptoJS.mode.CTR; + +})); \ No newline at end of file diff --git a/node_modules/crypto-js/mode-ecb.js b/node_modules/crypto-js/mode-ecb.js new file mode 100644 index 0000000..ff06921 --- /dev/null +++ b/node_modules/crypto-js/mode-ecb.js @@ -0,0 +1,40 @@ +;(function (root, factory, undef) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require("./core"), require("./cipher-core")); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core", "./cipher-core"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + /** + * Electronic Codebook block mode. + */ + CryptoJS.mode.ECB = (function () { + var ECB = CryptoJS.lib.BlockCipherMode.extend(); + + ECB.Encryptor = ECB.extend({ + processBlock: function (words, offset) { + this._cipher.encryptBlock(words, offset); + } + }); + + ECB.Decryptor = ECB.extend({ + processBlock: function (words, offset) { + this._cipher.decryptBlock(words, offset); + } + }); + + return ECB; + }()); + + + return CryptoJS.mode.ECB; + +})); \ No newline at end of file diff --git a/node_modules/crypto-js/mode-ofb.js b/node_modules/crypto-js/mode-ofb.js new file mode 100644 index 0000000..c01314c --- /dev/null +++ b/node_modules/crypto-js/mode-ofb.js @@ -0,0 +1,54 @@ +;(function (root, factory, undef) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require("./core"), require("./cipher-core")); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core", "./cipher-core"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + /** + * Output Feedback block mode. + */ + CryptoJS.mode.OFB = (function () { + var OFB = CryptoJS.lib.BlockCipherMode.extend(); + + var Encryptor = OFB.Encryptor = OFB.extend({ + processBlock: function (words, offset) { + // Shortcuts + var cipher = this._cipher + var blockSize = cipher.blockSize; + var iv = this._iv; + var keystream = this._keystream; + + // Generate keystream + if (iv) { + keystream = this._keystream = iv.slice(0); + + // Remove IV for subsequent blocks + this._iv = undefined; + } + cipher.encryptBlock(keystream, 0); + + // Encrypt + for (var i = 0; i < blockSize; i++) { + words[offset + i] ^= keystream[i]; + } + } + }); + + OFB.Decryptor = Encryptor; + + return OFB; + }()); + + + return CryptoJS.mode.OFB; + +})); \ No newline at end of file diff --git a/node_modules/crypto-js/package.json b/node_modules/crypto-js/package.json new file mode 100644 index 0000000..4b9a8e2 --- /dev/null +++ b/node_modules/crypto-js/package.json @@ -0,0 +1,42 @@ +{ + "name": "crypto-js", + "version": "4.2.0", + "description": "JavaScript library of crypto standards.", + "license": "MIT", + "author": { + "name": "Evan Vosberg", + "url": "http://github.com/evanvosberg" + }, + "homepage": "http://github.com/brix/crypto-js", + "repository": { + "type": "git", + "url": "http://github.com/brix/crypto-js.git" + }, + "keywords": [ + "security", + "crypto", + "Hash", + "MD5", + "SHA1", + "SHA-1", + "SHA256", + "SHA-256", + "RC4", + "Rabbit", + "AES", + "DES", + "PBKDF2", + "HMAC", + "OFB", + "CFB", + "CTR", + "CBC", + "Base64", + "Base64url" + ], + "main": "index.js", + "dependencies": {}, + "browser": { + "crypto": false + } +} diff --git a/node_modules/crypto-js/pad-ansix923.js b/node_modules/crypto-js/pad-ansix923.js new file mode 100644 index 0000000..f01f21e --- /dev/null +++ b/node_modules/crypto-js/pad-ansix923.js @@ -0,0 +1,49 @@ +;(function (root, factory, undef) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require("./core"), require("./cipher-core")); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core", "./cipher-core"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + /** + * ANSI X.923 padding strategy. + */ + CryptoJS.pad.AnsiX923 = { + pad: function (data, blockSize) { + // Shortcuts + var dataSigBytes = data.sigBytes; + var blockSizeBytes = blockSize * 4; + + // Count padding bytes + var nPaddingBytes = blockSizeBytes - dataSigBytes % blockSizeBytes; + + // Compute last byte position + var lastBytePos = dataSigBytes + nPaddingBytes - 1; + + // Pad + data.clamp(); + data.words[lastBytePos >>> 2] |= nPaddingBytes << (24 - (lastBytePos % 4) * 8); + data.sigBytes += nPaddingBytes; + }, + + unpad: function (data) { + // Get number of padding bytes from last byte + var nPaddingBytes = data.words[(data.sigBytes - 1) >>> 2] & 0xff; + + // Remove padding + data.sigBytes -= nPaddingBytes; + } + }; + + + return CryptoJS.pad.Ansix923; + +})); \ No newline at end of file diff --git a/node_modules/crypto-js/pad-iso10126.js b/node_modules/crypto-js/pad-iso10126.js new file mode 100644 index 0000000..6e2aefd --- /dev/null +++ b/node_modules/crypto-js/pad-iso10126.js @@ -0,0 +1,44 @@ +;(function (root, factory, undef) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require("./core"), require("./cipher-core")); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core", "./cipher-core"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + /** + * ISO 10126 padding strategy. + */ + CryptoJS.pad.Iso10126 = { + pad: function (data, blockSize) { + // Shortcut + var blockSizeBytes = blockSize * 4; + + // Count padding bytes + var nPaddingBytes = blockSizeBytes - data.sigBytes % blockSizeBytes; + + // Pad + data.concat(CryptoJS.lib.WordArray.random(nPaddingBytes - 1)). + concat(CryptoJS.lib.WordArray.create([nPaddingBytes << 24], 1)); + }, + + unpad: function (data) { + // Get number of padding bytes from last byte + var nPaddingBytes = data.words[(data.sigBytes - 1) >>> 2] & 0xff; + + // Remove padding + data.sigBytes -= nPaddingBytes; + } + }; + + + return CryptoJS.pad.Iso10126; + +})); \ No newline at end of file diff --git a/node_modules/crypto-js/pad-iso97971.js b/node_modules/crypto-js/pad-iso97971.js new file mode 100644 index 0000000..41049b4 --- /dev/null +++ b/node_modules/crypto-js/pad-iso97971.js @@ -0,0 +1,40 @@ +;(function (root, factory, undef) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require("./core"), require("./cipher-core")); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core", "./cipher-core"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + /** + * ISO/IEC 9797-1 Padding Method 2. + */ + CryptoJS.pad.Iso97971 = { + pad: function (data, blockSize) { + // Add 0x80 byte + data.concat(CryptoJS.lib.WordArray.create([0x80000000], 1)); + + // Zero pad the rest + CryptoJS.pad.ZeroPadding.pad(data, blockSize); + }, + + unpad: function (data) { + // Remove zero padding + CryptoJS.pad.ZeroPadding.unpad(data); + + // Remove one more byte -- the 0x80 byte + data.sigBytes--; + } + }; + + + return CryptoJS.pad.Iso97971; + +})); \ No newline at end of file diff --git a/node_modules/crypto-js/pad-nopadding.js b/node_modules/crypto-js/pad-nopadding.js new file mode 100644 index 0000000..c7787c9 --- /dev/null +++ b/node_modules/crypto-js/pad-nopadding.js @@ -0,0 +1,30 @@ +;(function (root, factory, undef) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require("./core"), require("./cipher-core")); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core", "./cipher-core"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + /** + * A noop padding strategy. + */ + CryptoJS.pad.NoPadding = { + pad: function () { + }, + + unpad: function () { + } + }; + + + return CryptoJS.pad.NoPadding; + +})); \ No newline at end of file diff --git a/node_modules/crypto-js/pad-pkcs7.js b/node_modules/crypto-js/pad-pkcs7.js new file mode 100644 index 0000000..3555168 --- /dev/null +++ b/node_modules/crypto-js/pad-pkcs7.js @@ -0,0 +1,18 @@ +;(function (root, factory, undef) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require("./core"), require("./cipher-core")); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core", "./cipher-core"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + return CryptoJS.pad.Pkcs7; + +})); \ No newline at end of file diff --git a/node_modules/crypto-js/pad-zeropadding.js b/node_modules/crypto-js/pad-zeropadding.js new file mode 100644 index 0000000..a1a459e --- /dev/null +++ b/node_modules/crypto-js/pad-zeropadding.js @@ -0,0 +1,47 @@ +;(function (root, factory, undef) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require("./core"), require("./cipher-core")); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core", "./cipher-core"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + /** + * Zero padding strategy. + */ + CryptoJS.pad.ZeroPadding = { + pad: function (data, blockSize) { + // Shortcut + var blockSizeBytes = blockSize * 4; + + // Pad + data.clamp(); + data.sigBytes += blockSizeBytes - ((data.sigBytes % blockSizeBytes) || blockSizeBytes); + }, + + unpad: function (data) { + // Shortcut + var dataWords = data.words; + + // Unpad + var i = data.sigBytes - 1; + for (var i = data.sigBytes - 1; i >= 0; i--) { + if (((dataWords[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff)) { + data.sigBytes = i + 1; + break; + } + } + } + }; + + + return CryptoJS.pad.ZeroPadding; + +})); \ No newline at end of file diff --git a/node_modules/crypto-js/pbkdf2.js b/node_modules/crypto-js/pbkdf2.js new file mode 100644 index 0000000..6850934 --- /dev/null +++ b/node_modules/crypto-js/pbkdf2.js @@ -0,0 +1,145 @@ +;(function (root, factory, undef) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require("./core"), require("./sha256"), require("./hmac")); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core", "./sha256", "./hmac"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + (function () { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var Base = C_lib.Base; + var WordArray = C_lib.WordArray; + var C_algo = C.algo; + var SHA256 = C_algo.SHA256; + var HMAC = C_algo.HMAC; + + /** + * Password-Based Key Derivation Function 2 algorithm. + */ + var PBKDF2 = C_algo.PBKDF2 = Base.extend({ + /** + * Configuration options. + * + * @property {number} keySize The key size in words to generate. Default: 4 (128 bits) + * @property {Hasher} hasher The hasher to use. Default: SHA256 + * @property {number} iterations The number of iterations to perform. Default: 250000 + */ + cfg: Base.extend({ + keySize: 128/32, + hasher: SHA256, + iterations: 250000 + }), + + /** + * Initializes a newly created key derivation function. + * + * @param {Object} cfg (Optional) The configuration options to use for the derivation. + * + * @example + * + * var kdf = CryptoJS.algo.PBKDF2.create(); + * var kdf = CryptoJS.algo.PBKDF2.create({ keySize: 8 }); + * var kdf = CryptoJS.algo.PBKDF2.create({ keySize: 8, iterations: 1000 }); + */ + init: function (cfg) { + this.cfg = this.cfg.extend(cfg); + }, + + /** + * Computes the Password-Based Key Derivation Function 2. + * + * @param {WordArray|string} password The password. + * @param {WordArray|string} salt A salt. + * + * @return {WordArray} The derived key. + * + * @example + * + * var key = kdf.compute(password, salt); + */ + compute: function (password, salt) { + // Shortcut + var cfg = this.cfg; + + // Init HMAC + var hmac = HMAC.create(cfg.hasher, password); + + // Initial values + var derivedKey = WordArray.create(); + var blockIndex = WordArray.create([0x00000001]); + + // Shortcuts + var derivedKeyWords = derivedKey.words; + var blockIndexWords = blockIndex.words; + var keySize = cfg.keySize; + var iterations = cfg.iterations; + + // Generate key + while (derivedKeyWords.length < keySize) { + var block = hmac.update(salt).finalize(blockIndex); + hmac.reset(); + + // Shortcuts + var blockWords = block.words; + var blockWordsLength = blockWords.length; + + // Iterations + var intermediate = block; + for (var i = 1; i < iterations; i++) { + intermediate = hmac.finalize(intermediate); + hmac.reset(); + + // Shortcut + var intermediateWords = intermediate.words; + + // XOR intermediate with block + for (var j = 0; j < blockWordsLength; j++) { + blockWords[j] ^= intermediateWords[j]; + } + } + + derivedKey.concat(block); + blockIndexWords[0]++; + } + derivedKey.sigBytes = keySize * 4; + + return derivedKey; + } + }); + + /** + * Computes the Password-Based Key Derivation Function 2. + * + * @param {WordArray|string} password The password. + * @param {WordArray|string} salt A salt. + * @param {Object} cfg (Optional) The configuration options to use for this computation. + * + * @return {WordArray} The derived key. + * + * @static + * + * @example + * + * var key = CryptoJS.PBKDF2(password, salt); + * var key = CryptoJS.PBKDF2(password, salt, { keySize: 8 }); + * var key = CryptoJS.PBKDF2(password, salt, { keySize: 8, iterations: 1000 }); + */ + C.PBKDF2 = function (password, salt, cfg) { + return PBKDF2.create(cfg).compute(password, salt); + }; + }()); + + + return CryptoJS.PBKDF2; + +})); \ No newline at end of file diff --git a/node_modules/crypto-js/rabbit-legacy.js b/node_modules/crypto-js/rabbit-legacy.js new file mode 100644 index 0000000..e118b6b --- /dev/null +++ b/node_modules/crypto-js/rabbit-legacy.js @@ -0,0 +1,190 @@ +;(function (root, factory, undef) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require("./core"), require("./enc-base64"), require("./md5"), require("./evpkdf"), require("./cipher-core")); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core", "./enc-base64", "./md5", "./evpkdf", "./cipher-core"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + (function () { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var StreamCipher = C_lib.StreamCipher; + var C_algo = C.algo; + + // Reusable objects + var S = []; + var C_ = []; + var G = []; + + /** + * Rabbit stream cipher algorithm. + * + * This is a legacy version that neglected to convert the key to little-endian. + * This error doesn't affect the cipher's security, + * but it does affect its compatibility with other implementations. + */ + var RabbitLegacy = C_algo.RabbitLegacy = StreamCipher.extend({ + _doReset: function () { + // Shortcuts + var K = this._key.words; + var iv = this.cfg.iv; + + // Generate initial state values + var X = this._X = [ + K[0], (K[3] << 16) | (K[2] >>> 16), + K[1], (K[0] << 16) | (K[3] >>> 16), + K[2], (K[1] << 16) | (K[0] >>> 16), + K[3], (K[2] << 16) | (K[1] >>> 16) + ]; + + // Generate initial counter values + var C = this._C = [ + (K[2] << 16) | (K[2] >>> 16), (K[0] & 0xffff0000) | (K[1] & 0x0000ffff), + (K[3] << 16) | (K[3] >>> 16), (K[1] & 0xffff0000) | (K[2] & 0x0000ffff), + (K[0] << 16) | (K[0] >>> 16), (K[2] & 0xffff0000) | (K[3] & 0x0000ffff), + (K[1] << 16) | (K[1] >>> 16), (K[3] & 0xffff0000) | (K[0] & 0x0000ffff) + ]; + + // Carry bit + this._b = 0; + + // Iterate the system four times + for (var i = 0; i < 4; i++) { + nextState.call(this); + } + + // Modify the counters + for (var i = 0; i < 8; i++) { + C[i] ^= X[(i + 4) & 7]; + } + + // IV setup + if (iv) { + // Shortcuts + var IV = iv.words; + var IV_0 = IV[0]; + var IV_1 = IV[1]; + + // Generate four subvectors + var i0 = (((IV_0 << 8) | (IV_0 >>> 24)) & 0x00ff00ff) | (((IV_0 << 24) | (IV_0 >>> 8)) & 0xff00ff00); + var i2 = (((IV_1 << 8) | (IV_1 >>> 24)) & 0x00ff00ff) | (((IV_1 << 24) | (IV_1 >>> 8)) & 0xff00ff00); + var i1 = (i0 >>> 16) | (i2 & 0xffff0000); + var i3 = (i2 << 16) | (i0 & 0x0000ffff); + + // Modify counter values + C[0] ^= i0; + C[1] ^= i1; + C[2] ^= i2; + C[3] ^= i3; + C[4] ^= i0; + C[5] ^= i1; + C[6] ^= i2; + C[7] ^= i3; + + // Iterate the system four times + for (var i = 0; i < 4; i++) { + nextState.call(this); + } + } + }, + + _doProcessBlock: function (M, offset) { + // Shortcut + var X = this._X; + + // Iterate the system + nextState.call(this); + + // Generate four keystream words + S[0] = X[0] ^ (X[5] >>> 16) ^ (X[3] << 16); + S[1] = X[2] ^ (X[7] >>> 16) ^ (X[5] << 16); + S[2] = X[4] ^ (X[1] >>> 16) ^ (X[7] << 16); + S[3] = X[6] ^ (X[3] >>> 16) ^ (X[1] << 16); + + for (var i = 0; i < 4; i++) { + // Swap endian + S[i] = (((S[i] << 8) | (S[i] >>> 24)) & 0x00ff00ff) | + (((S[i] << 24) | (S[i] >>> 8)) & 0xff00ff00); + + // Encrypt + M[offset + i] ^= S[i]; + } + }, + + blockSize: 128/32, + + ivSize: 64/32 + }); + + function nextState() { + // Shortcuts + var X = this._X; + var C = this._C; + + // Save old counter values + for (var i = 0; i < 8; i++) { + C_[i] = C[i]; + } + + // Calculate new counter values + C[0] = (C[0] + 0x4d34d34d + this._b) | 0; + C[1] = (C[1] + 0xd34d34d3 + ((C[0] >>> 0) < (C_[0] >>> 0) ? 1 : 0)) | 0; + C[2] = (C[2] + 0x34d34d34 + ((C[1] >>> 0) < (C_[1] >>> 0) ? 1 : 0)) | 0; + C[3] = (C[3] + 0x4d34d34d + ((C[2] >>> 0) < (C_[2] >>> 0) ? 1 : 0)) | 0; + C[4] = (C[4] + 0xd34d34d3 + ((C[3] >>> 0) < (C_[3] >>> 0) ? 1 : 0)) | 0; + C[5] = (C[5] + 0x34d34d34 + ((C[4] >>> 0) < (C_[4] >>> 0) ? 1 : 0)) | 0; + C[6] = (C[6] + 0x4d34d34d + ((C[5] >>> 0) < (C_[5] >>> 0) ? 1 : 0)) | 0; + C[7] = (C[7] + 0xd34d34d3 + ((C[6] >>> 0) < (C_[6] >>> 0) ? 1 : 0)) | 0; + this._b = (C[7] >>> 0) < (C_[7] >>> 0) ? 1 : 0; + + // Calculate the g-values + for (var i = 0; i < 8; i++) { + var gx = X[i] + C[i]; + + // Construct high and low argument for squaring + var ga = gx & 0xffff; + var gb = gx >>> 16; + + // Calculate high and low result of squaring + var gh = ((((ga * ga) >>> 17) + ga * gb) >>> 15) + gb * gb; + var gl = (((gx & 0xffff0000) * gx) | 0) + (((gx & 0x0000ffff) * gx) | 0); + + // High XOR low + G[i] = gh ^ gl; + } + + // Calculate new state values + X[0] = (G[0] + ((G[7] << 16) | (G[7] >>> 16)) + ((G[6] << 16) | (G[6] >>> 16))) | 0; + X[1] = (G[1] + ((G[0] << 8) | (G[0] >>> 24)) + G[7]) | 0; + X[2] = (G[2] + ((G[1] << 16) | (G[1] >>> 16)) + ((G[0] << 16) | (G[0] >>> 16))) | 0; + X[3] = (G[3] + ((G[2] << 8) | (G[2] >>> 24)) + G[1]) | 0; + X[4] = (G[4] + ((G[3] << 16) | (G[3] >>> 16)) + ((G[2] << 16) | (G[2] >>> 16))) | 0; + X[5] = (G[5] + ((G[4] << 8) | (G[4] >>> 24)) + G[3]) | 0; + X[6] = (G[6] + ((G[5] << 16) | (G[5] >>> 16)) + ((G[4] << 16) | (G[4] >>> 16))) | 0; + X[7] = (G[7] + ((G[6] << 8) | (G[6] >>> 24)) + G[5]) | 0; + } + + /** + * Shortcut functions to the cipher's object interface. + * + * @example + * + * var ciphertext = CryptoJS.RabbitLegacy.encrypt(message, key, cfg); + * var plaintext = CryptoJS.RabbitLegacy.decrypt(ciphertext, key, cfg); + */ + C.RabbitLegacy = StreamCipher._createHelper(RabbitLegacy); + }()); + + + return CryptoJS.RabbitLegacy; + +})); \ No newline at end of file diff --git a/node_modules/crypto-js/rabbit.js b/node_modules/crypto-js/rabbit.js new file mode 100644 index 0000000..1b06833 --- /dev/null +++ b/node_modules/crypto-js/rabbit.js @@ -0,0 +1,192 @@ +;(function (root, factory, undef) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require("./core"), require("./enc-base64"), require("./md5"), require("./evpkdf"), require("./cipher-core")); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core", "./enc-base64", "./md5", "./evpkdf", "./cipher-core"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + (function () { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var StreamCipher = C_lib.StreamCipher; + var C_algo = C.algo; + + // Reusable objects + var S = []; + var C_ = []; + var G = []; + + /** + * Rabbit stream cipher algorithm + */ + var Rabbit = C_algo.Rabbit = StreamCipher.extend({ + _doReset: function () { + // Shortcuts + var K = this._key.words; + var iv = this.cfg.iv; + + // Swap endian + for (var i = 0; i < 4; i++) { + K[i] = (((K[i] << 8) | (K[i] >>> 24)) & 0x00ff00ff) | + (((K[i] << 24) | (K[i] >>> 8)) & 0xff00ff00); + } + + // Generate initial state values + var X = this._X = [ + K[0], (K[3] << 16) | (K[2] >>> 16), + K[1], (K[0] << 16) | (K[3] >>> 16), + K[2], (K[1] << 16) | (K[0] >>> 16), + K[3], (K[2] << 16) | (K[1] >>> 16) + ]; + + // Generate initial counter values + var C = this._C = [ + (K[2] << 16) | (K[2] >>> 16), (K[0] & 0xffff0000) | (K[1] & 0x0000ffff), + (K[3] << 16) | (K[3] >>> 16), (K[1] & 0xffff0000) | (K[2] & 0x0000ffff), + (K[0] << 16) | (K[0] >>> 16), (K[2] & 0xffff0000) | (K[3] & 0x0000ffff), + (K[1] << 16) | (K[1] >>> 16), (K[3] & 0xffff0000) | (K[0] & 0x0000ffff) + ]; + + // Carry bit + this._b = 0; + + // Iterate the system four times + for (var i = 0; i < 4; i++) { + nextState.call(this); + } + + // Modify the counters + for (var i = 0; i < 8; i++) { + C[i] ^= X[(i + 4) & 7]; + } + + // IV setup + if (iv) { + // Shortcuts + var IV = iv.words; + var IV_0 = IV[0]; + var IV_1 = IV[1]; + + // Generate four subvectors + var i0 = (((IV_0 << 8) | (IV_0 >>> 24)) & 0x00ff00ff) | (((IV_0 << 24) | (IV_0 >>> 8)) & 0xff00ff00); + var i2 = (((IV_1 << 8) | (IV_1 >>> 24)) & 0x00ff00ff) | (((IV_1 << 24) | (IV_1 >>> 8)) & 0xff00ff00); + var i1 = (i0 >>> 16) | (i2 & 0xffff0000); + var i3 = (i2 << 16) | (i0 & 0x0000ffff); + + // Modify counter values + C[0] ^= i0; + C[1] ^= i1; + C[2] ^= i2; + C[3] ^= i3; + C[4] ^= i0; + C[5] ^= i1; + C[6] ^= i2; + C[7] ^= i3; + + // Iterate the system four times + for (var i = 0; i < 4; i++) { + nextState.call(this); + } + } + }, + + _doProcessBlock: function (M, offset) { + // Shortcut + var X = this._X; + + // Iterate the system + nextState.call(this); + + // Generate four keystream words + S[0] = X[0] ^ (X[5] >>> 16) ^ (X[3] << 16); + S[1] = X[2] ^ (X[7] >>> 16) ^ (X[5] << 16); + S[2] = X[4] ^ (X[1] >>> 16) ^ (X[7] << 16); + S[3] = X[6] ^ (X[3] >>> 16) ^ (X[1] << 16); + + for (var i = 0; i < 4; i++) { + // Swap endian + S[i] = (((S[i] << 8) | (S[i] >>> 24)) & 0x00ff00ff) | + (((S[i] << 24) | (S[i] >>> 8)) & 0xff00ff00); + + // Encrypt + M[offset + i] ^= S[i]; + } + }, + + blockSize: 128/32, + + ivSize: 64/32 + }); + + function nextState() { + // Shortcuts + var X = this._X; + var C = this._C; + + // Save old counter values + for (var i = 0; i < 8; i++) { + C_[i] = C[i]; + } + + // Calculate new counter values + C[0] = (C[0] + 0x4d34d34d + this._b) | 0; + C[1] = (C[1] + 0xd34d34d3 + ((C[0] >>> 0) < (C_[0] >>> 0) ? 1 : 0)) | 0; + C[2] = (C[2] + 0x34d34d34 + ((C[1] >>> 0) < (C_[1] >>> 0) ? 1 : 0)) | 0; + C[3] = (C[3] + 0x4d34d34d + ((C[2] >>> 0) < (C_[2] >>> 0) ? 1 : 0)) | 0; + C[4] = (C[4] + 0xd34d34d3 + ((C[3] >>> 0) < (C_[3] >>> 0) ? 1 : 0)) | 0; + C[5] = (C[5] + 0x34d34d34 + ((C[4] >>> 0) < (C_[4] >>> 0) ? 1 : 0)) | 0; + C[6] = (C[6] + 0x4d34d34d + ((C[5] >>> 0) < (C_[5] >>> 0) ? 1 : 0)) | 0; + C[7] = (C[7] + 0xd34d34d3 + ((C[6] >>> 0) < (C_[6] >>> 0) ? 1 : 0)) | 0; + this._b = (C[7] >>> 0) < (C_[7] >>> 0) ? 1 : 0; + + // Calculate the g-values + for (var i = 0; i < 8; i++) { + var gx = X[i] + C[i]; + + // Construct high and low argument for squaring + var ga = gx & 0xffff; + var gb = gx >>> 16; + + // Calculate high and low result of squaring + var gh = ((((ga * ga) >>> 17) + ga * gb) >>> 15) + gb * gb; + var gl = (((gx & 0xffff0000) * gx) | 0) + (((gx & 0x0000ffff) * gx) | 0); + + // High XOR low + G[i] = gh ^ gl; + } + + // Calculate new state values + X[0] = (G[0] + ((G[7] << 16) | (G[7] >>> 16)) + ((G[6] << 16) | (G[6] >>> 16))) | 0; + X[1] = (G[1] + ((G[0] << 8) | (G[0] >>> 24)) + G[7]) | 0; + X[2] = (G[2] + ((G[1] << 16) | (G[1] >>> 16)) + ((G[0] << 16) | (G[0] >>> 16))) | 0; + X[3] = (G[3] + ((G[2] << 8) | (G[2] >>> 24)) + G[1]) | 0; + X[4] = (G[4] + ((G[3] << 16) | (G[3] >>> 16)) + ((G[2] << 16) | (G[2] >>> 16))) | 0; + X[5] = (G[5] + ((G[4] << 8) | (G[4] >>> 24)) + G[3]) | 0; + X[6] = (G[6] + ((G[5] << 16) | (G[5] >>> 16)) + ((G[4] << 16) | (G[4] >>> 16))) | 0; + X[7] = (G[7] + ((G[6] << 8) | (G[6] >>> 24)) + G[5]) | 0; + } + + /** + * Shortcut functions to the cipher's object interface. + * + * @example + * + * var ciphertext = CryptoJS.Rabbit.encrypt(message, key, cfg); + * var plaintext = CryptoJS.Rabbit.decrypt(ciphertext, key, cfg); + */ + C.Rabbit = StreamCipher._createHelper(Rabbit); + }()); + + + return CryptoJS.Rabbit; + +})); \ No newline at end of file diff --git a/node_modules/crypto-js/rc4.js b/node_modules/crypto-js/rc4.js new file mode 100644 index 0000000..0e4bdff --- /dev/null +++ b/node_modules/crypto-js/rc4.js @@ -0,0 +1,139 @@ +;(function (root, factory, undef) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require("./core"), require("./enc-base64"), require("./md5"), require("./evpkdf"), require("./cipher-core")); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core", "./enc-base64", "./md5", "./evpkdf", "./cipher-core"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + (function () { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var StreamCipher = C_lib.StreamCipher; + var C_algo = C.algo; + + /** + * RC4 stream cipher algorithm. + */ + var RC4 = C_algo.RC4 = StreamCipher.extend({ + _doReset: function () { + // Shortcuts + var key = this._key; + var keyWords = key.words; + var keySigBytes = key.sigBytes; + + // Init sbox + var S = this._S = []; + for (var i = 0; i < 256; i++) { + S[i] = i; + } + + // Key setup + for (var i = 0, j = 0; i < 256; i++) { + var keyByteIndex = i % keySigBytes; + var keyByte = (keyWords[keyByteIndex >>> 2] >>> (24 - (keyByteIndex % 4) * 8)) & 0xff; + + j = (j + S[i] + keyByte) % 256; + + // Swap + var t = S[i]; + S[i] = S[j]; + S[j] = t; + } + + // Counters + this._i = this._j = 0; + }, + + _doProcessBlock: function (M, offset) { + M[offset] ^= generateKeystreamWord.call(this); + }, + + keySize: 256/32, + + ivSize: 0 + }); + + function generateKeystreamWord() { + // Shortcuts + var S = this._S; + var i = this._i; + var j = this._j; + + // Generate keystream word + var keystreamWord = 0; + for (var n = 0; n < 4; n++) { + i = (i + 1) % 256; + j = (j + S[i]) % 256; + + // Swap + var t = S[i]; + S[i] = S[j]; + S[j] = t; + + keystreamWord |= S[(S[i] + S[j]) % 256] << (24 - n * 8); + } + + // Update counters + this._i = i; + this._j = j; + + return keystreamWord; + } + + /** + * Shortcut functions to the cipher's object interface. + * + * @example + * + * var ciphertext = CryptoJS.RC4.encrypt(message, key, cfg); + * var plaintext = CryptoJS.RC4.decrypt(ciphertext, key, cfg); + */ + C.RC4 = StreamCipher._createHelper(RC4); + + /** + * Modified RC4 stream cipher algorithm. + */ + var RC4Drop = C_algo.RC4Drop = RC4.extend({ + /** + * Configuration options. + * + * @property {number} drop The number of keystream words to drop. Default 192 + */ + cfg: RC4.cfg.extend({ + drop: 192 + }), + + _doReset: function () { + RC4._doReset.call(this); + + // Drop + for (var i = this.cfg.drop; i > 0; i--) { + generateKeystreamWord.call(this); + } + } + }); + + /** + * Shortcut functions to the cipher's object interface. + * + * @example + * + * var ciphertext = CryptoJS.RC4Drop.encrypt(message, key, cfg); + * var plaintext = CryptoJS.RC4Drop.decrypt(ciphertext, key, cfg); + */ + C.RC4Drop = StreamCipher._createHelper(RC4Drop); + }()); + + + return CryptoJS.RC4; + +})); \ No newline at end of file diff --git a/node_modules/crypto-js/ripemd160.js b/node_modules/crypto-js/ripemd160.js new file mode 100644 index 0000000..24feb47 --- /dev/null +++ b/node_modules/crypto-js/ripemd160.js @@ -0,0 +1,267 @@ +;(function (root, factory) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require("./core")); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + /** @preserve + (c) 2012 by Cédric Mesnil. All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + (function (Math) { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var WordArray = C_lib.WordArray; + var Hasher = C_lib.Hasher; + var C_algo = C.algo; + + // Constants table + var _zl = WordArray.create([ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, + 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12, + 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2, + 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13]); + var _zr = WordArray.create([ + 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, + 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2, + 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13, + 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14, + 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11]); + var _sl = WordArray.create([ + 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8, + 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12, + 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5, + 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12, + 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6 ]); + var _sr = WordArray.create([ + 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6, + 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11, + 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5, + 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8, + 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11 ]); + + var _hl = WordArray.create([ 0x00000000, 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xA953FD4E]); + var _hr = WordArray.create([ 0x50A28BE6, 0x5C4DD124, 0x6D703EF3, 0x7A6D76E9, 0x00000000]); + + /** + * RIPEMD160 hash algorithm. + */ + var RIPEMD160 = C_algo.RIPEMD160 = Hasher.extend({ + _doReset: function () { + this._hash = WordArray.create([0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0]); + }, + + _doProcessBlock: function (M, offset) { + + // Swap endian + for (var i = 0; i < 16; i++) { + // Shortcuts + var offset_i = offset + i; + var M_offset_i = M[offset_i]; + + // Swap + M[offset_i] = ( + (((M_offset_i << 8) | (M_offset_i >>> 24)) & 0x00ff00ff) | + (((M_offset_i << 24) | (M_offset_i >>> 8)) & 0xff00ff00) + ); + } + // Shortcut + var H = this._hash.words; + var hl = _hl.words; + var hr = _hr.words; + var zl = _zl.words; + var zr = _zr.words; + var sl = _sl.words; + var sr = _sr.words; + + // Working variables + var al, bl, cl, dl, el; + var ar, br, cr, dr, er; + + ar = al = H[0]; + br = bl = H[1]; + cr = cl = H[2]; + dr = dl = H[3]; + er = el = H[4]; + // Computation + var t; + for (var i = 0; i < 80; i += 1) { + t = (al + M[offset+zl[i]])|0; + if (i<16){ + t += f1(bl,cl,dl) + hl[0]; + } else if (i<32) { + t += f2(bl,cl,dl) + hl[1]; + } else if (i<48) { + t += f3(bl,cl,dl) + hl[2]; + } else if (i<64) { + t += f4(bl,cl,dl) + hl[3]; + } else {// if (i<80) { + t += f5(bl,cl,dl) + hl[4]; + } + t = t|0; + t = rotl(t,sl[i]); + t = (t+el)|0; + al = el; + el = dl; + dl = rotl(cl, 10); + cl = bl; + bl = t; + + t = (ar + M[offset+zr[i]])|0; + if (i<16){ + t += f5(br,cr,dr) + hr[0]; + } else if (i<32) { + t += f4(br,cr,dr) + hr[1]; + } else if (i<48) { + t += f3(br,cr,dr) + hr[2]; + } else if (i<64) { + t += f2(br,cr,dr) + hr[3]; + } else {// if (i<80) { + t += f1(br,cr,dr) + hr[4]; + } + t = t|0; + t = rotl(t,sr[i]) ; + t = (t+er)|0; + ar = er; + er = dr; + dr = rotl(cr, 10); + cr = br; + br = t; + } + // Intermediate hash value + t = (H[1] + cl + dr)|0; + H[1] = (H[2] + dl + er)|0; + H[2] = (H[3] + el + ar)|0; + H[3] = (H[4] + al + br)|0; + H[4] = (H[0] + bl + cr)|0; + H[0] = t; + }, + + _doFinalize: function () { + // Shortcuts + var data = this._data; + var dataWords = data.words; + + var nBitsTotal = this._nDataBytes * 8; + var nBitsLeft = data.sigBytes * 8; + + // Add padding + dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32); + dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = ( + (((nBitsTotal << 8) | (nBitsTotal >>> 24)) & 0x00ff00ff) | + (((nBitsTotal << 24) | (nBitsTotal >>> 8)) & 0xff00ff00) + ); + data.sigBytes = (dataWords.length + 1) * 4; + + // Hash final blocks + this._process(); + + // Shortcuts + var hash = this._hash; + var H = hash.words; + + // Swap endian + for (var i = 0; i < 5; i++) { + // Shortcut + var H_i = H[i]; + + // Swap + H[i] = (((H_i << 8) | (H_i >>> 24)) & 0x00ff00ff) | + (((H_i << 24) | (H_i >>> 8)) & 0xff00ff00); + } + + // Return final computed hash + return hash; + }, + + clone: function () { + var clone = Hasher.clone.call(this); + clone._hash = this._hash.clone(); + + return clone; + } + }); + + + function f1(x, y, z) { + return ((x) ^ (y) ^ (z)); + + } + + function f2(x, y, z) { + return (((x)&(y)) | ((~x)&(z))); + } + + function f3(x, y, z) { + return (((x) | (~(y))) ^ (z)); + } + + function f4(x, y, z) { + return (((x) & (z)) | ((y)&(~(z)))); + } + + function f5(x, y, z) { + return ((x) ^ ((y) |(~(z)))); + + } + + function rotl(x,n) { + return (x<>>(32-n)); + } + + + /** + * Shortcut function to the hasher's object interface. + * + * @param {WordArray|string} message The message to hash. + * + * @return {WordArray} The hash. + * + * @static + * + * @example + * + * var hash = CryptoJS.RIPEMD160('message'); + * var hash = CryptoJS.RIPEMD160(wordArray); + */ + C.RIPEMD160 = Hasher._createHelper(RIPEMD160); + + /** + * Shortcut function to the HMAC's object interface. + * + * @param {WordArray|string} message The message to hash. + * @param {WordArray|string} key The secret key. + * + * @return {WordArray} The HMAC. + * + * @static + * + * @example + * + * var hmac = CryptoJS.HmacRIPEMD160(message, key); + */ + C.HmacRIPEMD160 = Hasher._createHmacHelper(RIPEMD160); + }(Math)); + + + return CryptoJS.RIPEMD160; + +})); \ No newline at end of file diff --git a/node_modules/crypto-js/sha1.js b/node_modules/crypto-js/sha1.js new file mode 100644 index 0000000..6691149 --- /dev/null +++ b/node_modules/crypto-js/sha1.js @@ -0,0 +1,150 @@ +;(function (root, factory) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require("./core")); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + (function () { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var WordArray = C_lib.WordArray; + var Hasher = C_lib.Hasher; + var C_algo = C.algo; + + // Reusable object + var W = []; + + /** + * SHA-1 hash algorithm. + */ + var SHA1 = C_algo.SHA1 = Hasher.extend({ + _doReset: function () { + this._hash = new WordArray.init([ + 0x67452301, 0xefcdab89, + 0x98badcfe, 0x10325476, + 0xc3d2e1f0 + ]); + }, + + _doProcessBlock: function (M, offset) { + // Shortcut + var H = this._hash.words; + + // Working variables + var a = H[0]; + var b = H[1]; + var c = H[2]; + var d = H[3]; + var e = H[4]; + + // Computation + for (var i = 0; i < 80; i++) { + if (i < 16) { + W[i] = M[offset + i] | 0; + } else { + var n = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16]; + W[i] = (n << 1) | (n >>> 31); + } + + var t = ((a << 5) | (a >>> 27)) + e + W[i]; + if (i < 20) { + t += ((b & c) | (~b & d)) + 0x5a827999; + } else if (i < 40) { + t += (b ^ c ^ d) + 0x6ed9eba1; + } else if (i < 60) { + t += ((b & c) | (b & d) | (c & d)) - 0x70e44324; + } else /* if (i < 80) */ { + t += (b ^ c ^ d) - 0x359d3e2a; + } + + e = d; + d = c; + c = (b << 30) | (b >>> 2); + b = a; + a = t; + } + + // Intermediate hash value + H[0] = (H[0] + a) | 0; + H[1] = (H[1] + b) | 0; + H[2] = (H[2] + c) | 0; + H[3] = (H[3] + d) | 0; + H[4] = (H[4] + e) | 0; + }, + + _doFinalize: function () { + // Shortcuts + var data = this._data; + var dataWords = data.words; + + var nBitsTotal = this._nDataBytes * 8; + var nBitsLeft = data.sigBytes * 8; + + // Add padding + dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32); + dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = Math.floor(nBitsTotal / 0x100000000); + dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = nBitsTotal; + data.sigBytes = dataWords.length * 4; + + // Hash final blocks + this._process(); + + // Return final computed hash + return this._hash; + }, + + clone: function () { + var clone = Hasher.clone.call(this); + clone._hash = this._hash.clone(); + + return clone; + } + }); + + /** + * Shortcut function to the hasher's object interface. + * + * @param {WordArray|string} message The message to hash. + * + * @return {WordArray} The hash. + * + * @static + * + * @example + * + * var hash = CryptoJS.SHA1('message'); + * var hash = CryptoJS.SHA1(wordArray); + */ + C.SHA1 = Hasher._createHelper(SHA1); + + /** + * Shortcut function to the HMAC's object interface. + * + * @param {WordArray|string} message The message to hash. + * @param {WordArray|string} key The secret key. + * + * @return {WordArray} The HMAC. + * + * @static + * + * @example + * + * var hmac = CryptoJS.HmacSHA1(message, key); + */ + C.HmacSHA1 = Hasher._createHmacHelper(SHA1); + }()); + + + return CryptoJS.SHA1; + +})); \ No newline at end of file diff --git a/node_modules/crypto-js/sha224.js b/node_modules/crypto-js/sha224.js new file mode 100644 index 0000000..d8ce988 --- /dev/null +++ b/node_modules/crypto-js/sha224.js @@ -0,0 +1,80 @@ +;(function (root, factory, undef) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require("./core"), require("./sha256")); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core", "./sha256"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + (function () { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var WordArray = C_lib.WordArray; + var C_algo = C.algo; + var SHA256 = C_algo.SHA256; + + /** + * SHA-224 hash algorithm. + */ + var SHA224 = C_algo.SHA224 = SHA256.extend({ + _doReset: function () { + this._hash = new WordArray.init([ + 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, + 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4 + ]); + }, + + _doFinalize: function () { + var hash = SHA256._doFinalize.call(this); + + hash.sigBytes -= 4; + + return hash; + } + }); + + /** + * Shortcut function to the hasher's object interface. + * + * @param {WordArray|string} message The message to hash. + * + * @return {WordArray} The hash. + * + * @static + * + * @example + * + * var hash = CryptoJS.SHA224('message'); + * var hash = CryptoJS.SHA224(wordArray); + */ + C.SHA224 = SHA256._createHelper(SHA224); + + /** + * Shortcut function to the HMAC's object interface. + * + * @param {WordArray|string} message The message to hash. + * @param {WordArray|string} key The secret key. + * + * @return {WordArray} The HMAC. + * + * @static + * + * @example + * + * var hmac = CryptoJS.HmacSHA224(message, key); + */ + C.HmacSHA224 = SHA256._createHmacHelper(SHA224); + }()); + + + return CryptoJS.SHA224; + +})); \ No newline at end of file diff --git a/node_modules/crypto-js/sha256.js b/node_modules/crypto-js/sha256.js new file mode 100644 index 0000000..de2d7fc --- /dev/null +++ b/node_modules/crypto-js/sha256.js @@ -0,0 +1,199 @@ +;(function (root, factory) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require("./core")); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + (function (Math) { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var WordArray = C_lib.WordArray; + var Hasher = C_lib.Hasher; + var C_algo = C.algo; + + // Initialization and round constants tables + var H = []; + var K = []; + + // Compute constants + (function () { + function isPrime(n) { + var sqrtN = Math.sqrt(n); + for (var factor = 2; factor <= sqrtN; factor++) { + if (!(n % factor)) { + return false; + } + } + + return true; + } + + function getFractionalBits(n) { + return ((n - (n | 0)) * 0x100000000) | 0; + } + + var n = 2; + var nPrime = 0; + while (nPrime < 64) { + if (isPrime(n)) { + if (nPrime < 8) { + H[nPrime] = getFractionalBits(Math.pow(n, 1 / 2)); + } + K[nPrime] = getFractionalBits(Math.pow(n, 1 / 3)); + + nPrime++; + } + + n++; + } + }()); + + // Reusable object + var W = []; + + /** + * SHA-256 hash algorithm. + */ + var SHA256 = C_algo.SHA256 = Hasher.extend({ + _doReset: function () { + this._hash = new WordArray.init(H.slice(0)); + }, + + _doProcessBlock: function (M, offset) { + // Shortcut + var H = this._hash.words; + + // Working variables + var a = H[0]; + var b = H[1]; + var c = H[2]; + var d = H[3]; + var e = H[4]; + var f = H[5]; + var g = H[6]; + var h = H[7]; + + // Computation + for (var i = 0; i < 64; i++) { + if (i < 16) { + W[i] = M[offset + i] | 0; + } else { + var gamma0x = W[i - 15]; + var gamma0 = ((gamma0x << 25) | (gamma0x >>> 7)) ^ + ((gamma0x << 14) | (gamma0x >>> 18)) ^ + (gamma0x >>> 3); + + var gamma1x = W[i - 2]; + var gamma1 = ((gamma1x << 15) | (gamma1x >>> 17)) ^ + ((gamma1x << 13) | (gamma1x >>> 19)) ^ + (gamma1x >>> 10); + + W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16]; + } + + var ch = (e & f) ^ (~e & g); + var maj = (a & b) ^ (a & c) ^ (b & c); + + var sigma0 = ((a << 30) | (a >>> 2)) ^ ((a << 19) | (a >>> 13)) ^ ((a << 10) | (a >>> 22)); + var sigma1 = ((e << 26) | (e >>> 6)) ^ ((e << 21) | (e >>> 11)) ^ ((e << 7) | (e >>> 25)); + + var t1 = h + sigma1 + ch + K[i] + W[i]; + var t2 = sigma0 + maj; + + h = g; + g = f; + f = e; + e = (d + t1) | 0; + d = c; + c = b; + b = a; + a = (t1 + t2) | 0; + } + + // Intermediate hash value + H[0] = (H[0] + a) | 0; + H[1] = (H[1] + b) | 0; + H[2] = (H[2] + c) | 0; + H[3] = (H[3] + d) | 0; + H[4] = (H[4] + e) | 0; + H[5] = (H[5] + f) | 0; + H[6] = (H[6] + g) | 0; + H[7] = (H[7] + h) | 0; + }, + + _doFinalize: function () { + // Shortcuts + var data = this._data; + var dataWords = data.words; + + var nBitsTotal = this._nDataBytes * 8; + var nBitsLeft = data.sigBytes * 8; + + // Add padding + dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32); + dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = Math.floor(nBitsTotal / 0x100000000); + dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = nBitsTotal; + data.sigBytes = dataWords.length * 4; + + // Hash final blocks + this._process(); + + // Return final computed hash + return this._hash; + }, + + clone: function () { + var clone = Hasher.clone.call(this); + clone._hash = this._hash.clone(); + + return clone; + } + }); + + /** + * Shortcut function to the hasher's object interface. + * + * @param {WordArray|string} message The message to hash. + * + * @return {WordArray} The hash. + * + * @static + * + * @example + * + * var hash = CryptoJS.SHA256('message'); + * var hash = CryptoJS.SHA256(wordArray); + */ + C.SHA256 = Hasher._createHelper(SHA256); + + /** + * Shortcut function to the HMAC's object interface. + * + * @param {WordArray|string} message The message to hash. + * @param {WordArray|string} key The secret key. + * + * @return {WordArray} The HMAC. + * + * @static + * + * @example + * + * var hmac = CryptoJS.HmacSHA256(message, key); + */ + C.HmacSHA256 = Hasher._createHmacHelper(SHA256); + }(Math)); + + + return CryptoJS.SHA256; + +})); \ No newline at end of file diff --git a/node_modules/crypto-js/sha3.js b/node_modules/crypto-js/sha3.js new file mode 100644 index 0000000..34ad86c --- /dev/null +++ b/node_modules/crypto-js/sha3.js @@ -0,0 +1,326 @@ +;(function (root, factory, undef) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require("./core"), require("./x64-core")); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core", "./x64-core"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + (function (Math) { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var WordArray = C_lib.WordArray; + var Hasher = C_lib.Hasher; + var C_x64 = C.x64; + var X64Word = C_x64.Word; + var C_algo = C.algo; + + // Constants tables + var RHO_OFFSETS = []; + var PI_INDEXES = []; + var ROUND_CONSTANTS = []; + + // Compute Constants + (function () { + // Compute rho offset constants + var x = 1, y = 0; + for (var t = 0; t < 24; t++) { + RHO_OFFSETS[x + 5 * y] = ((t + 1) * (t + 2) / 2) % 64; + + var newX = y % 5; + var newY = (2 * x + 3 * y) % 5; + x = newX; + y = newY; + } + + // Compute pi index constants + for (var x = 0; x < 5; x++) { + for (var y = 0; y < 5; y++) { + PI_INDEXES[x + 5 * y] = y + ((2 * x + 3 * y) % 5) * 5; + } + } + + // Compute round constants + var LFSR = 0x01; + for (var i = 0; i < 24; i++) { + var roundConstantMsw = 0; + var roundConstantLsw = 0; + + for (var j = 0; j < 7; j++) { + if (LFSR & 0x01) { + var bitPosition = (1 << j) - 1; + if (bitPosition < 32) { + roundConstantLsw ^= 1 << bitPosition; + } else /* if (bitPosition >= 32) */ { + roundConstantMsw ^= 1 << (bitPosition - 32); + } + } + + // Compute next LFSR + if (LFSR & 0x80) { + // Primitive polynomial over GF(2): x^8 + x^6 + x^5 + x^4 + 1 + LFSR = (LFSR << 1) ^ 0x71; + } else { + LFSR <<= 1; + } + } + + ROUND_CONSTANTS[i] = X64Word.create(roundConstantMsw, roundConstantLsw); + } + }()); + + // Reusable objects for temporary values + var T = []; + (function () { + for (var i = 0; i < 25; i++) { + T[i] = X64Word.create(); + } + }()); + + /** + * SHA-3 hash algorithm. + */ + var SHA3 = C_algo.SHA3 = Hasher.extend({ + /** + * Configuration options. + * + * @property {number} outputLength + * The desired number of bits in the output hash. + * Only values permitted are: 224, 256, 384, 512. + * Default: 512 + */ + cfg: Hasher.cfg.extend({ + outputLength: 512 + }), + + _doReset: function () { + var state = this._state = [] + for (var i = 0; i < 25; i++) { + state[i] = new X64Word.init(); + } + + this.blockSize = (1600 - 2 * this.cfg.outputLength) / 32; + }, + + _doProcessBlock: function (M, offset) { + // Shortcuts + var state = this._state; + var nBlockSizeLanes = this.blockSize / 2; + + // Absorb + for (var i = 0; i < nBlockSizeLanes; i++) { + // Shortcuts + var M2i = M[offset + 2 * i]; + var M2i1 = M[offset + 2 * i + 1]; + + // Swap endian + M2i = ( + (((M2i << 8) | (M2i >>> 24)) & 0x00ff00ff) | + (((M2i << 24) | (M2i >>> 8)) & 0xff00ff00) + ); + M2i1 = ( + (((M2i1 << 8) | (M2i1 >>> 24)) & 0x00ff00ff) | + (((M2i1 << 24) | (M2i1 >>> 8)) & 0xff00ff00) + ); + + // Absorb message into state + var lane = state[i]; + lane.high ^= M2i1; + lane.low ^= M2i; + } + + // Rounds + for (var round = 0; round < 24; round++) { + // Theta + for (var x = 0; x < 5; x++) { + // Mix column lanes + var tMsw = 0, tLsw = 0; + for (var y = 0; y < 5; y++) { + var lane = state[x + 5 * y]; + tMsw ^= lane.high; + tLsw ^= lane.low; + } + + // Temporary values + var Tx = T[x]; + Tx.high = tMsw; + Tx.low = tLsw; + } + for (var x = 0; x < 5; x++) { + // Shortcuts + var Tx4 = T[(x + 4) % 5]; + var Tx1 = T[(x + 1) % 5]; + var Tx1Msw = Tx1.high; + var Tx1Lsw = Tx1.low; + + // Mix surrounding columns + var tMsw = Tx4.high ^ ((Tx1Msw << 1) | (Tx1Lsw >>> 31)); + var tLsw = Tx4.low ^ ((Tx1Lsw << 1) | (Tx1Msw >>> 31)); + for (var y = 0; y < 5; y++) { + var lane = state[x + 5 * y]; + lane.high ^= tMsw; + lane.low ^= tLsw; + } + } + + // Rho Pi + for (var laneIndex = 1; laneIndex < 25; laneIndex++) { + var tMsw; + var tLsw; + + // Shortcuts + var lane = state[laneIndex]; + var laneMsw = lane.high; + var laneLsw = lane.low; + var rhoOffset = RHO_OFFSETS[laneIndex]; + + // Rotate lanes + if (rhoOffset < 32) { + tMsw = (laneMsw << rhoOffset) | (laneLsw >>> (32 - rhoOffset)); + tLsw = (laneLsw << rhoOffset) | (laneMsw >>> (32 - rhoOffset)); + } else /* if (rhoOffset >= 32) */ { + tMsw = (laneLsw << (rhoOffset - 32)) | (laneMsw >>> (64 - rhoOffset)); + tLsw = (laneMsw << (rhoOffset - 32)) | (laneLsw >>> (64 - rhoOffset)); + } + + // Transpose lanes + var TPiLane = T[PI_INDEXES[laneIndex]]; + TPiLane.high = tMsw; + TPiLane.low = tLsw; + } + + // Rho pi at x = y = 0 + var T0 = T[0]; + var state0 = state[0]; + T0.high = state0.high; + T0.low = state0.low; + + // Chi + for (var x = 0; x < 5; x++) { + for (var y = 0; y < 5; y++) { + // Shortcuts + var laneIndex = x + 5 * y; + var lane = state[laneIndex]; + var TLane = T[laneIndex]; + var Tx1Lane = T[((x + 1) % 5) + 5 * y]; + var Tx2Lane = T[((x + 2) % 5) + 5 * y]; + + // Mix rows + lane.high = TLane.high ^ (~Tx1Lane.high & Tx2Lane.high); + lane.low = TLane.low ^ (~Tx1Lane.low & Tx2Lane.low); + } + } + + // Iota + var lane = state[0]; + var roundConstant = ROUND_CONSTANTS[round]; + lane.high ^= roundConstant.high; + lane.low ^= roundConstant.low; + } + }, + + _doFinalize: function () { + // Shortcuts + var data = this._data; + var dataWords = data.words; + var nBitsTotal = this._nDataBytes * 8; + var nBitsLeft = data.sigBytes * 8; + var blockSizeBits = this.blockSize * 32; + + // Add padding + dataWords[nBitsLeft >>> 5] |= 0x1 << (24 - nBitsLeft % 32); + dataWords[((Math.ceil((nBitsLeft + 1) / blockSizeBits) * blockSizeBits) >>> 5) - 1] |= 0x80; + data.sigBytes = dataWords.length * 4; + + // Hash final blocks + this._process(); + + // Shortcuts + var state = this._state; + var outputLengthBytes = this.cfg.outputLength / 8; + var outputLengthLanes = outputLengthBytes / 8; + + // Squeeze + var hashWords = []; + for (var i = 0; i < outputLengthLanes; i++) { + // Shortcuts + var lane = state[i]; + var laneMsw = lane.high; + var laneLsw = lane.low; + + // Swap endian + laneMsw = ( + (((laneMsw << 8) | (laneMsw >>> 24)) & 0x00ff00ff) | + (((laneMsw << 24) | (laneMsw >>> 8)) & 0xff00ff00) + ); + laneLsw = ( + (((laneLsw << 8) | (laneLsw >>> 24)) & 0x00ff00ff) | + (((laneLsw << 24) | (laneLsw >>> 8)) & 0xff00ff00) + ); + + // Squeeze state to retrieve hash + hashWords.push(laneLsw); + hashWords.push(laneMsw); + } + + // Return final computed hash + return new WordArray.init(hashWords, outputLengthBytes); + }, + + clone: function () { + var clone = Hasher.clone.call(this); + + var state = clone._state = this._state.slice(0); + for (var i = 0; i < 25; i++) { + state[i] = state[i].clone(); + } + + return clone; + } + }); + + /** + * Shortcut function to the hasher's object interface. + * + * @param {WordArray|string} message The message to hash. + * + * @return {WordArray} The hash. + * + * @static + * + * @example + * + * var hash = CryptoJS.SHA3('message'); + * var hash = CryptoJS.SHA3(wordArray); + */ + C.SHA3 = Hasher._createHelper(SHA3); + + /** + * Shortcut function to the HMAC's object interface. + * + * @param {WordArray|string} message The message to hash. + * @param {WordArray|string} key The secret key. + * + * @return {WordArray} The HMAC. + * + * @static + * + * @example + * + * var hmac = CryptoJS.HmacSHA3(message, key); + */ + C.HmacSHA3 = Hasher._createHmacHelper(SHA3); + }(Math)); + + + return CryptoJS.SHA3; + +})); \ No newline at end of file diff --git a/node_modules/crypto-js/sha384.js b/node_modules/crypto-js/sha384.js new file mode 100644 index 0000000..a0b95bf --- /dev/null +++ b/node_modules/crypto-js/sha384.js @@ -0,0 +1,83 @@ +;(function (root, factory, undef) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require("./core"), require("./x64-core"), require("./sha512")); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core", "./x64-core", "./sha512"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + (function () { + // Shortcuts + var C = CryptoJS; + var C_x64 = C.x64; + var X64Word = C_x64.Word; + var X64WordArray = C_x64.WordArray; + var C_algo = C.algo; + var SHA512 = C_algo.SHA512; + + /** + * SHA-384 hash algorithm. + */ + var SHA384 = C_algo.SHA384 = SHA512.extend({ + _doReset: function () { + this._hash = new X64WordArray.init([ + new X64Word.init(0xcbbb9d5d, 0xc1059ed8), new X64Word.init(0x629a292a, 0x367cd507), + new X64Word.init(0x9159015a, 0x3070dd17), new X64Word.init(0x152fecd8, 0xf70e5939), + new X64Word.init(0x67332667, 0xffc00b31), new X64Word.init(0x8eb44a87, 0x68581511), + new X64Word.init(0xdb0c2e0d, 0x64f98fa7), new X64Word.init(0x47b5481d, 0xbefa4fa4) + ]); + }, + + _doFinalize: function () { + var hash = SHA512._doFinalize.call(this); + + hash.sigBytes -= 16; + + return hash; + } + }); + + /** + * Shortcut function to the hasher's object interface. + * + * @param {WordArray|string} message The message to hash. + * + * @return {WordArray} The hash. + * + * @static + * + * @example + * + * var hash = CryptoJS.SHA384('message'); + * var hash = CryptoJS.SHA384(wordArray); + */ + C.SHA384 = SHA512._createHelper(SHA384); + + /** + * Shortcut function to the HMAC's object interface. + * + * @param {WordArray|string} message The message to hash. + * @param {WordArray|string} key The secret key. + * + * @return {WordArray} The HMAC. + * + * @static + * + * @example + * + * var hmac = CryptoJS.HmacSHA384(message, key); + */ + C.HmacSHA384 = SHA512._createHmacHelper(SHA384); + }()); + + + return CryptoJS.SHA384; + +})); \ No newline at end of file diff --git a/node_modules/crypto-js/sha512.js b/node_modules/crypto-js/sha512.js new file mode 100644 index 0000000..d274ab0 --- /dev/null +++ b/node_modules/crypto-js/sha512.js @@ -0,0 +1,326 @@ +;(function (root, factory, undef) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require("./core"), require("./x64-core")); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core", "./x64-core"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + (function () { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var Hasher = C_lib.Hasher; + var C_x64 = C.x64; + var X64Word = C_x64.Word; + var X64WordArray = C_x64.WordArray; + var C_algo = C.algo; + + function X64Word_create() { + return X64Word.create.apply(X64Word, arguments); + } + + // Constants + var K = [ + X64Word_create(0x428a2f98, 0xd728ae22), X64Word_create(0x71374491, 0x23ef65cd), + X64Word_create(0xb5c0fbcf, 0xec4d3b2f), X64Word_create(0xe9b5dba5, 0x8189dbbc), + X64Word_create(0x3956c25b, 0xf348b538), X64Word_create(0x59f111f1, 0xb605d019), + X64Word_create(0x923f82a4, 0xaf194f9b), X64Word_create(0xab1c5ed5, 0xda6d8118), + X64Word_create(0xd807aa98, 0xa3030242), X64Word_create(0x12835b01, 0x45706fbe), + X64Word_create(0x243185be, 0x4ee4b28c), X64Word_create(0x550c7dc3, 0xd5ffb4e2), + X64Word_create(0x72be5d74, 0xf27b896f), X64Word_create(0x80deb1fe, 0x3b1696b1), + X64Word_create(0x9bdc06a7, 0x25c71235), X64Word_create(0xc19bf174, 0xcf692694), + X64Word_create(0xe49b69c1, 0x9ef14ad2), X64Word_create(0xefbe4786, 0x384f25e3), + X64Word_create(0x0fc19dc6, 0x8b8cd5b5), X64Word_create(0x240ca1cc, 0x77ac9c65), + X64Word_create(0x2de92c6f, 0x592b0275), X64Word_create(0x4a7484aa, 0x6ea6e483), + X64Word_create(0x5cb0a9dc, 0xbd41fbd4), X64Word_create(0x76f988da, 0x831153b5), + X64Word_create(0x983e5152, 0xee66dfab), X64Word_create(0xa831c66d, 0x2db43210), + X64Word_create(0xb00327c8, 0x98fb213f), X64Word_create(0xbf597fc7, 0xbeef0ee4), + X64Word_create(0xc6e00bf3, 0x3da88fc2), X64Word_create(0xd5a79147, 0x930aa725), + X64Word_create(0x06ca6351, 0xe003826f), X64Word_create(0x14292967, 0x0a0e6e70), + X64Word_create(0x27b70a85, 0x46d22ffc), X64Word_create(0x2e1b2138, 0x5c26c926), + X64Word_create(0x4d2c6dfc, 0x5ac42aed), X64Word_create(0x53380d13, 0x9d95b3df), + X64Word_create(0x650a7354, 0x8baf63de), X64Word_create(0x766a0abb, 0x3c77b2a8), + X64Word_create(0x81c2c92e, 0x47edaee6), X64Word_create(0x92722c85, 0x1482353b), + X64Word_create(0xa2bfe8a1, 0x4cf10364), X64Word_create(0xa81a664b, 0xbc423001), + X64Word_create(0xc24b8b70, 0xd0f89791), X64Word_create(0xc76c51a3, 0x0654be30), + X64Word_create(0xd192e819, 0xd6ef5218), X64Word_create(0xd6990624, 0x5565a910), + X64Word_create(0xf40e3585, 0x5771202a), X64Word_create(0x106aa070, 0x32bbd1b8), + X64Word_create(0x19a4c116, 0xb8d2d0c8), X64Word_create(0x1e376c08, 0x5141ab53), + X64Word_create(0x2748774c, 0xdf8eeb99), X64Word_create(0x34b0bcb5, 0xe19b48a8), + X64Word_create(0x391c0cb3, 0xc5c95a63), X64Word_create(0x4ed8aa4a, 0xe3418acb), + X64Word_create(0x5b9cca4f, 0x7763e373), X64Word_create(0x682e6ff3, 0xd6b2b8a3), + X64Word_create(0x748f82ee, 0x5defb2fc), X64Word_create(0x78a5636f, 0x43172f60), + X64Word_create(0x84c87814, 0xa1f0ab72), X64Word_create(0x8cc70208, 0x1a6439ec), + X64Word_create(0x90befffa, 0x23631e28), X64Word_create(0xa4506ceb, 0xde82bde9), + X64Word_create(0xbef9a3f7, 0xb2c67915), X64Word_create(0xc67178f2, 0xe372532b), + X64Word_create(0xca273ece, 0xea26619c), X64Word_create(0xd186b8c7, 0x21c0c207), + X64Word_create(0xeada7dd6, 0xcde0eb1e), X64Word_create(0xf57d4f7f, 0xee6ed178), + X64Word_create(0x06f067aa, 0x72176fba), X64Word_create(0x0a637dc5, 0xa2c898a6), + X64Word_create(0x113f9804, 0xbef90dae), X64Word_create(0x1b710b35, 0x131c471b), + X64Word_create(0x28db77f5, 0x23047d84), X64Word_create(0x32caab7b, 0x40c72493), + X64Word_create(0x3c9ebe0a, 0x15c9bebc), X64Word_create(0x431d67c4, 0x9c100d4c), + X64Word_create(0x4cc5d4be, 0xcb3e42b6), X64Word_create(0x597f299c, 0xfc657e2a), + X64Word_create(0x5fcb6fab, 0x3ad6faec), X64Word_create(0x6c44198c, 0x4a475817) + ]; + + // Reusable objects + var W = []; + (function () { + for (var i = 0; i < 80; i++) { + W[i] = X64Word_create(); + } + }()); + + /** + * SHA-512 hash algorithm. + */ + var SHA512 = C_algo.SHA512 = Hasher.extend({ + _doReset: function () { + this._hash = new X64WordArray.init([ + new X64Word.init(0x6a09e667, 0xf3bcc908), new X64Word.init(0xbb67ae85, 0x84caa73b), + new X64Word.init(0x3c6ef372, 0xfe94f82b), new X64Word.init(0xa54ff53a, 0x5f1d36f1), + new X64Word.init(0x510e527f, 0xade682d1), new X64Word.init(0x9b05688c, 0x2b3e6c1f), + new X64Word.init(0x1f83d9ab, 0xfb41bd6b), new X64Word.init(0x5be0cd19, 0x137e2179) + ]); + }, + + _doProcessBlock: function (M, offset) { + // Shortcuts + var H = this._hash.words; + + var H0 = H[0]; + var H1 = H[1]; + var H2 = H[2]; + var H3 = H[3]; + var H4 = H[4]; + var H5 = H[5]; + var H6 = H[6]; + var H7 = H[7]; + + var H0h = H0.high; + var H0l = H0.low; + var H1h = H1.high; + var H1l = H1.low; + var H2h = H2.high; + var H2l = H2.low; + var H3h = H3.high; + var H3l = H3.low; + var H4h = H4.high; + var H4l = H4.low; + var H5h = H5.high; + var H5l = H5.low; + var H6h = H6.high; + var H6l = H6.low; + var H7h = H7.high; + var H7l = H7.low; + + // Working variables + var ah = H0h; + var al = H0l; + var bh = H1h; + var bl = H1l; + var ch = H2h; + var cl = H2l; + var dh = H3h; + var dl = H3l; + var eh = H4h; + var el = H4l; + var fh = H5h; + var fl = H5l; + var gh = H6h; + var gl = H6l; + var hh = H7h; + var hl = H7l; + + // Rounds + for (var i = 0; i < 80; i++) { + var Wil; + var Wih; + + // Shortcut + var Wi = W[i]; + + // Extend message + if (i < 16) { + Wih = Wi.high = M[offset + i * 2] | 0; + Wil = Wi.low = M[offset + i * 2 + 1] | 0; + } else { + // Gamma0 + var gamma0x = W[i - 15]; + var gamma0xh = gamma0x.high; + var gamma0xl = gamma0x.low; + var gamma0h = ((gamma0xh >>> 1) | (gamma0xl << 31)) ^ ((gamma0xh >>> 8) | (gamma0xl << 24)) ^ (gamma0xh >>> 7); + var gamma0l = ((gamma0xl >>> 1) | (gamma0xh << 31)) ^ ((gamma0xl >>> 8) | (gamma0xh << 24)) ^ ((gamma0xl >>> 7) | (gamma0xh << 25)); + + // Gamma1 + var gamma1x = W[i - 2]; + var gamma1xh = gamma1x.high; + var gamma1xl = gamma1x.low; + var gamma1h = ((gamma1xh >>> 19) | (gamma1xl << 13)) ^ ((gamma1xh << 3) | (gamma1xl >>> 29)) ^ (gamma1xh >>> 6); + var gamma1l = ((gamma1xl >>> 19) | (gamma1xh << 13)) ^ ((gamma1xl << 3) | (gamma1xh >>> 29)) ^ ((gamma1xl >>> 6) | (gamma1xh << 26)); + + // W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16] + var Wi7 = W[i - 7]; + var Wi7h = Wi7.high; + var Wi7l = Wi7.low; + + var Wi16 = W[i - 16]; + var Wi16h = Wi16.high; + var Wi16l = Wi16.low; + + Wil = gamma0l + Wi7l; + Wih = gamma0h + Wi7h + ((Wil >>> 0) < (gamma0l >>> 0) ? 1 : 0); + Wil = Wil + gamma1l; + Wih = Wih + gamma1h + ((Wil >>> 0) < (gamma1l >>> 0) ? 1 : 0); + Wil = Wil + Wi16l; + Wih = Wih + Wi16h + ((Wil >>> 0) < (Wi16l >>> 0) ? 1 : 0); + + Wi.high = Wih; + Wi.low = Wil; + } + + var chh = (eh & fh) ^ (~eh & gh); + var chl = (el & fl) ^ (~el & gl); + var majh = (ah & bh) ^ (ah & ch) ^ (bh & ch); + var majl = (al & bl) ^ (al & cl) ^ (bl & cl); + + var sigma0h = ((ah >>> 28) | (al << 4)) ^ ((ah << 30) | (al >>> 2)) ^ ((ah << 25) | (al >>> 7)); + var sigma0l = ((al >>> 28) | (ah << 4)) ^ ((al << 30) | (ah >>> 2)) ^ ((al << 25) | (ah >>> 7)); + var sigma1h = ((eh >>> 14) | (el << 18)) ^ ((eh >>> 18) | (el << 14)) ^ ((eh << 23) | (el >>> 9)); + var sigma1l = ((el >>> 14) | (eh << 18)) ^ ((el >>> 18) | (eh << 14)) ^ ((el << 23) | (eh >>> 9)); + + // t1 = h + sigma1 + ch + K[i] + W[i] + var Ki = K[i]; + var Kih = Ki.high; + var Kil = Ki.low; + + var t1l = hl + sigma1l; + var t1h = hh + sigma1h + ((t1l >>> 0) < (hl >>> 0) ? 1 : 0); + var t1l = t1l + chl; + var t1h = t1h + chh + ((t1l >>> 0) < (chl >>> 0) ? 1 : 0); + var t1l = t1l + Kil; + var t1h = t1h + Kih + ((t1l >>> 0) < (Kil >>> 0) ? 1 : 0); + var t1l = t1l + Wil; + var t1h = t1h + Wih + ((t1l >>> 0) < (Wil >>> 0) ? 1 : 0); + + // t2 = sigma0 + maj + var t2l = sigma0l + majl; + var t2h = sigma0h + majh + ((t2l >>> 0) < (sigma0l >>> 0) ? 1 : 0); + + // Update working variables + hh = gh; + hl = gl; + gh = fh; + gl = fl; + fh = eh; + fl = el; + el = (dl + t1l) | 0; + eh = (dh + t1h + ((el >>> 0) < (dl >>> 0) ? 1 : 0)) | 0; + dh = ch; + dl = cl; + ch = bh; + cl = bl; + bh = ah; + bl = al; + al = (t1l + t2l) | 0; + ah = (t1h + t2h + ((al >>> 0) < (t1l >>> 0) ? 1 : 0)) | 0; + } + + // Intermediate hash value + H0l = H0.low = (H0l + al); + H0.high = (H0h + ah + ((H0l >>> 0) < (al >>> 0) ? 1 : 0)); + H1l = H1.low = (H1l + bl); + H1.high = (H1h + bh + ((H1l >>> 0) < (bl >>> 0) ? 1 : 0)); + H2l = H2.low = (H2l + cl); + H2.high = (H2h + ch + ((H2l >>> 0) < (cl >>> 0) ? 1 : 0)); + H3l = H3.low = (H3l + dl); + H3.high = (H3h + dh + ((H3l >>> 0) < (dl >>> 0) ? 1 : 0)); + H4l = H4.low = (H4l + el); + H4.high = (H4h + eh + ((H4l >>> 0) < (el >>> 0) ? 1 : 0)); + H5l = H5.low = (H5l + fl); + H5.high = (H5h + fh + ((H5l >>> 0) < (fl >>> 0) ? 1 : 0)); + H6l = H6.low = (H6l + gl); + H6.high = (H6h + gh + ((H6l >>> 0) < (gl >>> 0) ? 1 : 0)); + H7l = H7.low = (H7l + hl); + H7.high = (H7h + hh + ((H7l >>> 0) < (hl >>> 0) ? 1 : 0)); + }, + + _doFinalize: function () { + // Shortcuts + var data = this._data; + var dataWords = data.words; + + var nBitsTotal = this._nDataBytes * 8; + var nBitsLeft = data.sigBytes * 8; + + // Add padding + dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32); + dataWords[(((nBitsLeft + 128) >>> 10) << 5) + 30] = Math.floor(nBitsTotal / 0x100000000); + dataWords[(((nBitsLeft + 128) >>> 10) << 5) + 31] = nBitsTotal; + data.sigBytes = dataWords.length * 4; + + // Hash final blocks + this._process(); + + // Convert hash to 32-bit word array before returning + var hash = this._hash.toX32(); + + // Return final computed hash + return hash; + }, + + clone: function () { + var clone = Hasher.clone.call(this); + clone._hash = this._hash.clone(); + + return clone; + }, + + blockSize: 1024/32 + }); + + /** + * Shortcut function to the hasher's object interface. + * + * @param {WordArray|string} message The message to hash. + * + * @return {WordArray} The hash. + * + * @static + * + * @example + * + * var hash = CryptoJS.SHA512('message'); + * var hash = CryptoJS.SHA512(wordArray); + */ + C.SHA512 = Hasher._createHelper(SHA512); + + /** + * Shortcut function to the HMAC's object interface. + * + * @param {WordArray|string} message The message to hash. + * @param {WordArray|string} key The secret key. + * + * @return {WordArray} The HMAC. + * + * @static + * + * @example + * + * var hmac = CryptoJS.HmacSHA512(message, key); + */ + C.HmacSHA512 = Hasher._createHmacHelper(SHA512); + }()); + + + return CryptoJS.SHA512; + +})); \ No newline at end of file diff --git a/node_modules/crypto-js/tripledes.js b/node_modules/crypto-js/tripledes.js new file mode 100644 index 0000000..1a92477 --- /dev/null +++ b/node_modules/crypto-js/tripledes.js @@ -0,0 +1,779 @@ +;(function (root, factory, undef) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require("./core"), require("./enc-base64"), require("./md5"), require("./evpkdf"), require("./cipher-core")); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core", "./enc-base64", "./md5", "./evpkdf", "./cipher-core"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + (function () { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var WordArray = C_lib.WordArray; + var BlockCipher = C_lib.BlockCipher; + var C_algo = C.algo; + + // Permuted Choice 1 constants + var PC1 = [ + 57, 49, 41, 33, 25, 17, 9, 1, + 58, 50, 42, 34, 26, 18, 10, 2, + 59, 51, 43, 35, 27, 19, 11, 3, + 60, 52, 44, 36, 63, 55, 47, 39, + 31, 23, 15, 7, 62, 54, 46, 38, + 30, 22, 14, 6, 61, 53, 45, 37, + 29, 21, 13, 5, 28, 20, 12, 4 + ]; + + // Permuted Choice 2 constants + var PC2 = [ + 14, 17, 11, 24, 1, 5, + 3, 28, 15, 6, 21, 10, + 23, 19, 12, 4, 26, 8, + 16, 7, 27, 20, 13, 2, + 41, 52, 31, 37, 47, 55, + 30, 40, 51, 45, 33, 48, + 44, 49, 39, 56, 34, 53, + 46, 42, 50, 36, 29, 32 + ]; + + // Cumulative bit shift constants + var BIT_SHIFTS = [1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28]; + + // SBOXes and round permutation constants + var SBOX_P = [ + { + 0x0: 0x808200, + 0x10000000: 0x8000, + 0x20000000: 0x808002, + 0x30000000: 0x2, + 0x40000000: 0x200, + 0x50000000: 0x808202, + 0x60000000: 0x800202, + 0x70000000: 0x800000, + 0x80000000: 0x202, + 0x90000000: 0x800200, + 0xa0000000: 0x8200, + 0xb0000000: 0x808000, + 0xc0000000: 0x8002, + 0xd0000000: 0x800002, + 0xe0000000: 0x0, + 0xf0000000: 0x8202, + 0x8000000: 0x0, + 0x18000000: 0x808202, + 0x28000000: 0x8202, + 0x38000000: 0x8000, + 0x48000000: 0x808200, + 0x58000000: 0x200, + 0x68000000: 0x808002, + 0x78000000: 0x2, + 0x88000000: 0x800200, + 0x98000000: 0x8200, + 0xa8000000: 0x808000, + 0xb8000000: 0x800202, + 0xc8000000: 0x800002, + 0xd8000000: 0x8002, + 0xe8000000: 0x202, + 0xf8000000: 0x800000, + 0x1: 0x8000, + 0x10000001: 0x2, + 0x20000001: 0x808200, + 0x30000001: 0x800000, + 0x40000001: 0x808002, + 0x50000001: 0x8200, + 0x60000001: 0x200, + 0x70000001: 0x800202, + 0x80000001: 0x808202, + 0x90000001: 0x808000, + 0xa0000001: 0x800002, + 0xb0000001: 0x8202, + 0xc0000001: 0x202, + 0xd0000001: 0x800200, + 0xe0000001: 0x8002, + 0xf0000001: 0x0, + 0x8000001: 0x808202, + 0x18000001: 0x808000, + 0x28000001: 0x800000, + 0x38000001: 0x200, + 0x48000001: 0x8000, + 0x58000001: 0x800002, + 0x68000001: 0x2, + 0x78000001: 0x8202, + 0x88000001: 0x8002, + 0x98000001: 0x800202, + 0xa8000001: 0x202, + 0xb8000001: 0x808200, + 0xc8000001: 0x800200, + 0xd8000001: 0x0, + 0xe8000001: 0x8200, + 0xf8000001: 0x808002 + }, + { + 0x0: 0x40084010, + 0x1000000: 0x4000, + 0x2000000: 0x80000, + 0x3000000: 0x40080010, + 0x4000000: 0x40000010, + 0x5000000: 0x40084000, + 0x6000000: 0x40004000, + 0x7000000: 0x10, + 0x8000000: 0x84000, + 0x9000000: 0x40004010, + 0xa000000: 0x40000000, + 0xb000000: 0x84010, + 0xc000000: 0x80010, + 0xd000000: 0x0, + 0xe000000: 0x4010, + 0xf000000: 0x40080000, + 0x800000: 0x40004000, + 0x1800000: 0x84010, + 0x2800000: 0x10, + 0x3800000: 0x40004010, + 0x4800000: 0x40084010, + 0x5800000: 0x40000000, + 0x6800000: 0x80000, + 0x7800000: 0x40080010, + 0x8800000: 0x80010, + 0x9800000: 0x0, + 0xa800000: 0x4000, + 0xb800000: 0x40080000, + 0xc800000: 0x40000010, + 0xd800000: 0x84000, + 0xe800000: 0x40084000, + 0xf800000: 0x4010, + 0x10000000: 0x0, + 0x11000000: 0x40080010, + 0x12000000: 0x40004010, + 0x13000000: 0x40084000, + 0x14000000: 0x40080000, + 0x15000000: 0x10, + 0x16000000: 0x84010, + 0x17000000: 0x4000, + 0x18000000: 0x4010, + 0x19000000: 0x80000, + 0x1a000000: 0x80010, + 0x1b000000: 0x40000010, + 0x1c000000: 0x84000, + 0x1d000000: 0x40004000, + 0x1e000000: 0x40000000, + 0x1f000000: 0x40084010, + 0x10800000: 0x84010, + 0x11800000: 0x80000, + 0x12800000: 0x40080000, + 0x13800000: 0x4000, + 0x14800000: 0x40004000, + 0x15800000: 0x40084010, + 0x16800000: 0x10, + 0x17800000: 0x40000000, + 0x18800000: 0x40084000, + 0x19800000: 0x40000010, + 0x1a800000: 0x40004010, + 0x1b800000: 0x80010, + 0x1c800000: 0x0, + 0x1d800000: 0x4010, + 0x1e800000: 0x40080010, + 0x1f800000: 0x84000 + }, + { + 0x0: 0x104, + 0x100000: 0x0, + 0x200000: 0x4000100, + 0x300000: 0x10104, + 0x400000: 0x10004, + 0x500000: 0x4000004, + 0x600000: 0x4010104, + 0x700000: 0x4010000, + 0x800000: 0x4000000, + 0x900000: 0x4010100, + 0xa00000: 0x10100, + 0xb00000: 0x4010004, + 0xc00000: 0x4000104, + 0xd00000: 0x10000, + 0xe00000: 0x4, + 0xf00000: 0x100, + 0x80000: 0x4010100, + 0x180000: 0x4010004, + 0x280000: 0x0, + 0x380000: 0x4000100, + 0x480000: 0x4000004, + 0x580000: 0x10000, + 0x680000: 0x10004, + 0x780000: 0x104, + 0x880000: 0x4, + 0x980000: 0x100, + 0xa80000: 0x4010000, + 0xb80000: 0x10104, + 0xc80000: 0x10100, + 0xd80000: 0x4000104, + 0xe80000: 0x4010104, + 0xf80000: 0x4000000, + 0x1000000: 0x4010100, + 0x1100000: 0x10004, + 0x1200000: 0x10000, + 0x1300000: 0x4000100, + 0x1400000: 0x100, + 0x1500000: 0x4010104, + 0x1600000: 0x4000004, + 0x1700000: 0x0, + 0x1800000: 0x4000104, + 0x1900000: 0x4000000, + 0x1a00000: 0x4, + 0x1b00000: 0x10100, + 0x1c00000: 0x4010000, + 0x1d00000: 0x104, + 0x1e00000: 0x10104, + 0x1f00000: 0x4010004, + 0x1080000: 0x4000000, + 0x1180000: 0x104, + 0x1280000: 0x4010100, + 0x1380000: 0x0, + 0x1480000: 0x10004, + 0x1580000: 0x4000100, + 0x1680000: 0x100, + 0x1780000: 0x4010004, + 0x1880000: 0x10000, + 0x1980000: 0x4010104, + 0x1a80000: 0x10104, + 0x1b80000: 0x4000004, + 0x1c80000: 0x4000104, + 0x1d80000: 0x4010000, + 0x1e80000: 0x4, + 0x1f80000: 0x10100 + }, + { + 0x0: 0x80401000, + 0x10000: 0x80001040, + 0x20000: 0x401040, + 0x30000: 0x80400000, + 0x40000: 0x0, + 0x50000: 0x401000, + 0x60000: 0x80000040, + 0x70000: 0x400040, + 0x80000: 0x80000000, + 0x90000: 0x400000, + 0xa0000: 0x40, + 0xb0000: 0x80001000, + 0xc0000: 0x80400040, + 0xd0000: 0x1040, + 0xe0000: 0x1000, + 0xf0000: 0x80401040, + 0x8000: 0x80001040, + 0x18000: 0x40, + 0x28000: 0x80400040, + 0x38000: 0x80001000, + 0x48000: 0x401000, + 0x58000: 0x80401040, + 0x68000: 0x0, + 0x78000: 0x80400000, + 0x88000: 0x1000, + 0x98000: 0x80401000, + 0xa8000: 0x400000, + 0xb8000: 0x1040, + 0xc8000: 0x80000000, + 0xd8000: 0x400040, + 0xe8000: 0x401040, + 0xf8000: 0x80000040, + 0x100000: 0x400040, + 0x110000: 0x401000, + 0x120000: 0x80000040, + 0x130000: 0x0, + 0x140000: 0x1040, + 0x150000: 0x80400040, + 0x160000: 0x80401000, + 0x170000: 0x80001040, + 0x180000: 0x80401040, + 0x190000: 0x80000000, + 0x1a0000: 0x80400000, + 0x1b0000: 0x401040, + 0x1c0000: 0x80001000, + 0x1d0000: 0x400000, + 0x1e0000: 0x40, + 0x1f0000: 0x1000, + 0x108000: 0x80400000, + 0x118000: 0x80401040, + 0x128000: 0x0, + 0x138000: 0x401000, + 0x148000: 0x400040, + 0x158000: 0x80000000, + 0x168000: 0x80001040, + 0x178000: 0x40, + 0x188000: 0x80000040, + 0x198000: 0x1000, + 0x1a8000: 0x80001000, + 0x1b8000: 0x80400040, + 0x1c8000: 0x1040, + 0x1d8000: 0x80401000, + 0x1e8000: 0x400000, + 0x1f8000: 0x401040 + }, + { + 0x0: 0x80, + 0x1000: 0x1040000, + 0x2000: 0x40000, + 0x3000: 0x20000000, + 0x4000: 0x20040080, + 0x5000: 0x1000080, + 0x6000: 0x21000080, + 0x7000: 0x40080, + 0x8000: 0x1000000, + 0x9000: 0x20040000, + 0xa000: 0x20000080, + 0xb000: 0x21040080, + 0xc000: 0x21040000, + 0xd000: 0x0, + 0xe000: 0x1040080, + 0xf000: 0x21000000, + 0x800: 0x1040080, + 0x1800: 0x21000080, + 0x2800: 0x80, + 0x3800: 0x1040000, + 0x4800: 0x40000, + 0x5800: 0x20040080, + 0x6800: 0x21040000, + 0x7800: 0x20000000, + 0x8800: 0x20040000, + 0x9800: 0x0, + 0xa800: 0x21040080, + 0xb800: 0x1000080, + 0xc800: 0x20000080, + 0xd800: 0x21000000, + 0xe800: 0x1000000, + 0xf800: 0x40080, + 0x10000: 0x40000, + 0x11000: 0x80, + 0x12000: 0x20000000, + 0x13000: 0x21000080, + 0x14000: 0x1000080, + 0x15000: 0x21040000, + 0x16000: 0x20040080, + 0x17000: 0x1000000, + 0x18000: 0x21040080, + 0x19000: 0x21000000, + 0x1a000: 0x1040000, + 0x1b000: 0x20040000, + 0x1c000: 0x40080, + 0x1d000: 0x20000080, + 0x1e000: 0x0, + 0x1f000: 0x1040080, + 0x10800: 0x21000080, + 0x11800: 0x1000000, + 0x12800: 0x1040000, + 0x13800: 0x20040080, + 0x14800: 0x20000000, + 0x15800: 0x1040080, + 0x16800: 0x80, + 0x17800: 0x21040000, + 0x18800: 0x40080, + 0x19800: 0x21040080, + 0x1a800: 0x0, + 0x1b800: 0x21000000, + 0x1c800: 0x1000080, + 0x1d800: 0x40000, + 0x1e800: 0x20040000, + 0x1f800: 0x20000080 + }, + { + 0x0: 0x10000008, + 0x100: 0x2000, + 0x200: 0x10200000, + 0x300: 0x10202008, + 0x400: 0x10002000, + 0x500: 0x200000, + 0x600: 0x200008, + 0x700: 0x10000000, + 0x800: 0x0, + 0x900: 0x10002008, + 0xa00: 0x202000, + 0xb00: 0x8, + 0xc00: 0x10200008, + 0xd00: 0x202008, + 0xe00: 0x2008, + 0xf00: 0x10202000, + 0x80: 0x10200000, + 0x180: 0x10202008, + 0x280: 0x8, + 0x380: 0x200000, + 0x480: 0x202008, + 0x580: 0x10000008, + 0x680: 0x10002000, + 0x780: 0x2008, + 0x880: 0x200008, + 0x980: 0x2000, + 0xa80: 0x10002008, + 0xb80: 0x10200008, + 0xc80: 0x0, + 0xd80: 0x10202000, + 0xe80: 0x202000, + 0xf80: 0x10000000, + 0x1000: 0x10002000, + 0x1100: 0x10200008, + 0x1200: 0x10202008, + 0x1300: 0x2008, + 0x1400: 0x200000, + 0x1500: 0x10000000, + 0x1600: 0x10000008, + 0x1700: 0x202000, + 0x1800: 0x202008, + 0x1900: 0x0, + 0x1a00: 0x8, + 0x1b00: 0x10200000, + 0x1c00: 0x2000, + 0x1d00: 0x10002008, + 0x1e00: 0x10202000, + 0x1f00: 0x200008, + 0x1080: 0x8, + 0x1180: 0x202000, + 0x1280: 0x200000, + 0x1380: 0x10000008, + 0x1480: 0x10002000, + 0x1580: 0x2008, + 0x1680: 0x10202008, + 0x1780: 0x10200000, + 0x1880: 0x10202000, + 0x1980: 0x10200008, + 0x1a80: 0x2000, + 0x1b80: 0x202008, + 0x1c80: 0x200008, + 0x1d80: 0x0, + 0x1e80: 0x10000000, + 0x1f80: 0x10002008 + }, + { + 0x0: 0x100000, + 0x10: 0x2000401, + 0x20: 0x400, + 0x30: 0x100401, + 0x40: 0x2100401, + 0x50: 0x0, + 0x60: 0x1, + 0x70: 0x2100001, + 0x80: 0x2000400, + 0x90: 0x100001, + 0xa0: 0x2000001, + 0xb0: 0x2100400, + 0xc0: 0x2100000, + 0xd0: 0x401, + 0xe0: 0x100400, + 0xf0: 0x2000000, + 0x8: 0x2100001, + 0x18: 0x0, + 0x28: 0x2000401, + 0x38: 0x2100400, + 0x48: 0x100000, + 0x58: 0x2000001, + 0x68: 0x2000000, + 0x78: 0x401, + 0x88: 0x100401, + 0x98: 0x2000400, + 0xa8: 0x2100000, + 0xb8: 0x100001, + 0xc8: 0x400, + 0xd8: 0x2100401, + 0xe8: 0x1, + 0xf8: 0x100400, + 0x100: 0x2000000, + 0x110: 0x100000, + 0x120: 0x2000401, + 0x130: 0x2100001, + 0x140: 0x100001, + 0x150: 0x2000400, + 0x160: 0x2100400, + 0x170: 0x100401, + 0x180: 0x401, + 0x190: 0x2100401, + 0x1a0: 0x100400, + 0x1b0: 0x1, + 0x1c0: 0x0, + 0x1d0: 0x2100000, + 0x1e0: 0x2000001, + 0x1f0: 0x400, + 0x108: 0x100400, + 0x118: 0x2000401, + 0x128: 0x2100001, + 0x138: 0x1, + 0x148: 0x2000000, + 0x158: 0x100000, + 0x168: 0x401, + 0x178: 0x2100400, + 0x188: 0x2000001, + 0x198: 0x2100000, + 0x1a8: 0x0, + 0x1b8: 0x2100401, + 0x1c8: 0x100401, + 0x1d8: 0x400, + 0x1e8: 0x2000400, + 0x1f8: 0x100001 + }, + { + 0x0: 0x8000820, + 0x1: 0x20000, + 0x2: 0x8000000, + 0x3: 0x20, + 0x4: 0x20020, + 0x5: 0x8020820, + 0x6: 0x8020800, + 0x7: 0x800, + 0x8: 0x8020000, + 0x9: 0x8000800, + 0xa: 0x20800, + 0xb: 0x8020020, + 0xc: 0x820, + 0xd: 0x0, + 0xe: 0x8000020, + 0xf: 0x20820, + 0x80000000: 0x800, + 0x80000001: 0x8020820, + 0x80000002: 0x8000820, + 0x80000003: 0x8000000, + 0x80000004: 0x8020000, + 0x80000005: 0x20800, + 0x80000006: 0x20820, + 0x80000007: 0x20, + 0x80000008: 0x8000020, + 0x80000009: 0x820, + 0x8000000a: 0x20020, + 0x8000000b: 0x8020800, + 0x8000000c: 0x0, + 0x8000000d: 0x8020020, + 0x8000000e: 0x8000800, + 0x8000000f: 0x20000, + 0x10: 0x20820, + 0x11: 0x8020800, + 0x12: 0x20, + 0x13: 0x800, + 0x14: 0x8000800, + 0x15: 0x8000020, + 0x16: 0x8020020, + 0x17: 0x20000, + 0x18: 0x0, + 0x19: 0x20020, + 0x1a: 0x8020000, + 0x1b: 0x8000820, + 0x1c: 0x8020820, + 0x1d: 0x20800, + 0x1e: 0x820, + 0x1f: 0x8000000, + 0x80000010: 0x20000, + 0x80000011: 0x800, + 0x80000012: 0x8020020, + 0x80000013: 0x20820, + 0x80000014: 0x20, + 0x80000015: 0x8020000, + 0x80000016: 0x8000000, + 0x80000017: 0x8000820, + 0x80000018: 0x8020820, + 0x80000019: 0x8000020, + 0x8000001a: 0x8000800, + 0x8000001b: 0x0, + 0x8000001c: 0x20800, + 0x8000001d: 0x820, + 0x8000001e: 0x20020, + 0x8000001f: 0x8020800 + } + ]; + + // Masks that select the SBOX input + var SBOX_MASK = [ + 0xf8000001, 0x1f800000, 0x01f80000, 0x001f8000, + 0x0001f800, 0x00001f80, 0x000001f8, 0x8000001f + ]; + + /** + * DES block cipher algorithm. + */ + var DES = C_algo.DES = BlockCipher.extend({ + _doReset: function () { + // Shortcuts + var key = this._key; + var keyWords = key.words; + + // Select 56 bits according to PC1 + var keyBits = []; + for (var i = 0; i < 56; i++) { + var keyBitPos = PC1[i] - 1; + keyBits[i] = (keyWords[keyBitPos >>> 5] >>> (31 - keyBitPos % 32)) & 1; + } + + // Assemble 16 subkeys + var subKeys = this._subKeys = []; + for (var nSubKey = 0; nSubKey < 16; nSubKey++) { + // Create subkey + var subKey = subKeys[nSubKey] = []; + + // Shortcut + var bitShift = BIT_SHIFTS[nSubKey]; + + // Select 48 bits according to PC2 + for (var i = 0; i < 24; i++) { + // Select from the left 28 key bits + subKey[(i / 6) | 0] |= keyBits[((PC2[i] - 1) + bitShift) % 28] << (31 - i % 6); + + // Select from the right 28 key bits + subKey[4 + ((i / 6) | 0)] |= keyBits[28 + (((PC2[i + 24] - 1) + bitShift) % 28)] << (31 - i % 6); + } + + // Since each subkey is applied to an expanded 32-bit input, + // the subkey can be broken into 8 values scaled to 32-bits, + // which allows the key to be used without expansion + subKey[0] = (subKey[0] << 1) | (subKey[0] >>> 31); + for (var i = 1; i < 7; i++) { + subKey[i] = subKey[i] >>> ((i - 1) * 4 + 3); + } + subKey[7] = (subKey[7] << 5) | (subKey[7] >>> 27); + } + + // Compute inverse subkeys + var invSubKeys = this._invSubKeys = []; + for (var i = 0; i < 16; i++) { + invSubKeys[i] = subKeys[15 - i]; + } + }, + + encryptBlock: function (M, offset) { + this._doCryptBlock(M, offset, this._subKeys); + }, + + decryptBlock: function (M, offset) { + this._doCryptBlock(M, offset, this._invSubKeys); + }, + + _doCryptBlock: function (M, offset, subKeys) { + // Get input + this._lBlock = M[offset]; + this._rBlock = M[offset + 1]; + + // Initial permutation + exchangeLR.call(this, 4, 0x0f0f0f0f); + exchangeLR.call(this, 16, 0x0000ffff); + exchangeRL.call(this, 2, 0x33333333); + exchangeRL.call(this, 8, 0x00ff00ff); + exchangeLR.call(this, 1, 0x55555555); + + // Rounds + for (var round = 0; round < 16; round++) { + // Shortcuts + var subKey = subKeys[round]; + var lBlock = this._lBlock; + var rBlock = this._rBlock; + + // Feistel function + var f = 0; + for (var i = 0; i < 8; i++) { + f |= SBOX_P[i][((rBlock ^ subKey[i]) & SBOX_MASK[i]) >>> 0]; + } + this._lBlock = rBlock; + this._rBlock = lBlock ^ f; + } + + // Undo swap from last round + var t = this._lBlock; + this._lBlock = this._rBlock; + this._rBlock = t; + + // Final permutation + exchangeLR.call(this, 1, 0x55555555); + exchangeRL.call(this, 8, 0x00ff00ff); + exchangeRL.call(this, 2, 0x33333333); + exchangeLR.call(this, 16, 0x0000ffff); + exchangeLR.call(this, 4, 0x0f0f0f0f); + + // Set output + M[offset] = this._lBlock; + M[offset + 1] = this._rBlock; + }, + + keySize: 64/32, + + ivSize: 64/32, + + blockSize: 64/32 + }); + + // Swap bits across the left and right words + function exchangeLR(offset, mask) { + var t = ((this._lBlock >>> offset) ^ this._rBlock) & mask; + this._rBlock ^= t; + this._lBlock ^= t << offset; + } + + function exchangeRL(offset, mask) { + var t = ((this._rBlock >>> offset) ^ this._lBlock) & mask; + this._lBlock ^= t; + this._rBlock ^= t << offset; + } + + /** + * Shortcut functions to the cipher's object interface. + * + * @example + * + * var ciphertext = CryptoJS.DES.encrypt(message, key, cfg); + * var plaintext = CryptoJS.DES.decrypt(ciphertext, key, cfg); + */ + C.DES = BlockCipher._createHelper(DES); + + /** + * Triple-DES block cipher algorithm. + */ + var TripleDES = C_algo.TripleDES = BlockCipher.extend({ + _doReset: function () { + // Shortcuts + var key = this._key; + var keyWords = key.words; + // Make sure the key length is valid (64, 128 or >= 192 bit) + if (keyWords.length !== 2 && keyWords.length !== 4 && keyWords.length < 6) { + throw new Error('Invalid key length - 3DES requires the key length to be 64, 128, 192 or >192.'); + } + + // Extend the key according to the keying options defined in 3DES standard + var key1 = keyWords.slice(0, 2); + var key2 = keyWords.length < 4 ? keyWords.slice(0, 2) : keyWords.slice(2, 4); + var key3 = keyWords.length < 6 ? keyWords.slice(0, 2) : keyWords.slice(4, 6); + + // Create DES instances + this._des1 = DES.createEncryptor(WordArray.create(key1)); + this._des2 = DES.createEncryptor(WordArray.create(key2)); + this._des3 = DES.createEncryptor(WordArray.create(key3)); + }, + + encryptBlock: function (M, offset) { + this._des1.encryptBlock(M, offset); + this._des2.decryptBlock(M, offset); + this._des3.encryptBlock(M, offset); + }, + + decryptBlock: function (M, offset) { + this._des3.decryptBlock(M, offset); + this._des2.encryptBlock(M, offset); + this._des1.decryptBlock(M, offset); + }, + + keySize: 192/32, + + ivSize: 64/32, + + blockSize: 64/32 + }); + + /** + * Shortcut functions to the cipher's object interface. + * + * @example + * + * var ciphertext = CryptoJS.TripleDES.encrypt(message, key, cfg); + * var plaintext = CryptoJS.TripleDES.decrypt(ciphertext, key, cfg); + */ + C.TripleDES = BlockCipher._createHelper(TripleDES); + }()); + + + return CryptoJS.TripleDES; + +})); \ No newline at end of file diff --git a/node_modules/crypto-js/x64-core.js b/node_modules/crypto-js/x64-core.js new file mode 100644 index 0000000..57dcc14 --- /dev/null +++ b/node_modules/crypto-js/x64-core.js @@ -0,0 +1,304 @@ +;(function (root, factory) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require("./core")); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + (function (undefined) { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var Base = C_lib.Base; + var X32WordArray = C_lib.WordArray; + + /** + * x64 namespace. + */ + var C_x64 = C.x64 = {}; + + /** + * A 64-bit word. + */ + var X64Word = C_x64.Word = Base.extend({ + /** + * Initializes a newly created 64-bit word. + * + * @param {number} high The high 32 bits. + * @param {number} low The low 32 bits. + * + * @example + * + * var x64Word = CryptoJS.x64.Word.create(0x00010203, 0x04050607); + */ + init: function (high, low) { + this.high = high; + this.low = low; + } + + /** + * Bitwise NOTs this word. + * + * @return {X64Word} A new x64-Word object after negating. + * + * @example + * + * var negated = x64Word.not(); + */ + // not: function () { + // var high = ~this.high; + // var low = ~this.low; + + // return X64Word.create(high, low); + // }, + + /** + * Bitwise ANDs this word with the passed word. + * + * @param {X64Word} word The x64-Word to AND with this word. + * + * @return {X64Word} A new x64-Word object after ANDing. + * + * @example + * + * var anded = x64Word.and(anotherX64Word); + */ + // and: function (word) { + // var high = this.high & word.high; + // var low = this.low & word.low; + + // return X64Word.create(high, low); + // }, + + /** + * Bitwise ORs this word with the passed word. + * + * @param {X64Word} word The x64-Word to OR with this word. + * + * @return {X64Word} A new x64-Word object after ORing. + * + * @example + * + * var ored = x64Word.or(anotherX64Word); + */ + // or: function (word) { + // var high = this.high | word.high; + // var low = this.low | word.low; + + // return X64Word.create(high, low); + // }, + + /** + * Bitwise XORs this word with the passed word. + * + * @param {X64Word} word The x64-Word to XOR with this word. + * + * @return {X64Word} A new x64-Word object after XORing. + * + * @example + * + * var xored = x64Word.xor(anotherX64Word); + */ + // xor: function (word) { + // var high = this.high ^ word.high; + // var low = this.low ^ word.low; + + // return X64Word.create(high, low); + // }, + + /** + * Shifts this word n bits to the left. + * + * @param {number} n The number of bits to shift. + * + * @return {X64Word} A new x64-Word object after shifting. + * + * @example + * + * var shifted = x64Word.shiftL(25); + */ + // shiftL: function (n) { + // if (n < 32) { + // var high = (this.high << n) | (this.low >>> (32 - n)); + // var low = this.low << n; + // } else { + // var high = this.low << (n - 32); + // var low = 0; + // } + + // return X64Word.create(high, low); + // }, + + /** + * Shifts this word n bits to the right. + * + * @param {number} n The number of bits to shift. + * + * @return {X64Word} A new x64-Word object after shifting. + * + * @example + * + * var shifted = x64Word.shiftR(7); + */ + // shiftR: function (n) { + // if (n < 32) { + // var low = (this.low >>> n) | (this.high << (32 - n)); + // var high = this.high >>> n; + // } else { + // var low = this.high >>> (n - 32); + // var high = 0; + // } + + // return X64Word.create(high, low); + // }, + + /** + * Rotates this word n bits to the left. + * + * @param {number} n The number of bits to rotate. + * + * @return {X64Word} A new x64-Word object after rotating. + * + * @example + * + * var rotated = x64Word.rotL(25); + */ + // rotL: function (n) { + // return this.shiftL(n).or(this.shiftR(64 - n)); + // }, + + /** + * Rotates this word n bits to the right. + * + * @param {number} n The number of bits to rotate. + * + * @return {X64Word} A new x64-Word object after rotating. + * + * @example + * + * var rotated = x64Word.rotR(7); + */ + // rotR: function (n) { + // return this.shiftR(n).or(this.shiftL(64 - n)); + // }, + + /** + * Adds this word with the passed word. + * + * @param {X64Word} word The x64-Word to add with this word. + * + * @return {X64Word} A new x64-Word object after adding. + * + * @example + * + * var added = x64Word.add(anotherX64Word); + */ + // add: function (word) { + // var low = (this.low + word.low) | 0; + // var carry = (low >>> 0) < (this.low >>> 0) ? 1 : 0; + // var high = (this.high + word.high + carry) | 0; + + // return X64Word.create(high, low); + // } + }); + + /** + * An array of 64-bit words. + * + * @property {Array} words The array of CryptoJS.x64.Word objects. + * @property {number} sigBytes The number of significant bytes in this word array. + */ + var X64WordArray = C_x64.WordArray = Base.extend({ + /** + * Initializes a newly created word array. + * + * @param {Array} words (Optional) An array of CryptoJS.x64.Word objects. + * @param {number} sigBytes (Optional) The number of significant bytes in the words. + * + * @example + * + * var wordArray = CryptoJS.x64.WordArray.create(); + * + * var wordArray = CryptoJS.x64.WordArray.create([ + * CryptoJS.x64.Word.create(0x00010203, 0x04050607), + * CryptoJS.x64.Word.create(0x18191a1b, 0x1c1d1e1f) + * ]); + * + * var wordArray = CryptoJS.x64.WordArray.create([ + * CryptoJS.x64.Word.create(0x00010203, 0x04050607), + * CryptoJS.x64.Word.create(0x18191a1b, 0x1c1d1e1f) + * ], 10); + */ + init: function (words, sigBytes) { + words = this.words = words || []; + + if (sigBytes != undefined) { + this.sigBytes = sigBytes; + } else { + this.sigBytes = words.length * 8; + } + }, + + /** + * Converts this 64-bit word array to a 32-bit word array. + * + * @return {CryptoJS.lib.WordArray} This word array's data as a 32-bit word array. + * + * @example + * + * var x32WordArray = x64WordArray.toX32(); + */ + toX32: function () { + // Shortcuts + var x64Words = this.words; + var x64WordsLength = x64Words.length; + + // Convert + var x32Words = []; + for (var i = 0; i < x64WordsLength; i++) { + var x64Word = x64Words[i]; + x32Words.push(x64Word.high); + x32Words.push(x64Word.low); + } + + return X32WordArray.create(x32Words, this.sigBytes); + }, + + /** + * Creates a copy of this word array. + * + * @return {X64WordArray} The clone. + * + * @example + * + * var clone = x64WordArray.clone(); + */ + clone: function () { + var clone = Base.clone.call(this); + + // Clone "words" array + var words = clone.words = this.words.slice(0); + + // Clone each X64Word object + var wordsLength = words.length; + for (var i = 0; i < wordsLength; i++) { + words[i] = words[i].clone(); + } + + return clone; + } + }); + }()); + + + return CryptoJS; + +})); \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..aba3431 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,21 @@ +{ + "name": "checkbox", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "checkbox", + "version": "1.0.0", + "dependencies": { + "crypto-js": "^4.2.0" + } + }, + "node_modules/crypto-js": { + "version": "4.2.0", + "resolved": "https://registry.npmmirror.com/crypto-js/-/crypto-js-4.2.0.tgz", + "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==", + "license": "MIT" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..1eaf59f --- /dev/null +++ b/package.json @@ -0,0 +1,18 @@ +{ + "id": "p-checkbox", + "name": "checkbox", + "version": "1.0.0", + "description": "checkbox", + "keywords": [ + "checkbox" + ], + "dcloudext": { + "category": [ + "前端组件", + "通用组件" + ] + }, + "dependencies": { + "crypto-js": "^4.2.0" + } +} diff --git a/pages.json b/pages.json new file mode 100644 index 0000000..91a828c --- /dev/null +++ b/pages.json @@ -0,0 +1,300 @@ +{ + "pages": [ + { + "path" : "pages/login/login", + "style" : + { + "navigationBarTitleText" : "", + "enablePullDownRefresh" : false, + "backgroundColor": "#ffffff", + "navigationStyle": "custom", + "disableSwipeBack": true + } + }, + { + "path" : "pages/ssoLogin/ssoLogin", + "style" : + { + "navigationBarTitleText" : "", + "enablePullDownRefresh" : false, + "backgroundColor": "#ffffff", + "navigationStyle": "custom", + "disableSwipeBack": true + } + }, + { + "path": "pages/dashboard/dashboard", + "style": { + "navigationBarTitleText": "", + "enablePullDownRefresh" : false, + "backgroundColor": "#ffffff", + "navigationStyle": "custom", + "disableSwipeBack": true + } + }, + { + "path": "pages/findPlayer/findPlayer", + "style": { + "navigationBarTitleText": "", + "enablePullDownRefresh" : false, + "backgroundColor": "#ffffff", + "navigationStyle": "custom", + "disableSwipeBack": true + } + }, + { + "path" : "pages/setting/setting", + "style" : + { + "navigationBarTitleText": "", + "enablePullDownRefresh" : false, + "backgroundColor": "#ffffff", + "navigationStyle": "custom", + "disableSwipeBack": true + } + }, + + { + "path" : "booking/bookingRecord/bookingRecord", + "style" : + { + "navigationBarTitleText" : "", + "enablePullDownRefresh" : true, + "app-plus": { + "pullToRefresh": { + "color": "#C39A4B" + } + }, + "navigationStyle": "custom", + "disableSwipeBack": true + } + }, + { + "path" : "booking/newBooking/newBooking", + "style" : + { + "navigationBarTitleText" : "", + "enablePullDownRefresh" : false, + "navigationStyle": "custom", + "disableSwipeBack": true + } + }, + { + "path" : "booking/bookingConfirm/bookingConfirm", + "style" : + { + "navigationBarTitleText" : "", + "enablePullDownRefresh" : false, + "navigationStyle": "custom", + "disableSwipeBack": true + } + }, + { + "path" : "booking/multipleDate/multipleDate", + "style" : + { + "navigationBarTitleText" : "", + "enablePullDownRefresh" : false, + "navigationStyle": "custom", + "disableSwipeBack": true + } + }, + { + "path" : "booking/bookingDetail/bookingDetail", + "style" : + { + "navigationBarTitleText" : "", + "enablePullDownRefresh" : false, + "navigationStyle": "custom", + "disableSwipeBack": true + } + }, + { + "path" : "booking/submitBooking/submitBooking", + "style" : + { + "navigationBarTitleText" : "", + "enablePullDownRefresh" : false, + "navigationStyle": "custom", + "disableSwipeBack": true + } + }, + { + "path" : "booking/newWaitlist/newWaitlist", + "style" : + { + "navigationBarTitleText" : "", + "enablePullDownRefresh" : false, + "navigationStyle": "custom", + "disableSwipeBack": true + } + }, + { + "path" : "booking/bookingGroup/bookingGroup", + "style" : + { + "navigationBarTitleText" : "", + "enablePullDownRefresh" : true, + "navigationStyle": "custom", + "disableSwipeBack": true + } + }, + + { + "path" : "salessupport/todoList/todoList", + "style": { + "navigationBarTitleText": "", + "enablePullDownRefresh" : false, + "backgroundColor": "#ffffff", + "navigationStyle": "custom", + "disableSwipeBack": true + } + }, + + { + "path" : "pages/azureLogin/azureLogin", + "style" : + { + "navigationBarTitleText" : "" + } + }, + { + "path" : "pages/azureLogout/azureLogout", + "style" : + { + "navigationBarTitleText" : "" + } + }, + { + "path" : "pages/idpLogin/idpLogin", + "style" : + { + "navigationBarTitleText" : "" + } + }, + { + "path" : "pages/samlLogin/samlLogin", + "style" : + { + "navigationBarTitleText" : "" + } + }, + { + "path" : "pages/regionRestrict/regionRestrict", + "style" : + { + "navigationBarTitleText": "", + "enablePullDownRefresh" : false, + "backgroundColor": "#ffffff", + "navigationStyle": "custom", + "disableSwipeBack": true + } + }, + { + "path" : "pages/disableApp/disableApp", + "style" : + { + "navigationBarTitleText": "", + "enablePullDownRefresh" : false, + "backgroundColor": "#ffffff", + "navigationStyle": "custom", + "disableSwipeBack": true + } + }, + { + "path": "pages/approval/approval", + "style": { + "navigationBarTitleText": "", + "enablePullDownRefresh" : false, + "backgroundColor": "#ffffff", + "navigationStyle": "custom", + "disableSwipeBack": true + } + }, + { + "path" : "pages/roomCount/roomCount", + "style" : + { + "navigationBarTitleText": "", + "enablePullDownRefresh" : false, + "backgroundColor": "#ffffff", + "navigationStyle": "custom", + "disableSwipeBack": true + } + }, + { + "path" : "pages/playerDetail/playerDetail", + "style" : + { + "navigationBarTitleText": "", + "enablePullDownRefresh" : false, + "backgroundColor": "#ffffff", + "navigationStyle": "custom", + "disableSwipeBack": true + } + }, + { + "path" : "pages/notification/notification", + "style" : + { + "navigationBarTitleText": "", + "enablePullDownRefresh" : false, + "backgroundColor": "#ffffff", + "navigationStyle": "custom", + "disableSwipeBack": true + } + } + ], + "globalStyle": { + "pageOrientation": "portrait", + "navigationBarTextStyle": "black", + "navigationBarTitleText": "Mobile CRM", + "navigationBarBackgroundColor": "#C39A4B", + "backgroundColor": "#F8F8F8" + }, + "tabBar": { + "color": "#000000", + "selectedColor": "#C39A4B", + "borderStyle": "#7d7d83", + "backgroundColor": "#ffffff", + "list": [ + { + "pagePath": "pages/dashboard/dashboard", + "iconPath": "static/images/ico_home.png", + "selectedIconPath": "static/images/ico_home_active.png", + "text": "%dashboard.title%", + "visible":false + }, + { + "pagePath": "salessupport/todoList/todoList", + "iconPath": "static/images/ico_todo.png", + "selectedIconPath": "static/images/ico_todo_active.png", + "text": "%todo.title%", + "visible":false + }, + { + "pagePath": "pages/findPlayer/findPlayer", + "iconPath": "static/images/ico_hotel.png", + "selectedIconPath": "static/images/ico_hotel_active.png", + "text": "%hotel.title%", + "visible":false + }, + // approvalRouting + // { + // "pagePath": "pages/approval/approval", + // "iconPath": "/static/images/task.png", + // "selectedIconPath": "/static/images/task_active.png", + // "text": "%approval.title%", + // "visible":true + // }, + { + "pagePath": "pages/setting/setting", + "iconPath": "static/images/ico_set.png", + "selectedIconPath": "static/images/ico_set_active.png", + "text": "%setting.title%", + "visible":true + } + ] + }, + "uniIdRouter": {} +} \ No newline at end of file diff --git a/pages/approval/approval.vue b/pages/approval/approval.vue new file mode 100644 index 0000000..0960368 --- /dev/null +++ b/pages/approval/approval.vue @@ -0,0 +1,597 @@ + + + + \ No newline at end of file diff --git a/pages/azureLogin/azureLogin.vue b/pages/azureLogin/azureLogin.vue new file mode 100644 index 0000000..70a347e --- /dev/null +++ b/pages/azureLogin/azureLogin.vue @@ -0,0 +1,81 @@ + + + + diff --git a/pages/azureLogout/azureLogout.vue b/pages/azureLogout/azureLogout.vue new file mode 100644 index 0000000..5fe1690 --- /dev/null +++ b/pages/azureLogout/azureLogout.vue @@ -0,0 +1,84 @@ + + + + diff --git a/pages/dashboard/dashboard.vue b/pages/dashboard/dashboard.vue new file mode 100644 index 0000000..998a6da --- /dev/null +++ b/pages/dashboard/dashboard.vue @@ -0,0 +1,311 @@ + + + + + \ No newline at end of file diff --git a/pages/disableApp/disableApp.vue b/pages/disableApp/disableApp.vue new file mode 100644 index 0000000..3f2c3da --- /dev/null +++ b/pages/disableApp/disableApp.vue @@ -0,0 +1,48 @@ + + + + + diff --git a/pages/findPlayer/findPlayer.vue b/pages/findPlayer/findPlayer.vue new file mode 100644 index 0000000..fa3cd08 --- /dev/null +++ b/pages/findPlayer/findPlayer.vue @@ -0,0 +1,235 @@ + + + + + diff --git a/pages/idpLogin/idpLogin.vue b/pages/idpLogin/idpLogin.vue new file mode 100644 index 0000000..f4245ad --- /dev/null +++ b/pages/idpLogin/idpLogin.vue @@ -0,0 +1,112 @@ + + + + + + diff --git a/pages/login/login.vue b/pages/login/login.vue new file mode 100644 index 0000000..20d83ff --- /dev/null +++ b/pages/login/login.vue @@ -0,0 +1,408 @@ + + + + + diff --git a/pages/notification/notification.vue b/pages/notification/notification.vue new file mode 100644 index 0000000..4a5f04f --- /dev/null +++ b/pages/notification/notification.vue @@ -0,0 +1,235 @@ + + + + + diff --git a/pages/playerDetail/playerDetail.vue b/pages/playerDetail/playerDetail.vue new file mode 100644 index 0000000..7381585 --- /dev/null +++ b/pages/playerDetail/playerDetail.vue @@ -0,0 +1,986 @@ + + + + + \ No newline at end of file diff --git a/pages/regionRestrict/regionRestrict.vue b/pages/regionRestrict/regionRestrict.vue new file mode 100644 index 0000000..68aa318 --- /dev/null +++ b/pages/regionRestrict/regionRestrict.vue @@ -0,0 +1,96 @@ + + + + + diff --git a/pages/roomCount/roomCount.vue b/pages/roomCount/roomCount.vue new file mode 100644 index 0000000..ca9884e --- /dev/null +++ b/pages/roomCount/roomCount.vue @@ -0,0 +1,75 @@ + + + + + \ No newline at end of file diff --git a/pages/samlLogin/samlLogin.vue b/pages/samlLogin/samlLogin.vue new file mode 100644 index 0000000..66725f2 --- /dev/null +++ b/pages/samlLogin/samlLogin.vue @@ -0,0 +1,92 @@ + + + + + + diff --git a/pages/setting/setting.vue b/pages/setting/setting.vue new file mode 100644 index 0000000..525d8d4 --- /dev/null +++ b/pages/setting/setting.vue @@ -0,0 +1,454 @@ + + + + + diff --git a/pages/ssoLogin/ssoLogin.vue b/pages/ssoLogin/ssoLogin.vue new file mode 100644 index 0000000..84aecb4 --- /dev/null +++ b/pages/ssoLogin/ssoLogin.vue @@ -0,0 +1,150 @@ + + + + + diff --git a/salessupport/todoList/todoList.vue b/salessupport/todoList/todoList.vue new file mode 100644 index 0000000..4ef42e3 --- /dev/null +++ b/salessupport/todoList/todoList.vue @@ -0,0 +1,1646 @@ + + + + + \ No newline at end of file diff --git a/static/css/custom.scss b/static/css/custom.scss new file mode 100644 index 0000000..936191d --- /dev/null +++ b/static/css/custom.scss @@ -0,0 +1,448 @@ +page{ + background-color: $page-color-light; + font-size:$font-base; + font-family: "Inter-Regular"; + font-weight:600; +} +.hz-page{ + padding-bottom:calc(var(--window-bottom) + 20px); +} +.hz-bg-white{ + background-color: $page-color-light; +} +.hz-bg-primary{ + background-color: $base-color; +} +.hz-bg-primary:active{ + background-color: $base-color-active; +} +.hz-bg-disPrimary{ + background-color: $base-color-disActive; +} +.hz-bg-light{ + background-color: $base-color-light; +} +.hz-font-color-black{ + color: $font-color-black; +} +.hz-font-color-dark{ + color: $font-color-dark; +} +.hz-spacing{ + margin-left:$page-col-spacing; + margin-right:$page-col-spacing; +} +.hz-split{ + border-top:1rpx solid #dddddd; + margin-top:6px; + margin-bottom:6px; +} +.hz-split-primary{ + border-top:1rpx solid $base-color; + margin-top:6px; + margin-bottom:6px; +} +.text-truncate { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } +.hz-row-spacing{ + margin-top:$page-row-spacing; +} +.hz-font-min{ + font-size:$font-min; +} +.hz-font-12px{ + font-size:$font-12px; +} +.hz-font-sm{ + font-size:$font-sm; +} +.hz-font-base{ + font-size:$font-base; +} +.hz-font-md{ + font-size:$font-md; +} +.hz-font-lg{ + font-size:$font-lg; +} +.hz-font-xl{ + font-size:$font-xl; +} +.hz-font-color-danger{ + color:$font-color-highlight1; +} +.hz-font-color-primary{ + color:$font-color-highlight2; +} +.hz-font-color-light{ + color:$base-color-light; +} +.hz-font-color-white{ + color:$font-color-white; +} +.hz-font-normal{ + font-family: "Inter-Regular"; +} +.hz-font-bold{ + font-family: "Inter-Medium"; +} +.hz-font-bolder{ + font-family: "Inter-Bold"; +} +.hz-text-left{ + text-align: left; +} +.hz-text-center{ + text-align: center; +} +.hz-text-right{ + text-align: right; +} +.hz-banner-bg{ + border-radius: 0 0 5% 5%; +} +.hz-card-profile{ + border-radius: 12px; + padding:18px; + background-color: $font-color-highlight2; + color:$font-color-white; +} +.hz-card-booking{ + border-radius: 12px; + padding:18px; + background-color: $page-color-greylight; + color:$font-color-black; +} +.hz-card-extend{ + border-radius: 12px; + padding:18px; + background-color: $base-color-light; + color:$font-color-black; +} +.hz-card-level{ + border-radius: 4px; + padding:0px 4px; + font-size:9px; + height:12px; + display: flex; + justify-content: center; + align-items: center; + background-color: $uni-color-error; + color:$font-color-white; +} +.hz-mr-t-30{ + margin-top:30rpx; +} +.hz-mr-b-30{ + margin-bottom:30rpx; +} +.hz-mr-t-20{ + margin-top:20rpx; +} +.hz-mr-b-20{ + margin-bottom:20rpx; +} +.hz-pd-16{ + padding:16rpx; +} +.hz-pd-30{ + padding:30rpx; +} +.hz-pd-l-30{ + padding-left:30rpx; +} +.hz-pd-r-30{ + padding-right:30rpx; +} +.hz-nav-btn{ + width:22px; + height:22px; +} +.hz-flex-row{ + display: flex; + flex-direction: row; +} +.hz-flex-col{ + display: flex; + flex-direction: column; +} +.hz-flex-vertical-mid{ + justify-content: center; + align-items: center; +} +.hz-btn-status{ + border-radius: 4px; + padding: 3px 2px; + font-size:20rpx; + color:#ffffff; + text-align:center; +} +.hz-status-duein{ + background-color: $font-color-spec; +} +.hz-status-reserved{ + background-color: $uni-color-primary; +} +.hz-status-cancel{ + background-color: $font-color-highlight2; +} +.hz-status-checkedin{ + background-color: $font-color-spec; +} +.hz-status-dueout{ + background-color: $font-color-spec; +} +.hz-status-pending{ + background-color: $uni-text-color-placeholder; +} +.hz-status-waitlist{ + background-color: $uni-color-error; +} +.hz-status-approval{ + background-color: $uni-color-error; +} +.hz-status-font-duein{ + color: $font-color-spec; +} +.hz-status-font-reserved{ + color: $uni-color-primary; +} +.hz-status-font-cancel{ + color: $font-color-highlight2; +} +.hz-status-font-approval{ + color: $uni-color-error; +} +.hz-status-font-checkedin{ + color: $font-color-spec; +} +.hz-status-font-dueout{ + color: $font-color-spec; +} +.hz-status-font-pending{ + color: $uni-text-color-placeholder; +} +.hz-status-font-waitlist{ + color: $uni-color-error; +} +.hz-status-font-pendingApproval{ + color: #E8D9BA +} +.hz-btn-extend{ + border-radius: 4px; + padding: 3px 2px; + background-color: $base-color; + color:#ffffff; + text-align:center; + font-size: 20rpx; + width:30%; +} +.hz-btn-group{ + border-radius: 4px; + padding: 3px 2px; + background-color: $font-color-spec; + color:#ffffff; + text-align:center; + font-size: 20rpx; + width:30%; +} +.hz-btn-sharer{ + border-radius: 4px; + padding: 3px 2px; + background-color: #4bc397; + color:#ffffff; + text-align:center; + font-size: 20rpx; + width:30%; +} +.hz-btn-sm{ + border-radius: 6rpx; + padding: 10rpx 20rpx; + background-color: $base-color; + color:#ffffff; + text-align:center; + font-size: $font-sm; +} +.hz-date-title{ + border-radius: 12rpx; + padding: 10rpx 20rpx; + background-color: $base-color; + font-size: $font-lg; + color:$font-color-white; + font-weight:bold; +} +.hz-date-des { + font-size: $font-12px; + color: $font-color-base; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + display: block; +} +.hz-btn{ + background-color: $base-color; + width:100%; + margin-top:6px; + height:44px; + line-height:44px; + border-radius:22px; +} +.hz-btn-line{ + background-color: #ffffff; + border:1px solid $base-color; + width:100%; + color:$base-color; + margin-top:6px; + height:44px; + line-height:44px; + border-radius:22px; +} +.hz-btn:active{ + background-color: $base-color-active; +} +.hz-btn-light{ + background-color: $base-color-light; + width:100%; + margin-top:6px; + height:44px; + line-height:44px; + border-radius:22px; +} +.hz-btn-danger{ + background-color: $base-color-danger; + width:100%; + margin-top:6px; + height:44px; + line-height:44px; + border-radius:22px; +} +.hz-circle{ + width: 20px; + height: 20px; + background-color: $base-color; + border-radius: 50%; +} +.hz-placeholder{ + color:#666; + font-size:$font-md; +} +.hz-disabled{ + opacity: 0.4; + background-color: #dddddd; +} +.hz-btn-leftRight { + background-color: #ffffff; + border-top:1rpx solid #f4f4f4; + width:100%; + .hz-btn-left { + width: 50%; + text-align: center; + margin-top:12rpx; + height:44px; + line-height:44px; + border-top-left-radius:22px; + border-bottom-left-radius:22px; + } + .hz-btn-right { + width: 50%; + text-align: center; + margin-top:12rpx; + height:44px; + line-height:44px; + border-top-right-radius:22px; + border-bottom-right-radius:22px; + } +} +.hz-card-waitlist{ + border-radius: 12px; + padding:18px; + background-color:$base-color-notice; + color:$font-color-black; +} +.hz-card-approval{ + border-radius: 12px; + padding:18px; + background-color:$base-color-approval; + color:$font-color-black; +} +.book { + background-color: #ffffff; + border-top:1rpx solid #f4f4f4; + width:100%; +} +/* textarea */ +.uni-textarea{ + width:100%; + background:#FFF; +} +.uni-textarea textarea{ + width:96%; + padding:18rpx 2%; + line-height:1.6; + font-size:28rpx; + height:150rpx; +} +.scroll-list { + @include flex(column); + + &__goods-item { + margin-right: 20px; + + &__image { + width: 60px; + height: 60px; + border-radius: 4px; + } + + &__text { + color: #f56c6c; + text-align: center; + font-size: 12px; + margin-top: 5px; + } + } + + &__show-more { + background-color: #fff0f0; + border-radius: 3px; + padding: 3px 6px; + @include flex(column); + align-items: center; + + &__text { + font-size: 12px; + width: 12px; + color: #f56c6c; + line-height: 16px; + } + } + + &__line { + @include flex; + margin-top: 10px; + text-align:center; + + &__item { + margin-right: 15px; + + &__image { + width: 60px; + height: 60px; + } + + &__text { + margin-top: 5px; + color: $u-content-color; + font-size: 12px; + text-align: center; + } + + &--no-margin-right { + margin-right: 0; + } + } + } +} \ No newline at end of file diff --git a/static/css/font_3379718_ey1vmrktwg7.ttf b/static/css/font_3379718_ey1vmrktwg7.ttf new file mode 100644 index 0000000000000000000000000000000000000000..2176c611c1f1104ab7abc3fd8a80b4177138f147 GIT binary patch literal 35152 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¨l=0RllT1K65(e?i|Z>< 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
eA*oHF==1$> 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ë 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 Z4)6Z6Xp%P-{R7NjGO@orpUJK5{{f-JOD+Ha literal 0 HcmV?d00001 diff --git a/static/fonts/Inter-ExtraLight.otf b/static/fonts/Inter-ExtraLight.otf new file mode 100644 index 0000000000000000000000000000000000000000..6dc068dc90b394ad7d20e4e3156ec9d23fcc2a17 GIT binary patch literal 264196 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%0DaHsxqnqRlTbESLIY4Q&m;fST(F_RMn|fXI4$C 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 literal 0 HcmV?d00001 diff --git a/static/fonts/Inter-Light.otf b/static/fonts/Inter-Light.otf new file mode 100644 index 0000000000000000000000000000000000000000..2a83ae168def2d07982cd5f15e40bf2711ab0ea5 GIT binary patch literal 265000 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

-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 J>wTt%eg>tMGE@Kn literal 0 HcmV?d00001 diff --git a/static/fonts/font.css b/static/fonts/font.css new file mode 100644 index 0000000..8fb4f00 --- /dev/null +++ b/static/fonts/font.css @@ -0,0 +1,30 @@ +@font-face { + font-family: "Inter-Bold"; + src: url('Inter-ExtraBold.otf'); + font-weight: 800; + font-style: normal; +} +@font-face { + font-family: "Inter-Medium"; + src: url('Inter-Medium.otf'); + font-weight: normal; + font-style: normal; +} +@font-face { + font-family: "Inter-Regular"; + src: url('Inter-Regular.otf'); + font-weight: normal; + font-style: normal; +} +@font-face { + font-family: "Inter-Light"; + src: url('Inter-Light.otf'); + font-weight: normal; + font-style: normal; +} +@font-face { + font-family: "Inter-ExtraLight"; + src: url('Inter-ExtraLight.otf'); + font-weight: normal; + font-style: normal; +} \ No newline at end of file diff --git a/static/fonts/font_3379718_ey1vmrktwg7.ttf b/static/fonts/font_3379718_ey1vmrktwg7.ttf new file mode 100644 index 0000000000000000000000000000000000000000..2176c611c1f1104ab7abc3fd8a80b4177138f147 GIT binary patch literal 35152 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¨l=0RllT1K65(e?i|Z>< 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 T>Mu|wJc1w_Tal`X?s5MHjt>7% literal 0 HcmV?d00001 diff --git a/static/images/arrow_next.png b/static/images/arrow_next.png new file mode 100644 index 0000000000000000000000000000000000000000..e8a715c3d8f2a586a208fc49226ef8c56c59576d GIT binary patch literal 2722 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 literal 0 HcmV?d00001 diff --git a/static/images/arrow_previous.png b/static/images/arrow_previous.png new file mode 100644 index 0000000000000000000000000000000000000000..00f0d5f69eb2a971bb015613b88a943d020ba8f6 GIT binary patch literal 5008 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 KMNUMnLSTaEH#^P% literal 0 HcmV?d00001 diff --git a/static/images/close.png b/static/images/close.png new file mode 100644 index 0000000000000000000000000000000000000000..ce813df2c0ebe66e2074525360a1647cad5278cc GIT binary patch literal 746 zcmVGq18l4j3lmiz zph{f-ujgLeI%nVcbJ|K*#dqh6{e8cmeb;j?qdWfB3f%MrwlmPqK;#Itmr&#YI=c^t z!{C7pYS`-y-uAi!<;=!>a%=0=Bl+Xk-|g+)=OLlJ0)Qt)pAk$Sf5JXh0sKaG_K!$C zR*P&uM50n)bF+V+3iupa(fd>qC48PqZ!RSCLFK1X;Q099lmtDrA|#L~;1BFP;-j37 zo>=D`l}Z7$mva0+rNk2a3*^g-((s3)5BafY;}t-EBcbo&pQz`BVJ2eX!4V{YhL8|~ z`dktm@Zbs-Kw~ZmE_g825aNcb8QX-R|J4UfbXa+vp+X&Ssxw5kN?ngdlpYze@(MV-uSIf|U~D zH|kcYu{^N)c`B>|$TgpLI)WDWaBP)Kb*ws5g;k)uVa2m+d<<)+Yccf+Hh~hJ%4?qJ z3)k97vpPR40#0~b^V9J=&IO>$AX;E0e6gM{Z){>+iW`|I0Ux|cl2W3vKq!1_iADl- z;ZsV~7HA5eN}`rPEPM)yU;!?8Ziyg)0$#r{TY5;T@K+xO`s$wJzmr#B3BJtF0B?fD zN>mE$?7V!S*Yg;8laGiI-UKxgrk?MycIpmh`EkXjQeZOqc0xkDx$K_+-o%Ck*{?BY z8;h)OzF)Pk6hJ2_M|-4HE+LEM0nVo=vV4s>n=i86$CH;s5{u07*qoM6N<$g0yQ+djJ3c literal 0 HcmV?d00001 diff --git a/static/images/datanull.png b/static/images/datanull.png new file mode 100644 index 0000000000000000000000000000000000000000..8b287516ef006526bd41015143deaa9f66d0dffd GIT binary patch literal 17165 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 KiE1&U!2bcM2u4!? literal 0 HcmV?d00001 diff --git a/static/images/edit.png b/static/images/edit.png new file mode 100644 index 0000000000000000000000000000000000000000..c4a41cd75c9483ac941a34f3baf7a6b17a69bb8f GIT binary patch literal 1117 zcmV-j1fu(iP)gt3=O;r33)|ciO@|HN@7OxNRijT zGkK)U`2F{>j&;^uXYX^)UhAAQaQpxF`qtWaec$&#YoE3ETKjZtY3{$Nq<0CvfiK|( z*afyjGYi>5wwK{F*a!B5+u=<(6PBP^g-FEal1%?qhGU+E<6#j#A>BDU2Cj#47@D|E zh2ps)_S54RH0XqJ432;aTp_z?{RlODJ1FHaBypJvpNMhvSOxpT6VRYH#$nhOw%9^G z(6AOZ3O*4NN#+I=-f>t2_dtW882eyR$SEp4ppC~=ZUrXpyzq&b%zs{oF4oYn6&g&z zXw``5(wRraz|0gwXc!xqN*I?VP@8hF8j9sL=>%?r zX?W$H)QAkT8n0pNTBL{$pNLsR)fGXJir>!J&k{1gYJ6tdF-@O{*#x`@v*3!jPlq-M zp{y%>BIc68d6)%PgeIhg>QrwbJ`oE@M0aY6RQN>9p~n+goPK4;rcZ=EO-=n-u~S8; zbG=5yCt@)PoP=4(6d?!o5aJWDl;Fo<7Ag`UC$WY2L@X!p5txOFMaWT1AwChh*&b5h z3|1vVzG4aSiO@(KP|yrkEkgcc2=R$nMzAO&f!_ong~*{##1c+u-9V9wnnuES3@OAX zLQ|~!q-tW@WiAnN6iSFsgcd=erdX|54c$k6=?HRX_leLQ+g_F?!90g*Mnd}tVh4|( z+(K64)cu6?>=f*djsJ>}=hD(%(?%zXR+>ScogBZJ)jUEZLSjr1J&B$%m6WoY%PGZ8 z>8U(IW>~JYjdaecmouY?P_SBsXt&QEjlFV~!Du2Bw^kve)%h5mD|V%3FJ|qcF7jt>m@k zuNh76GiWX%%19XRwT_6kQjHId$Q>%${8sW8u(v@QQAH?F9wD|E`6@?kI%^*{=y$>m zR;v*C*~FpTz2hn84npmwYt#8Hc2wjMa+l0B`}Cq53C)JLz9)mIuYkVYbeh8>j}Vj1 zdyIQfmzww*yY2`fr0z-k0{$1``&0t9RqaY6^4;py*|M9-)Xmo9^UWA`DIuDDOq>1E z$Fw!N)UO`~TS@4Bh*d3^67sNMCdWw}wFakX3TSHAG;SxOrv$s6*b<`GyFZg!;h;6R zUcv38Dp8H1mduaHK|kT3NU)pZC)f@Wq8E$WM6gdzpt251RHLZ%zr9@0vz&4wt@e-* zwQ3VhizU6)RlV7GnuL17vM@sQ54SlCg!%=J?$AH58;KVL*ORm^?fKZL_yYg{|NqR2 jXRrVO00v1!K~w_()0-8m1$4H200000NkvXXu0mjf$$%0q literal 0 HcmV?d00001 diff --git a/static/images/edit_active.png b/static/images/edit_active.png new file mode 100644 index 0000000000000000000000000000000000000000..a30d19ad6290104a796918116efd4bee60fde275 GIT binary patch literal 1460 zcmV;l1xxygP)7%Q6oB6wr$TT-R0XwCQ3VGi{?Y>%TH8s)Pl@f&BB4;KREQ9-6H!FrkOP;NBZoqf z3XL6<76bx{P@%CmrAUNiQ_fz@ z1h5T&j&v+6OwZCi!-P4{>!J3T=jx{+3!7_9ItZ|-H$H5BT;Dowl%BGQo_F;O zleWe(or#=F;Bo(8JXUA9i0zHy6%=cS4s)ykA^RS^Zz&Wfbhz^2hr+sn5JSD;Si4KA~?Ed87)K}7P%|LVz z2spsA6HomTN^@xiAwAawLbZgxCumL%gSbk#Hu2fymo_w_sVk#669fU&I z&$Ck~Q!Il{FUol8kOW>Ys|L|Q*nk5&v!$ii(t5AeItN#?ie>e@ciF*pZ|desx6Q^m zZ%C^GnayVosQTRwqq zM>%kYsk$NPk7tYTR%=bO6%MDScIqz#2O-++8bgGmiCpPDx85v|3PSt^0y$quZRe?V z@op%Ly&}f^BuWVJ8wkWENJ{6be7paH(@RS>hVL~(* z_b38^c=`hZZ1mRM^7QcswnYIE$#X=4=3%yFrjXt-%bVX4ylnaN^JTOn7P}vJU z^E3-q40K17tz;|J@yIjQMg?$QHoql!M0J|?V_$GCE}bHU5H}oyWGj=zNKrsUT6W|$ z$T7R4qu1T-XxSlPgFqnSt77AGfY9vO@in&@ukdbqk~f{Z20#3X>yf6wAl<{o3yEy0 zzq~-35$(I7f;}Qi(KdenxRu4|*6gN7MH3jr4XEcy^Otyb>N6Q`B0Go7AKYtenXejT zEra#*^*@N;UnhiXD>fl3m%rRzF;LgI<#m>Ca^r~s{OOjxxdMa>u7Z%fAAMYPTXU2q`A>6ZkmU1ITa#t4~x8scA!Q}a32vI z6sUFy$0J{wJ+BLNIboOwS+7k>v`ND}iRip6U6J}aly?~72EVu*5NQz4maMBu-NIw? z2-jsn_&4Y6Oy9Bd)BN54FfVr=<+5-34*&rF|FR7(w*UYD21!IgR09CSE)&Fncs}j` O0000Gn-yCdGnTn%;Jw9|TjjmRFwQf| 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 \ No newline at end of file diff --git a/static/images/filter_active.png b/static/images/filter_active.png new file mode 100644 index 0000000000000000000000000000000000000000..9891e46513283f6448334b0095e0c589907c4a5d GIT binary patch literal 1496 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 TQ}q*r00000NkvXXu0mjfP&j#& literal 0 HcmV?d00001 diff --git a/static/images/find_player.png b/static/images/find_player.png new file mode 100644 index 0000000000000000000000000000000000000000..6b953b98da86cf346db9c7d80338c3ac82dad1ef GIT binary patch literal 2200 zcmV;J2xs?+P)Px-Qb|NXRCr$Pom+O?HV{Nf?@K4vx4n%x%ZRm%INPwlqa5uklLK3I3=L$5F6ztg{c8eYS%r{8~0zgz!l)&buB`ucsCg}w=|SMzlk z$Cs92XbJ!)(H~*bBn(Xea25VfeSn+xXbOa?0mv-;o|Yy+s1ks}!hZna>D#Yola~jqT;Kq~$%j>qx2wi!b;0KEP9@=xTHE(kTx?Uy-!`1AWUftV@d48mo6 zdHUn$cLH~Znm`Z0w1{)LgbH6T&SiX=7IhSYtcyl5YX}uVzz={W@|^_Oz@VREI<)}` zW z`~`-ZA)o;Oihj~43Lu~muoZ+n0Lal#k@t^^tG6FtE@JUT1~CNyQ1la8zp);m0=X6d zs0J<81(?zR2LO`&R}lTGf{-W;umEtBJFAKQ6#}Ui=m6YIRLuVsMZd-cSkgdo2M}-c zXcPdJ8%NjysLuXtO9Ko5JkI|_xl)|p?=}#fjihhf090uIa2?PA7={)LKp22wph#~; z9iRhH{(%x|09d9<+We1R9AfBSSpeooxF6ne%P>F|@h1T0+u09qYh&nNSpbAVVi=$f zfOQ0b{lq9~c^1%%K)@zz20*&N)d83-;_xO4lDRTqW*;^Y7lJwfCkKE8?xIED)d3El z`mM1L6lTn`8vRNw+o^po|22LLGzkh=hs z`w9C%0|4X#WcI1Feo7bP0swFU##8`VKVkIK6oK36r8Fg+wk67=sQ9c4T2u~z-bup( z0s2TdTjjqEI644ofdGztqILg!3we|PfCb^wpRDt0wAx<>nMw5y>+9R2-V03oFKTTTljW>{uT5`1XPgo_sy>cfN5qB z^X&j2bfY$@Q2c6Az+M>D96U-@aOXz0mJO4HmxL0I_q4oP=$^o!U@$NbRPW z1vn4hEH;>@kpYsnac;kKI`>t^q7L9Pc!rNdN~4Vaf3ful$L9)*0HD66zE`B6=u1tFM0pU6_$cwO(C%xH>6r7Ual?=1+Js9w$O?d2d=lZ;YG1Q1p=i7M zT8HA;k08$mfJuCZ4r-(OXnR%aifFqEgoyKGn+3EW{uKT4dw*troQgE`d@=PvatA;= zu|{4b(Vh{%Jr)@KE_wOgd67G!BE~E!0Ii4*N550#?;%DU)anAs06-eO>1fjB&RAD~ zqCb)No0-S)C+UnXkOTm&_)O2s--88kGI#4YxPYk*?f|I7H&PoL(c1mR=M@u2|LOt> z-mUBk0A!U*Z)y==e(Q%R^0W{_YY>JpbpxP9@u5M_6#Y;wP!s@kj%;Y8C0e}pky4tq z`nI-DXph>BTpU0V{pto<2g++dp#aR@A5H+IFJ;bZWFIUK2r2_$&^l7I14tIRijX;1 zdWa7!0A+_-8t<$Cz}8=>_>=$~&q~xlMmYemKvKms@<(propWQI$-6yf03<8Ac2rGd z>;QT1FZEMvxv}l@u1V|wAcbGW){m~fd0qNN!8ioKFvT_j0OtPcqd(Q+3o7=9>jBcL zq#@vJ03eG#hQ?S2CiQ+&t&=Maq)10<0HEkMSW#*bV~#Hke6E*42^XbIj;jX%i2hs= z5hJR0U+Icq>OPAQ8XZ>!z!{?-E(Q~>bOPgUivG|y9RR@nX{jSY8@Zm_OD>Qq6^Q3G zM!y~adFp2-(Nm~Y#}aKgoY=AcL2nO_2|CyT02^|<9XgeO9>*1P?=)xeFAP@lnEY5V|?CNAZ zp#uoh%dWy}>XdbcS_>HfdHGj;(u`UZJ=Fxlv^ogA0_Ncx&Qd}U55S2FKr3Af7@8Hl zR1nAjNHc(w7l2j>Ec>Y-00XlFU{RvrKHd;S1JGvx`Dsu!Gn10bHjzuWzY+YvZ~04UIr6maAK9RLCz?=Cz6;)kZo04$3c4?3!u%My%L z(@h8 \ No newline at end of file diff --git a/static/images/flight_line.svg b/static/images/flight_line.svg new file mode 100644 index 0000000..761872f --- /dev/null +++ b/static/images/flight_line.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/images/flight_line_2.svg b/static/images/flight_line_2.svg new file mode 100644 index 0000000..2c50c09 --- /dev/null +++ b/static/images/flight_line_2.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/images/ico_calendar.png b/static/images/ico_calendar.png new file mode 100644 index 0000000000000000000000000000000000000000..a041f4ec2669c9d4bd57c0e913829fe7041e8032 GIT binary patch literal 343 zcmV-d0jU0oP)Px$5lKWrR9HvtS5XdwAPj8}Mxx((jk#mY9b@hq`aKs8#s*UZ4%S9O+%ovXLi>1q zttrCJ3wMqWBmjA>3vuYj5YSjV4WO$OAeJEzGScnskk?O z72X{YCJpw%c@`nXfbIcy{d4x3@b#TJ3C?$_4;Yo2UjJIGy*_BSZrusj-)w&r11Yun z8;yvQb6>u*1~}UJ9}R@qAQ@oQ{kl&CYTgHe1i;B-%$W?}%NUr%GyiyEa?86r4Lfg> pk(mz?FMG-&N3+CO=;1UqfCtx2GcYmlwcr2%002ovPDHLkV1i4#i0uFX literal 0 HcmV?d00001 diff --git a/static/images/ico_calendar_grey.png b/static/images/ico_calendar_grey.png new file mode 100644 index 0000000000000000000000000000000000000000..6b2d79fb1fe11c081d5bedf0803708cfe4512f19 GIT binary patch literal 1723 zcmbVNeM}o=96lJCh+%_F37Rp^V^P?+-d9WMg^oZAQnCXARhf&)u6J+gh295u2Q4fz zWkAMoOZ-C!W<-r9#2Ke%MmJDlF=1QO&6z0MSRBGambszPxkYEx_e$F^GrxApUElZa zd7t0!`F(Yuq3*HFjE6E11j+Q(cpKp_YTfCp5hNw;nc4u{+^f}WGZ5syb=IANymTNJ zLDH^E{${h8+sX>6Y~w{W0BliNgJ=XPE01ct&daP0|cOG6c=w6vL7Z*6u*#7X}ULVvue0R>#f3 zof`|8rp6LPBoeVj7@MlM5R}X1B1oE`X&fSOqf;^YD6SX<2?j4P1YOchNmWpbkq@Zt zrW=FKE~}8WB&}k^BL!ndM0t&%Y^0?s1{8%PPHWf0G2@~@fH07OVj2)jC9zsaHB}>| z{tb2V^KAxTbU7|*V8!XCvw%0a2ciTwi2|E;{{2vL=>$!0=&El+!)N89VhKL&G>1UHy2Bio5@o6T!wP0 zCZd3x#T0cL6xNN%oBY3mMS%^fy39k#lFYXNLQ`5WG#NWue96KIRC!V(&*1C|%8`gUW2l~^ER z@z>H_M_`#Y5(1F)AJV-HGt{6N;dM~a0;BaG3W|X46IL%SD~Ki#%|*Ol?5C%&G{&3^UZ!E*(@ zbB(nh&6Hf+yD*fI`Rw+w@VRjC|cx0fA}U-wRVPK8{@ zPvjIL#Ti9?eD0yt$~|kQq#s+aZr+&r3gs(%IB!kwWNQ7pT;AnX*~MuWnmQIf?%DtR z(uH+%FPs_u<4k(a`hguy=t%gvnTz)v{Va0j{3!kN;8YpbtcACjAMXEfFf_h)!(M6YVDS2;?v!_iQ*I1@Rejw0d+}A(c@I_Y==l?$ CPD~^K literal 0 HcmV?d00001 diff --git a/static/images/ico_err.png b/static/images/ico_err.png new file mode 100644 index 0000000000000000000000000000000000000000..1e48d0d3f6b98fe2b67bbe05d8b03a592d37da83 GIT binary patch literal 1915 zcmV->2ZZ>EP)Px+HAzH4RCr$Poj;P*I1t87L`Jq%kE)%6Kmv0HjsiJ5IUI#E?2y1gW~+Ern~@Ri zPP?p!p2w0~QcL>OZYM+WY^kO1r|y>jNY5sv$HVFLc4->@eY0w&`)%F&d+$HKdjGz^ zIiLOC)b!dj4J}#3c0z~5m1-)1KyavlVn_fM!9RKKwFbWS7l2?EL-~htIg3uj+ zhtuir$D~P%t4|Fn-9tk+03J>!N{-xAF16#do!SLgoTsqkljK zIJ1IX0BrORsQhn}cSAuG026;`@mUF>0iZ(TXd|LtAP9hsepO@yZxb5;s&r0&izo(w zW&XP0*z^LM0GRvNrTo&G&0HV^fQ^2Y3`|eFz!LyaNB{HJucsI9-%s?Hj$hxtO~1Z> zpMHM&)Kw}}y8@l^cdhum%8b)s8>De7U&&SVy*mfFr&OQv?CnapeWp0KmEbKY#pS_g@PL zxZ*pb|9Sb6ZGWQ^w*f$O|I{HV0MPk0AxIUU>;VLT%({euiw8i>{<$H*A3Zf7$Pu67 zKVS%;uDW;u9{|YZ+Gv_Z5TqWG5afto+Z(0!$Ljn|0N~=kGrFe$J?kzMIeNK!S!DJA zsPW%#K@TB%)LB#XRoQbM-~fP|{%v(cOF>%J)lhW5s`;*<0{}Aq_k!R6;$IR$2LNpR zZwV1rpZV7-P62O`e98~=I zj^OYBl!k-(`oN>+*dUd>(bUly+^GPd1cIE-S0esA6CePFnF8*KmFvp)%JqL&B)&cX zYI_1@;_C#U76b~#zW^}QO(3qjmJA0<#h<&9asZV8NO=Oy;;RRs6awwy8vr};!~oz1 zT+s6*@&N4+sLcT+#CKe4hCtPgASall_{t&BbtkYi>D!BB3O#`?0BVfVD5>*9&r;9|PhJh3ST0E&s4F`y;g!y|3t=9>J%LBL}poRFUFPwm`5_Yv-F#J-n zoK?bFik|{O54#uvBfL~BY8Z&Q-JYF{YF7+`^;UAjEEi9m{ruIdtL5TJ{N9T(quLdK zfVEsaVWk39X@1z_maL@V|&a?!h^pX~uG6d>!oZ5wCwrvhLJ;W!*@?i9XdJ}U%x zxqyWNdL-bx6axIF+pGW+1a90r+w5o#faM08+BO~az6IR?Fc9V*Xcp_cOar-oY)KI5 z^pD(Y20yQhyYHR^?um8)5MYFNT67NqAt;nh8{ve92S7oNK%#$L;(XK0e$UfFC4pRH zmlsiK3W=O2IH8+Q=eYgY{XRghq5gFq3~wGs7(vnV7*6ydJwQz1#y||=+PNbFHVNc5 zAd*CqXYjoPc?)-hyv90K&oP`XYJG>UwEf)c{|D!AI4p!y7Rvwt002ovPDHLkV1k55 BYQ+Em literal 0 HcmV?d00001 diff --git a/static/images/ico_exit.png b/static/images/ico_exit.png new file mode 100644 index 0000000000000000000000000000000000000000..354d292890e740a77011816854863d737baf4a3b GIT binary patch literal 289 zcmV++0p9+JP)Px#+et)0R9HvtmSGNqFbIX=WSb}3Jej*0vxX)*JNxL$$QJuo3tt|O0#oqe;QVv~ z6crGWI}u%o=xQv{$js?3e0Bhu{02wZ{@4XTG^RON3v@|=1%PKQTLN0|{2zdNC@Bb; zvAY5yGHLfbn0cs`q&q-LXn}A6ut2y0pb)MA2m}o9;R~6)xHIPO0My#)-S=8YzzVbg z)RHex{%c^Fi``=uAj#bT(Bv)vt8R&Tit{#w%mEh#tY&pHAqr9g$m29@B}E literal 0 HcmV?d00001 diff --git a/static/images/ico_find_player.png b/static/images/ico_find_player.png new file mode 100644 index 0000000000000000000000000000000000000000..431f06fa6c4ee6a39b5f559bb16365594428ef4b GIT binary patch literal 632 zcmV-;0*C#HP)Px%GD$>1RA@u(m;p}1FbqYzlL03KP6nI|W~q_P$4>lhccaoGO_R1Z@$l z<8pHQw+Fzz6?`b*DDb>(n|$>6y#6Mi*3qee82oA&jt0N)AT2Om03QLvEs(dW9901E zx)@&>FO|@$0C>hrXh@jI7-6DwLc$D38lnPVg-yf|2^)kEP^PX++JpYq&JgAnvw836QtW)7`}4kbDiGmC2g+G9qRVlGfNQ4jCM zO7Hs}02q=~9#jFS#hg77^MIQ3KLFfR0dZn?4j=&KRO;b91T+A>Yur1DWqsT=sF($S za!tu7fJs+T;VuA{3YqP+Y`hqfQ9$0a&M^#xbs|lLVirIkEF&%8hG#-pV& zp7pvJVPzPAmDjbABL`+st5!^?zC;0L9SBKOw(AyEaS0It@Qe@3Y{+2UsYiXmj>WV- zL;!HH(f7%=23HlBx*x0nI@%{F!0P-@UG!%FR-CSYBXwZq;gv$+N=!`@v0PPT?5FDO z75|$$ZT4sP#U)$4Q%Ow4A>sXY2v31kq9twq^IEhX$cv^DQGkx*ok5TDkKURw7tEsO z8Ky(1Qm`sYg~E8Xjj~6CioxEyqK<3F(V=k!P`C~pzIew14+T2BSefJW3j6?E0+%sm S;hpjT0000ymEv{=+<0Q#=ma%_a+n*)>QHF9z1aYbgTvK=>RD5+xXfGju6%48u~e zS|Sq@C@O=))e>AqD#ODRO7(lN9F;4is6r}Nh-C^44a1aSaNmIdgDjbarE1^rGY6hD zh>_>5m{e-B*(5fFgkiI#GPPPQMdebtTnrFm&SBwkyV$~o^fPEFj$mmkPcs%+V8jhf z9x&eKnbeM3r7{UBsOkZdgd1ngV@*BANkU4QC^Kc@Ie?Y9u~s9) zGn|q68*2CGmkfaD>U3@!uk^)icAMb%*nA+PFCec(b9#rBlBQA|lgAQNY(8)^L{MYJ zVpt028CK6Qrv6-|^t%kpm6FNuL>*4h7C}Vl3tK2H&Qlr$ZfRie*TA`$HB`OQg zQiS#I*D^$&klX(K|3eI$apezcR+GA%(VyaA0^s^-(0$@;sU%=b)W`ViX_15;B zfOX4kQ0s}yK94gO#A$a|rc&CZZPlmjD??qL(^pqFnXd=81}<1z^i)0g$bk(m%zLBp_kCe$xyghrWsEEK2T#$x z?-nIR@7zDtNA_HQX^7LjXX_*=Z`Cu8J2QiuOKK#aB@)}_K`v%eUG9d8s^u}?tj~!2 zaNMCSliO4Wr$oRXL#{K1;KC~#Hc!}_K4VF$=PJ?Zx7S3E>}W}kTwWIhOU75ZuI|tn zKkceK5+ojP888wm49Y%R9QsB1#4hNmq*fhr%;Vy@M`v7#>$=-J6DEYEwM5^Kp~9C2 zE^kaMe$dfke7HRz(b3u*_jO}*Cto2(>d(!cf!4i~{^01qY-e}Stup9{SG{k*=DM5h zKC0E{h=C4&=zLmb@iFmN^ynMkcdV|m*HnKQ5^{QI``zo@)3_=KnCT=9%sI%JOL?e2{}V>}Z(8y}mb-4&f#@+T#H*X;lR literal 0 HcmV?d00001 diff --git a/static/images/ico_home.png b/static/images/ico_home.png new file mode 100644 index 0000000000000000000000000000000000000000..b005820cb639cc27b2371b548878ac0dc390d44b GIT binary patch literal 865 zcmV-n1D^beP)Px&8%ab#RA@u(m|MtAK@`V-pCl2INJ4}ZN#veHlH`)yB|af3Axetml2THxDIu5K zLKKBOxV(AuL|&v6PrP|i9_*#rwHmYco_+SrIp3E(bso++Gi(08wbraPd$-ZaM_VV? zPYuxO2*!-S3g9^K3pfp2jsY7BU>R^9=%Pf=2Hu2*hyk$Fi0|qUI~{l%5+XFf5+lA_ zj>w6?yHF4z0Tu!efbL4%QD7Lb!4f|UjXw$LsSJ2K~in{C}AgneHrQT6p(1?Q7N6O0L(Sw`zkdjfxQK}{RCJP z3ZhW}$!GC=KPBW8u*dUYJ_4lNR*pm?0JDtv0c!WNz%Ebm=`?YGbn8kGWdUXy@dMSa z=Ybt1#i!Hn0;|>9-@y1XCAJK}3?qJ!+VBFfy+QHmvYWs)fd7SV44v>SZ#C> z*j7<|y8If@u5A4PBvlKWoe#hiBYvpb;1aMkkoeS$+*UU$o8L^|$b~2Zm;~GdhAYEY zfGvT=r{*N8+A*I^$<2hw1DIeuKSGJU3T%obJ}VL*f#q50lm#G_K+4=GCH97ur!hIi zQ5)3;?-PJkE(jOEI3s?vG9Z;=eN4p;+t;mItP{cpkb8;b{1|2MwpHeu$zhk+e;{mt zGr&%zP#VqJW-4~UvL_v=lz;(VtRv~?e>j)@s z=Qhte0?Jc$3aP7$zDfj7p{!;rWisu=a)@2GR^7<#KB4VK1Ms{l1f3Q%0zs8|8vDNi rJe}0KX+?dYb;>+ZudKrzfQQ+npD00000NkvXXu0mjfz|@7< literal 0 HcmV?d00001 diff --git a/static/images/ico_home_active.png b/static/images/ico_home_active.png new file mode 100644 index 0000000000000000000000000000000000000000..04668760e45615ab2bdbb5735cc5a239c3d3d9f2 GIT binary patch literal 2118 zcmbVN2~ZPP7!DyQhqQ=RL8M(5aX?LWbCRq^gDePYP%$*9rMlVO9FSy}%>sdX;fPng z&?+KO#afF)Rdl>{s-wl$qhLKo?ReLEFd!B?9u;k0I5OI?b?VN%eedo2-uK`CE}D=! zIykUjpgIo^e>dNMfN zVS|J9(mGw8egYmt+yskAC8)=yb|6K1acnMUZx>FH2yLeww3BxMtkjETtqjk&tjxbq zdyiie0DP<0du6;)7l*?u!o?@%0W&%s@REA_qiBt;37;R39$#=!Ra)ZVRp4P%3Y)Ubz6w6cwsS-m`OraQps==ZI zs%I#hx!{dZ877T;4GNNmB6#AhV2Z@d4Cf$##Wn|Fp%K<;fg!ISu>{7>a6mB7PTsDC zUXP_XT|D6==@eWG1EVE28->xNf>g(8)M84dBE(XYLLt`BDl|PVY=3j3qkNLD`?84q3EM9C1 znP?ajygL!+Y7*Q0Bxhgx8Jp{iBaAB*Ter;{_j%A3MNr>Ct9IQ=%DK5SqONkb4l8RY zu2k=@kG5dFTfeu&FB zEX=e(_qJS!F`L6OeA(KIVKv0nwH4Q&_Nx}WylWWYJ9S8z!WYAimDhL6Zu|N%mYbNK z87(ZYE87%(#;1Q{YfcZ{vCHv;W*eiWwYsfq3!qxwf7#>k%>xE5DiWzm&po++eW&ID z;f@I{^2;i2()K*-Q}OV3W$>Ken!*h53SDljJUBG+$cZ`1)hSQ=T$++HJ`0bAmxyBT zRoCE0OLa42%WLQHy3}Xl^Izqi@>`Jiw0v4XgD^=d_X&-hdu~?XJ{>zI#6)GSf067C zz4S@y(v~kBNi#?D-=qtYA`(ogM!1FXL!Q2lgG=dMH|O{R{E1XM^V>sBB)g;Lof9yOZ&~{_35>%vp$UUX>8!ohgF}-Oq)y z1qk)z!lTQv*4CWyzwSA=;r{n+g>}yPk3WV7n;s+xbvyl64ZD7{7%ji)FJM!L)gJ7h z0DTcnO^%GCt9G<3FRId=$D_}%AKhAdvj?uXUM#Auf8IO~K7t3Gp{g1}^pm$bEAdTj t##8aNkN8u&T9*6tdufDC^Mw;1^$nOEjPj?u={Px#{7FPXRA@u(n9&i!FbqT0d0+^JU?4UFhF~6`{BZPokrOwVVCC1T9qBn~+6jY? zY4G(!0-_0uz%LUx0XPEKeR+`=0M}>Dxjr4G7CHks&=ZhX5=Mh>B_NuP2t*Tj0N|=? UF(!*^`Tzg`07*qoM6N<$f}v7=kpKVy literal 0 HcmV?d00001 diff --git a/static/images/ico_hotel_active.png b/static/images/ico_hotel_active.png new file mode 100644 index 0000000000000000000000000000000000000000..f01e7384b52766caec6a60ffbdfd1692444c04fc GIT binary patch literal 356 zcmV-q0h|7bP)Px$9!W$&RA@u(S-}y)AP_ukM_b6~+kCAdwvjeWAMvZ1)L=W}iw_Ro5snC%%@;Us zZ+8!v7^?g;mFG_Y@NWjeK(P!=w{yQU=0ZgKm6LqFt(}h7doS5HD4}_1A4GJL1j#Vx z)pX-Q689GXD+!QmPScGde*yp)2vh(Pnum7VCiW@T2Ao|&0Kl{_FrcmJ)bk?5NUiiPx$I7vi7RA@u(SkVr`APi(*rhb|FW$K@~OT-{4tPE}fDaqcT^zI71vADsYYddQUH+fHQ4jAf_X+cV9qH3NlNh>R>~pS z$R1H*cR_`C4jTXn1c;xZRX_p|tHcH%<&d=!zC^GvE}t-2e@>VHlKa~=%A{Qr+Z52S z#GGRaFxl0_o?Zdm@wpzLA&ELi(}~3n7+8%X8d=g%Y5-ty4_2bc3-xH`io6iY0wDaz zDMhXEPjIj=p2e+OXxKx11glN<*ixX$Cd?oPfXS{Vwke=ti8*I#1^iF_Yh`fChb=U@ z@bQaTDIiho#;FpT&I|S6MvKgx_uqK?w1+L`;h6dwWfIpcwkgnz%AJ8sft|!PTV@J0 cqjG1UH!AWnF*J*Fs{jB107*qoM6N<$f&zu5xc~qF literal 0 HcmV?d00001 diff --git a/static/images/ico_night.png b/static/images/ico_night.png new file mode 100644 index 0000000000000000000000000000000000000000..7548850b360766d760acca47579b7d1063d97288 GIT binary patch literal 650 zcmV;50(Jd~P)Px%L`g(JRA@u(nNe24Fc3u(_r(#uVH@HykY$M5fN$#QzKmv?)V4tLUNYdRr~TBl zGk4z0Oj@j&_+=-aznKC4TESU?f2~0Mu~{x&j@3OORV`G%Z{8$X>z<7&&JtL23o{sf^^qjt$JJl zT1Tq>72uXREd zw*z+X!vMhQqZ_!i>Nx-otrlV-KeX6EcPoBU0meQufJSD(U~*T++C92i^8s-CNQ{&M za%5kt6A1GND`6_5l| zYY+fv0`~$<9>CK)2qLY(wb#XzuHpZwmI^**{P3H42s_A1t;A00qylncYs&Tk6LkZ90uUAM1992mz>QA>JOlzvp0-f8Om|a)NWKU_lxRM5`LEK$kGuTP zBNLASvMe;rt_Xzum^+NE0uUeCer=9FaNN?NFzM_$!22TDEaQg@G?uCYXi&{{Gk|6_ kbDlLTkW)3ydnT{IH-BY9K*_AV@&Et;07*qoM6N<$f>Gro*8l(j literal 0 HcmV?d00001 diff --git a/static/images/ico_night_grey.png b/static/images/ico_night_grey.png new file mode 100644 index 0000000000000000000000000000000000000000..31fac96da7a06cfd014a25507d44db242076ef09 GIT binary patch literal 2181 zcmbVO2~ZPP7~Tkof|iQ5P!!p$BA_I@xlFPeg%X5N0}*HoOlw(pHxP4d$Sx2-6d1*F zRG{E+7V)6Pwos8OwXKS+cZ*dz;(_9U*NpYXs-tK(92xEObZ2(tf@WIQ2pl zr;L1zpq7w)tI^D&0buTYs~N-fBm*uXlXNBpbnCm_5U3**(7O^fqBe(+$-3}N3mKCc z8H;D?aXA6ap9jvhqAY=tWH8WbG?-}As(=Q0QFd*64MX4{gwZRYV4FcOPOSk$C<_V7 z`2rq}AOcV-=VLNLER~4F@<33C2t_a=f`uZUK!hR^R4f69FNig0A+%_;a>1}UcBg=n z8ODslaC&+=KV8J9EJ?6HE|A5;GttvV7?dQ9TXbedN0~qyBesM} zWfTzW?2rnh*-mSsha<(t47OrsSinbYss@1sZpWEZErvnk1P+r1(ny*Zn#Bt2SaUMP zP;@f&H`MmeFBo8>t5(}>{G~5Oqum6}gr>1Fh6D1KXgW5-Ov2G5O{H3JGBk~KbDB+! z84a(l9^JH=y z<4NUGsc?xb& zD}xRktOFFoZS}2ya9d(Y0vdj;d+7)a(WWPpEa^X_dk98TS|%N{kiki8wEjau!L0kR ztrv%sz<(Aw`0csA9f7mMz_zpxB6edRWu%FnUlw*y-IV~J0)T^5r3{Wu&OILAS#}Q` zm))xhyRvK3M2{f1)~xeW(bfky>z{a!iXY`Z=0NYGyV|rF+y=k(K8`)cp3yEIfF@$+ zxR&dMU)|p4d2effk=L@PiOn~<#zrl=a3E*RuP!~?*Wb!IbL&C#t*rj+5@XNuLotiU z)Qvup#+#0bE&6@u-RJo?CKkWJIRgZCpVliCZaA=B_Gpj|uT-Tfu*Bc6JQGQ#)-8lb?IX^qUXRTPdH@w}yE$6Vu{CV#9w+l{2Cz=8Z zwx#K2G`P#S+`gK&y8he`Ky|58$(RHn*KO2>uNTjBJpHUprYNtCDtl+yE~n2Xirc2pg~vP-qX#`Qjre_toM5EvX% z4dnRfjR)TD4s@%dy;KgDC12J%SCj|19{jv2?~8i(Q33s%9lNH*E)4RnUhRH<+mEtU ziIuNS+M_IXBAj>obx+yx4IHsW(;56$Yptf2_6|sKdiZ*Nf9_Ya8k-9R4pp_={X0%n zF5RDB*RZ`Qy!6$xw`+FBOL>sYYu$=#>vn}E_4RwBlYOY5ZO!@}Ys2jCv{I))z%c6v7no1_V%5ce8aElYT2a5 zSo5wwRC5k&xc@A?vRhyC}+Hd&b#K%YT!r_(1=DoRCYmnwm*0r0fmS!K# zt;)wd_2p?2x?^+xT>8o+H%(&8K=eZ3Y{x(~$9H9U#xI+*KIA-`Gw*5SlRKlII8+8- V42)QQZjS9oK@}RQY90~vc literal 0 HcmV?d00001 diff --git a/static/images/ico_room.png b/static/images/ico_room.png new file mode 100644 index 0000000000000000000000000000000000000000..9b04e200476830748ad36360d949fc8d4780c21e GIT binary patch literal 541 zcmV+&0^Px$*GWV{R9HvlS4(!oAPkgxFTdLB4h{T}SM!8^Rb(7av8|B8VM8+cp}-vHn@(<~t{ee-@juNh|n zJU)+Sz`*0R_r>!oKtupVUd!-?=5*^)(-8m`=WUd0xIyfe`4I!S9E|2&g*Fir0f5T1 zOBe$X6M!lSr=^7@<_sW3z49pK_LUrKPB*)^{m2>Z3X5| z353{>)sEE#|IF{o=Ui1Jd+UT;Q!E3K@>$f(BX!0JhF*SCd&K}|&+AGuV&@nPYD}C1 z2778Mz!>TQ>J0+$1MQ-`Cz9}A0WjE)$;Rofp#M_bqSHVCA}O9jz?;wgxj@HukpotW z9RS{RitW>06afQ{X{j6!lfsQ1aq(b6^vXNypd4pPGHHDM-Z0gWBtlW_^~%C@OXe5t zYCsf_J@wvHYRh-UUBEE_V!zs!KZyzb#e}1;(kYi-%_;y<>51xgJcWg1dsH(z(=@{C fIXy|lIhUKico0*&P?kN!00000NkvXXu0mjfC5H8H literal 0 HcmV?d00001 diff --git a/static/images/ico_room_grey.png b/static/images/ico_room_grey.png new file mode 100644 index 0000000000000000000000000000000000000000..1d2362ef3b2851d17313c98ff464128ec8715e18 GIT binary patch literal 1961 zcmbVN3ry5z953=v5OB(5Fo~;GbclEDUGJ3ZI0UXJ=#Bwi1f3|owg(07TH4|r7{M`l zh#(k@qB4gNCr0OM;vkB+unct=hb}C0=;k9PD47g(Q>Sw+kBctuWs|1g*Z#iW|Nr~H zx*;Kcp^w*_UH}02#Kq!C(i4>LaUKBR;ft3~s&|%HC37A6<4e?^qT7C^f;1ER2(nC?QK`_Ob02)}H z26al6ftNSMy1t+Y)PB&^Db}?L!GIK9qtR*OrM_6LP7{I{vs#id5|Edo1ydeJ!%4Kj=JF&Rvs!X1=m?AL?%UcOaGGisuX_&L6L!dK| zn1Rh^dC9Qk9XjNN(TK&_1d*_jbR4dSB-KiWp)kr!n8Q$lQqTycQfLV6JcXIkgeg!; zXE9qWY7I$-jh@F@GFQ&+=y~dYo_~*Lr1m1RUzta4I=LvYSVoZ2l{eB8OX!@DRW<_- z)d5D3a((L|Qcf&QK_jo3SB}6itv!R5NdF<-!!Uuhh<1Xfqtc~l{fB~rCHG;u7l)O= ze-%0O?YX`kg-gRgUOESnv~i9y+9u5}UK&*N&E6mY81sG{9%V`?Zd>}pkw(N@|1jyy zuRm>na_~x&SK@>ZJ~q`CF8V?|`i|kP{;~f11E$ncjv*~@C$`=38=;W8^7+Eoj?l{SlR54-vlaR zPj^*LYlv5PJW>k=d~s+^SMQ!lb0>H24^E|S&CFd}F+M`e+n3KccC@x6_EvDMxosmk zYf9yEF4G&B3S6#p?D05}vUfqj`FlaiZ5v$&LQ{KtyOtHMTe#5dCT8`onQ=BBsH$zil8fRS&@a(8--eW=;_KSkeY*Yw zb3D0}8`lndu-K<9j>8>s;H8rVT8~}ZU0?gU?|UFRF=0wO-vU3HT@Cnk4@P>PUSyoC zomfq*@BO4YaBokA&Ltx7x18REQ8icRsMaM|p)UF>-)C32o$ji<%xO#AtWiL9aQo}3 zYe1U13EVuXwsrBo`SlUI9~&bzcS7Q~>_GZ(_oAyi8z1-4~L}kKb1wzcVrV{OqbYzpJJ#H90jUHsA1VhM#?0H$k_{&IAJO zp>7*y4SqXt?z6_`C9d`fd|IO=d0M^K#Yn;P;ExN&FhM6i|9$5`V%4dw37H$_7w@Aj ztD2q;T)Dix70s#FJ@zlWgdRHY8ay>?tbePzy>LZAZNXwkT1RP6*?4wMYEnfreqmK- x(S+`MMDl^m&U0YtgYxw!S3D`fcmGjXR(Q59rnY&obG7_4jf;uL4@RdI{Rw73zn%a9 literal 0 HcmV?d00001 diff --git a/static/images/ico_set.png b/static/images/ico_set.png new file mode 100644 index 0000000000000000000000000000000000000000..256a5686c8f7ebc990381068ef1a9cf817c06609 GIT binary patch literal 747 zcmVPx%rAb6VRA@u(SzAs6F$_#k2Am8y8E`VFt2Hua>~XSQ(W2(3Qa9^(#_#ND-1s`( zxc=h~z*z8cjPX3ikl$>*k1;;Z8(uoB-)Vu*NrhU@ZV|GvDeTXzr?a)h8oSmJ0A3UK z5VujFqP&3EwYmVj8Q;&CmH3dovaSk%_5Z5_VA&P-kYzK7WmTRrt6H$$-Fzm?-0`9a zJIwm5_f--80MaItX$cXTB1haQO2H`zcGzrcq>OcEtPFr!=O6-nY{BFZ0muSvMbXuFXx%^nJo_w8BISHfv|4pj zGLdq7*;n^MOe^}82 zK#Ek%?&}452c=CGU-TU$U={>Rx!&ulG3F~atToj_rb=`KeWiCo%EQ)s)`ScIlcz+m z?zL(q+RU;3ojs3|7MmX!z;C&XF{U7U{^tN#Rj&9m0>Kz=aiMA;`GJQOC`O6^uB7E~ zpg|Qin_rJgqo@Y_Dt;`hRI4$Xvb-fwePJ<3L9kY0wcJ-)iAseRIUYp0m6*Nui25NE z#8qPS-7wCW3sqS{Qx+OKSMEg9p#PTxjWB0THtR~O<0E>HrranCuz}j9+7&lbW$i5o zaxYrYvNYzcAc`(sJ^^a8=?z`sgd}AEX0nRvSg}TS+ZVZCsOL%{kwbL2@E2W`c=2t5 zezA$ZFYLNn^o0aXMKsVHtyv?d)w}!+fmxuMQCNR(gI2!}$bY-f-z{L%Yz08Y-6(-w z0Q^O8)KXXXQN^<%z5KG-cvQxsx^!6p4I%9Cma|)gY?@|wq87}`w}g<4P5_MYL!RFO d975}a&@V}(1%O literal 0 HcmV?d00001 diff --git a/static/images/ico_set_active.png b/static/images/ico_set_active.png new file mode 100644 index 0000000000000000000000000000000000000000..54e3c9bb4f539409a40cc03222d9345ff847afca GIT binary patch literal 1992 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 YACU3#K;k)cmH+?%07*qoM6N<$g6yGrqW}N^ literal 0 HcmV?d00001 diff --git a/static/images/ico_warn.png b/static/images/ico_warn.png new file mode 100644 index 0000000000000000000000000000000000000000..6e8d833332a9ab00a561f45facba7a6419d7d980 GIT binary patch literal 594 zcmV-Y0Px%3`s;mRA@upnp<*%FbqYd?u%*ioou7>JO7={Az@(qUh9$AHcIWnYN`KgmD> zI@XnJOE7_s>~{Y2w_@{Jem|6-slR6Uhh8X6-X7Jt2pc%!zvPW(^AUKTl$ftEFhKyh z;o(O2vl_l8?~lrhGe=|*fQaF3Lz$0DJTe;~yPv*^$Z2}!_yqqfO)k&loPSROWMAh4 z8DovtKW2Di6hK8XQ^PV58-oDrIxw{rrJ zZSu*f7trJrUQ8zIWTyrINIHWl5HL7It$1hxV5B1pKty#Zc>rM65eKMyp#s2+zLmZ_ zK+Ov|07&~TZdCxB7YYFEI%gFCWZu^SC}qT8`KZM}u2;iX24)}K81MjC{jcDGEdvmx z49-Bh9w-5j8Auy|tOqs^fZnXD%>#DXvV$1F7pWvSH0^y-Dlw7i?KXvGVm$!nqg#!l zGm#2}-I)~t_&Cr2$g`aUfKCvXb)tQ2DZw(5pU7&Zl`WQ48Uxe>zy!0b2U<1KeU%nn z?h{y{LelE2;;ulQ2x2@fDX)XGQar%Y28WjtCaB{8LR(B8V#`gw`p^k%{>MCnYqK^W z3U9=AS;i%`uwy^jC+>Ti$m(^W;m)ogfL45jd&CsIw2*fsAOIbC{nCM|S8eR&=Ib{0 gRh#mNF}nWTKMIG08#&oYzW@LL07*qoM6N<$g8K>re*gdg literal 0 HcmV?d00001 diff --git a/static/images/limo_line.svg b/static/images/limo_line.svg new file mode 100644 index 0000000..3f18ab5 --- /dev/null +++ b/static/images/limo_line.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/images/limo_line_2.svg b/static/images/limo_line_2.svg new file mode 100644 index 0000000..f4abc2e --- /dev/null +++ b/static/images/limo_line_2.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/images/location_fail.png b/static/images/location_fail.png new file mode 100644 index 0000000000000000000000000000000000000000..449c852fde34e77d4a07190cd82903454b57cebb GIT binary patch literal 15950 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 literal 0 HcmV?d00001 diff --git a/static/images/logo.png b/static/images/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f69a1ef391d0dc07abd7d2af21903fcadd4e0bd8 GIT binary patch literal 45248 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 X#Lffde!BE`00000NkvXXu0mjf+^Yus literal 0 HcmV?d00001 diff --git a/static/images/mgm_logo_1.png b/static/images/mgm_logo_1.png new file mode 100644 index 0000000000000000000000000000000000000000..f7d3046c5b55f818cd307cea9513a3a8cf6ee009 GIT binary patch literal 57027 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 ea^joR|_1T zV0(;KT)b|A&;4O#sqh>-h=Y|S!6;-3lNg(Pfi~TrhJav6LEz`+-o!-KkY-{h9;g1k3Cx!f^OED%m*7Bs&hzV00nW`gap-u zJG+NVSKxHf89|2i550M%CDDHUl57STuR%!UFa4c$Pv>46+y%wE1|NvNl&p+u%&rJm zy!96?Hck=e`}7JKyhQsZb9tSGRNMrd*1SiGr80Vh_LJtWW_Z#z*B9QN)?QC6oO6O{ zh*DKn6!^)~kd>o3GN9pf%FC?rF#h0lktwsT{_#H7)3RUjC_TrVoOMW|=x&e1NF`@^ zj3{fTTm6Tt_wi9zQ3I*o+eWl0C23}s=nTGRE>7mf^@t{stQ$gP!y8|{pV%gs;bcm? zuJ7FEjRS9SaamrN+oK&W>R9ExCi~OdqT{e%d#&1It3w}ECij(A1e%=(VFFAciC=Ut zChcOr5~DV2zOBHS*_67DLcp`b*<=EZUZGK_%MJTu+9Ki!xV%jK6;9i2WWpZLzwUF8 zZyRZ+63lw9QlD%+pKTAT64^LV`F>TvLkj^H#lLCmoSu14YL%>+IAdEwFw5<2m>(`x(PPU9DxpqujpNhiI! zq?X;{(bb!?NHtQ3*+78O_yVgBc6{tN{dcBQrgOWKSBH%k?*2xl+bJ3G1c?aR8z8s2 zNoXojAFGyvj~zFa}uYol#p(YE8>NHqy1DkV3I-4q9&3!O8?c7kpm=@5gx`7 zRE@}luG_O?6?1ivVo&OC0}Ces0Mv$~_I>-Lvn7DC5mO!kfS1g`r$c7zBT+XDW`4_U zOnmF#Ez%d6kOyxmb~2v4K7%m#+o%Bfi}M9Cqy5HKAzT=ohzY0OtW)D)hM(EVeexEHaL-IeMdC zEedR#Ro~vsi4kmYh<$=6ZmRu$^UP)1voeVnB^4-t!;L~klMBQ_g{FfS0s8~d@Cn7^ z{PQ^w1ztW9`|mWZpM&1ciL1He$D{jr$?;#<130jJY`xlABMB;s!89?Hp5I zr@WEf7%^wj)d}dXUvKl+PJ<&`Rqr_DuhvnH!=hrr{Mq8)Wxp9$2bX7!3?-A_vHLLn zY-1S;2gEzM<_}{g6Lxu0fT=u4y?M34L4uNo@&90b2q|K2vh#VIJ1yVyMJho8P(yu% zkEzT=ScvhFsBS4XZ+AL|-BloSoE4;B?aw$|{d=2Vcd@S>)maZf>G0b3fXhswcaSiW zWk@4R9Wi`8M({_zwHipiLQoI;A|u{XV*8pT!5ro3E`5Vhwet87OlzN(@Q(bJ;7Xz%sr4Lbg9zV(6?<0^=?Jb*MiTn&& ze#kYd==jfSJ`Qtfx%9VHcs7n50?ex(H}g{=FM@)N805Gxbftqgv_&P2gK(y(ZD#9Z z?4dNC3s*f-+uLkTok@_Uy337-PiskQKF)e3pYx#Zq#O{S`ni1Cyt+n4ntqCf9&ab= z*7Lpos+B6bIm)RwJ4=Zi!^e#$XIn06b3Z;r4Sct`>n2 z9Z$a<{SXGNQ&5fJz&h%ydGDi)2S{Ni!XiqWgbebsDrU(zn7Hr8w}KU0Z?A#6%WhF0 z5feUEt@^wj;;p5{AM(1I#RkQ8<}!9iRDhVg3+YaM0*BUZ7B1zb@LWea(qnuyx$je+ zB_ow`@F6aD>f?$>;OmVr=JRvKXenamHVLST0a^mKV%ta#nVPU9)rMLxIRusof%Bq< zQbpN>n0(Bd@g!QlR=K&pWMO@wU;OIrZN6`s;+(>5cd&ycg~K3fFAN#$FAJ^CbJ<0) zadlrYil0JWQG}aa9K_zfP8AIjW(Gz_`Vz$h=gtKnR_nBWm-!{8M5PV3J#?l){aid5 z?S*T(8-#=|L;9CzD|BZ*<~^3vfgKM%y}4#IkCsCBTIrCN2isngUtOsSrhiucp4xe2sWKU z3nSogL#oPfyiN`g(E(mYo(=Gapl+A>J4P;}uHUM*lAF~BPBvbO0(Bb)O*5Sq>(8MR z@pjAYR~NccZts9Dd{|b%qzbQ3zaeKw(@zb06wKGq8#$ZA))TAIg!NdnhH>|kDV0!J z@33%%vx(7UEID|@De}Bxwod%#hwc8Vj{Vsj0*=GM3e#tZ-(=};dX>*YQ(4!eA;-EH zX96b~12f5|p?cpmGu@nz8!J?gLmFbN5)<%0RIxAD9j%nhWyX-y%X>bixAtR@O}x(# z!}gL zewdX6HQ)cb|DeYY+_H;xIb}!vQ@a#h$ydYs+XX$Xw1@O|o6TX$l>Zvpj75Gm%b); zOP_1qZ=UkUBh*;A_}P=Q6A?roaXxn+Q%X!Z(6}|(j!kPSx|_r&U@di?LtdVqdQ#<| zZ<@J$K-7C5M^oV7*4>{jrEA(*_ayEGEI)&n8`QI((b>tNOfOHWWZ(uiw(0b~er0i> zuUH-K*b#sn#i>^r-Zv zXr6_g(GP8ma7;HKJq#RV5-is|PqMP< z=MPO0Qh1VnEZf)l(Ng*}pV=p2xQ4Rc<`U~VHohH0yW8X*W+g%yMo2jP_Yyj-DAu_Y z%oie1@P=IDnou8`(IDWZj!@I6;?Q4T$T!fv>ngpB(#2PzH}Ty}5cu5QDjD~SZnyBM zhhml!mWE%{RtA@vQbAqUcjD4UVx>{ zE;lMo14#u5tLdlGQhGMFsv7o2v|?1`h<)-5A1^xTd9d**JEg~0Y#&LDaa$iwL`i- zvo2**u`U~NAwc_H*t?ANb#JA-r5GFQ5b#)*T$d&E6nT$PPWch&VRWZ3T}75e63Sz= zXX7R*k@-6uDSLX0kGdaq1lQSi^DsLBJgxe)Us6J_HLO$;KXVz+Q*YY6_=??sJ94&E zP6R|^@7{3VI(j=TT+HIGqHNy1=)>D@2d{C$nwN2Da*zyxJb>z4Z8_>%G9X0 zlr>n%?XEqFLrrNs+sDtkbwqeXrmyxpj%^I7{;=5!SC`cAo;WY5YU(?h^Bs3Z zrVG35E!xcd)6jz@es(R6oZY$MrRVBct{evE+N*~_5^Ck59}ib?Jq!bu{TdVN9K%V@ zX^kb*I@|(mVpj?ah@X>=do4RTT{VmEZ4H6UX$3=&-&s&kb&BhEhn%&EN=3c*V5scR zUEN5j+$mj&s1N>I4pC0Uxc+XrZ4&sTqnR~=_2!=?=+(6=;GM$=-KH5-*?Kn6`D{l| zEKjbesA%<}D>p7X(KY7Jl&rwnsv($TzWwAxDed6Llip=}-;LifVziZSyT|#fhxcfq zQu;Ru#u*N6v3_aq8MvIM_FA6j-BO;rea2Idcsf(G60(a^hhD?$th1Th-Pt%e(#sSg z<+Qrm$HEY^&DtKOBka@8G#V^mrmc(_0|7o)6PZkc_~37o{kBkF_ig8zVp^Ai%=DjI z0Cha&!MEupf5JOem$#5dcJo2X;-LP1LzUAG?r`gmKJMJJ%;#J1D!Yvs=u|bys>V&I z(YAI%ekx3ZAzNrli;u(7DZ^-0ab*chv^81F`QKTO>;BAFZ-rR)_1!7M3ObIBxl1?rwXY%~~DtqaB|Qf5e7>wa!Ackmu8)0NhM%PL;@ z8mK51s2~jST}8Q%a^%xQ__fWhivv_|yY^5G*saQ?3IFttq8bg( zhb;z(q9zTFpAauM`yCMdpQJb)Q=y!+#m`U#m9Xa&-b(OkzD{02B z(%PF3D@X-NOKjJHjg_bMC-p)VRC!5)&p`;ZZhvS5qqVE_z((ijl+U0VsG=ENq1Knc zO0BE4TZ|~1AJPqJZbeC|vObSzg*A69hsx4YHXiHRKa|CMt-K1AN3QBy$7s#Jr=%5_ z5u?0vh=@Q(*g{QP9ct52iUc8{0r+6|Xb6Z%?;d$e@4sFkZ*T7} zFLeIEIP`rhPM9klJwWhw%7fdv2^{?ZfOw%m67jL>UC0^spc+*AD7#8r7FhcXFmmO& zXL2^T>Y+g&Q+n}?1T;-$VLsvb zjz9z~9+>eG96}7ap)%6)vjLvNa>VtrHURn7bYy_5yE(rmKB_3vLvbzZ!iaXq5?B3) zD`+;WQ37(n6nSrc^EEk=t{4^vKr*2VzGyBcR~{w!bi z|26p2f-t3y%oe=V;-g?KhMgYE)~{h)?q+M~StkotRn)95sL$1j@|}Kk6!4O^qo8%a zx1ow3s3Zjg!H0W1qO;~vtbJi&tgfpILZ{#pnAZEcvD0B5T>K!jC~`>SEjS9b4;78Ys*fkFf+CCB9=@x7%%Qci-TCJ1C1GUbi+`u02qzinO(y!I z>eMCgVVo(wv}i@RS?6aR@10bBZ!gQ2m+n8Y_Cn@*gf?)_;VkwYGu_HORSEF9@uaY%gz(86#-Z*Im9l5Ch z(nFbjXGcM=)d`s8IiCFUy{M@@GGg9GdJ#QLd;*7pa%86W{6|o3bPL)2h+lD&v)ADh z84SX`tJOIv7mK4q>`dipVWOagUGHWOk#F-^e&~JWTZP-N=emZIl;7ILtts)v-yO*1 zbOMN$cn-nu7&t+IQ{g5Xxo33x@{g|uUhXLn=WOz2-V>yZ&is5Ci1&8A{rXs~5`Sw) z8NNYnSsAo(CsM#2v%bTl|H-S|S=;mMe4n8^)YjB^miPC+&vix#SaJBEmq^IZ?px0N zo|h@86bFawL0-hjjfM%)gnj z@KRD1zHVeqSBVw1ZXNWL_*iX(ZSuRF@j6wrbsHFfZ$$KccCQ}Y&V{S#m}n>%4;RMO zl!)Bta0as_!L*#se;~0LKLd_P_=EFvvboOR$}2xHujtnKULP zmQooMd(5WLrXZtC_sLn~OlT(m&id|gL!XZX1dfl%jjL|U+4BP#^}6?7E5EZtv*cKy zO2bepLd=@H&{Xe}=Z&3O^{cBgE2dp|{2Or{JeRCV>i85Yd5ZxCdH$9*#&f*-z_vGy!k@fK=5rdAlI9c<- zApLT+N2#)^g5T3b?(8GRE$MFLJBr#6*$ z)X0WR<6s@|ztEEUA=mM9vE~?&CmGwrg!q@cpGQzJ{7|=h%Qs$MDLaL5o;;MA^;o*V z+2r8@5D_WXyiUXa{K|R}*`jF_0MCAyHXBU&G#*dIuYq`llLmlzf4k3`)1F^(mRonk zVF*GirFWD{8V>C0wS(wS$WgJp{5M!>2L5(B!~{%Nm_cbd!8T9z8*cH2=eNe zSTt+FNcHsQ)P34*DM+01LL&5JMWhZ`ow-HZ(1u1qLjv2e?HIL!-E)rs*h4<%XJuBQd`1xy0 z`1r*6K%;!_*C22?n;sqAWQW|`B%#)1=_WEN5|p}FrMrwQ-k%tsFlkyeXWxgPW_DX2 z2}$=@-Db9|JDRZ>Y5Jr&GsVlm)K=!wb>{QI+yz+CBIGtIZuP!r7S-tWYV0d`wo_DL$ZbnG=6#`i^ zQ@KK>mF7tdBg#~Qb#Ofw)7tATou;7QFkB?}xlBYv6f2rS2fmWHNgy{DWp}@AWyMV0 zz#l6&na8dYWKgW$_-`K?tj`pmD@aUKoz=wO#tP-|eD|+Ejs zP*yn@8ao`|gQ6`cv-iqVexEl66N>f|L!?Xat)(?-3M9y9I&xqztTDD$>ug}Wm`@Mt zNL}(JH?mG0R%L5Fjtf43o2ndKZmP6_Np*IK5r)s)?dT|4L0)#$_7kJ~ezBA(WxHiAKbzo~Pv3z!$XW5*h>GjU=}}>5 z3^CJ3#~#mE2%6r4I4wIt5&--yr=(y}ap_jEaNmNVPPx_=_{qp}0$ zb)1nnCNlAc{MNH(4se+kym9awcR3_}P@1Oh{C)4Fm^}xQ-_hsyxC8cEG0;-O3cIHk z3&Kk9GF;G7S9Vq=T$>8sX&@H`gjM>UMI+7Y@q47TkZ{T>|@*VwB%e0tEh&H9hVh0<9cZou9{4K_d}gEfV5NLrjV@rn-*Z?CQ{ zk;*yfB5m*K9Kx*Em|t*(Ie<{UbOY-i%pzC;J!CE^E=kzYrm)Pn>p9kb{K(bAWWUTW zmYQU%RmaD~2)E=|Vg6KUV^xz>R`$u}?>@G!YoI>OMOSPZiu<#qFce)(TlH~; zDVDML!-v$Y<=I_khUMQz<2mhi{HR9qpT;=D*x?w_@wiuAd)pi41Y6BB4`DFuUug>U z{a7$y@N1#aIS^`j(g11xdm4-wA9K0R3cynLr@Yo83LZdl=Zqa>f3EH4n}KZM=N}jy z239soW=;$yqJ4S1rh(bq4kvTXHhjI2OP;f3KK#}z;sCL8Ca~=6UD9Te!IOp zTCQiKZX9#pfS@e;6;#UFZ3k`!?M91JqTEqgn{}mh`!QTr1r|!dxt}pXO6QBs?(>yn z*-ujLCNxbfD^bMzU@IJ+W=*Z7B|y-it%%iD7JYch3*0nm4#c+Sci*4qzfU`-8`m=( zboMXt6ozzLw~ohCEE*$Xt|Wagwo}yLZ>@9l)o@m#g>vagf9ItA3=UrSbrP)MGrF+S zw*-?+ltR4FLBm-w8-Yet1v%au`14R=DiMml*IKx>RlDqklhCd*7#8;ZLgaa~DpY+{ zOSAAbT3$PZVAItL#=?0b(8vMY$k2=yIn?k1eXFbK{iyL>w*BEOb|WHW)CijcjDA04 z`W@!U1#(|Ar@8(X$Zhi_7)699d{2o2HNhVm$O4nm$;iT;gybJQ!vYvIW}!pLwTXj* zZqi6G#J7;no)AUEp$7B}IwP6m$3w&9b>bR{A#_o8YVl-$7xM~Zrzxh$T9%E2MZ$z> z6typAq~!@kQTB%qHqrZh`jJ=_NZSN(7Gdu*?%pIYB9^zIM8^xu@NuCNhC^kaVg4E* z7YJosJwQBc={yo9e7>?QP;+p@y1GBQh>a6}HywNJZ85e$YF8d}Vmsd`WeoH&sY}no zvYef3g)umcxh$8irC9h@UE|{#)S7>!Z0uXqW%C&w{cyR#cKu@&cMW}>XhB<1-Gxzy zaNbE?-OCi&geZg4cz~E|H9bA8osI8ryHeU=As=z2Mys~H7zUg2;jJ3*K<>_!q=ROb zaYRq@oX0-;vf%so!g{1_=H|psPHs4Qmh7a-qmB4irJUT;XlmHwdhQ%C9(yl1CTTvc zW=v~;0%G{D^u`%!kyz3ILU{r`{{iJ8wqTSfQSe|sfu3^rF8b|fs1@pBPF&NB%j%pi z+g^??yEy-^%HsI)$ddm47DlioUHED&JX9qgOrha}px_4cZ~|h^wyV!BQ&X69hdjp zdxchX?$au^t7C2BLKUn0fMBJ^>*3=ychjyZn&mOl>0;k;$<#7%zqxMwVgLyV2coezzVByl>5%%F> zP}q?Cv8Whf*_)i;n+ z)w!%fISbq=i zyq(?CJ@axuH-mi-7|RXs&={5$I)Y5{6YZf)5NlEuULMOxPpe_@JDZWL0(L_vM-#y} z2e6W*4X)c zw((@)_s!X&nqj8O`L-{-U0Ohk2xRQ^`tCI5Zlgg?QcI$BimyTVe8?sw$5D4Y>f2!> z-iP@{Hi<_*4X|wr0q6Qt~s`Uz8 zD>3?z*RyBW)8)Q?$^Oz1DSN^5d`;gSgF@4~w%a8zbK4^yHTB!Y+CHg9Rz}jpOZoJ8 zj{Efj3iIg5;Xv>_m!KX!6FzXvod=YpI0KdCeKEm|EkqPRNSTYOQ_{sjfU+;ZZ(=4Z zzO%SAfY{k#uLntICw1P9k^IK&z>Q@pZ*>~{(Brs(DImfyl|>N!+~IwHi9q&b{Q;G` z$X`?hKqD;teqb3ZuZxaFfX=`zC#^3eUdnlN^Fn1HRI-x|*`GvX0;Kx^I|eYN601$^5D4ryDr}pEg^%O5LJ{eD7*R zl?+_1%TiaJ_5~B96U}9Gab~}1B6k%Ow#6H0s^XHiS;&u8R$cE2wB1x(lIbs-pUyXy z4(+Pt64yGuwb!?<{kW<+MsL?`e~nHBoqp|#VBwbz%cv^mm}bMoQc0W>nz}7|F+-5y zid#Kc7Q9_}B9g{SxQjPjyL+k@jVq*SxojFpw->Vu$Kg>fsZXb`cGI4Gq1A?|WV5*cHdF zAJ=vIq>$m`*=+5V#kypGDQMMA?6iYdy!YG1*%b2{ISIKcMT>TgGl~w{Q~$wCAYs(T zR4>X;i~D#+B3Wc~`1IelN*CK?jZN5z8G&y1@BBGe6bQBWM&{=iAKxGOF z1JV((uA;qVC6d^U@<%@R2;~I(F?5Q2?uiq!lYcsYWw?=L#TmiE1^1U99Sf?Za@sAl z{ry}@(u$KO%wC%IcF!f#;{B@U&-IwkalNL+yMWX(9}Rs=Nee4m%CmLSyvVy~`gw=D z<}v9H5eZ!T=g+mrA1F(~_;#0gTC^3M`zsB0(?M4s8cqy1GvGhDwX5ofp; z(uLSoRj{TE!E0#-v27RA6Px-8e5eF0_H04@mvG;St_@G1?i`&67OP$Ef}SCQev`E@ zc!JB9Kctk#UGl-1Ni-mSF<(S_faAcu#)ZrTAuZJsZr;_!13_tW;4jt~# zr>p47CdG@gZ)9m?WD4?VB{HlVf4%P11?9#*Kg<~j3ko=2`J+;r{+eg}poN+zM> z(0)F3V8;d~G_240R)ldZx+>$SC*kf>iwn7VxK4MK!U?Z8xZVCxo#Tss7b}709Yo&D z&MRYqoDA%RB(y82e|IT<&Xm1xf4mq)F(B2g-Tg7t)?07x^_u())BD(wA$BW46mzP3 zdd(>d{C;1%r{8;642V~+-M%G~YNT6cTIF)Ptt%fi6xX1DyZZSuPoShP>nhgOXX%^4 zCTiocr6E45Uooh2`5ILcq$`7v(_FNAmuo;-9)FUNffoDg`BF$#ojdAW#lwnTyPRQf zML!<0j{HPZnrEw+qr$j8kI0Y6359ItFY1`tV+0Q);%j(lt@JwA0uzZb-|zeSx)&X4 zF8=irL3o^i_e~yV6q68!1vYe}AE&lEQp8%4*m~d)$HGjq>g`g+pwZ`O+U;z;^>SD0 z%yXj|LzLFhsyEnZqH80^+)bbVGMsKqDN3anj#KZCggD(TX#%=KPcschsV$xIKq!GG zu_C9jd)}9QsvZ^*X<6B(tGbm28SB+Q=|;V2)}w)g@^#$FY~Po=)4GTCryJtKL1M9PGsi`hO_J|A*4T)XPKar+ zi$r*^NsZ^kO7|ZpIPDbuO+Gl8le$QKJ4~GPFbJuTN6}E;i`?F?W2gYGvcPo%7#2&Yr9{TVD1I?_iBvACFPwc%Pr{l*Xa~VtID2vy2~+c>s)VR2svRktC>xqqKYjqq@Q@Nd!^=H z9d`e)!rYOKGFPSk5PY}{i>D&kR$U6&d>IiyE2=fnU9#|a-R#ovFvEd3FPKX+_H-5mZK=3f)cvyJ|>vN!=X6ocH61sTxz;#xJ^DZ=0>Oj(tOcyO?L;w0cTr zdPai)gdpE4d!665D&lp=_qmpCM>D{;D>Sjt*!HWI%J%b? z(;HSYnLFgEP!=y}$=FauT?An=l1r4ETjGR9fpxvXL=*B(EHcnKtbK5nOO(5ThaB89 z+wVJH5CNpS9K#wbu;hplfq|JiY)pT@dL>1NeVaw$VHcst4kRupn0RIh7Ci31Y<+UC ztO*ca`I5ATLJL)rypa_~uMnb~@5rwhK-B%5ljZh>V+4`lcLW@7GXYkUDoa+hHlNgI zY9Q6li}|RY96-?s>CsQna8LN^9A^G0_Qhr=cMS&7Xe>S-3Tn5A+p1q-5KET*g=q9* zU6F%2G+&HgIBOf#Z{wPuDgRgYUL2LMFEa7?^5iJRr^&002>=XhDRHjs!?Z<6?Sz}I zs!YgOmGT)@-Ul`4lEejYR&tF;9Dz>ExNtjEupkchSE?k*?UfkzuPBi3_O2oCx+t6D z*?-X@~~F$g>AJ3LN$iK5Tx;Qkg2yW^C0A zuG$yK>T&s6zG(RN0LfsL?x!oH;w!4Gt(FAqy|u@tZ7<~~PVH)q`4!%DhrleNd*Ek% zXW~T7hdTJ!;J%=Rc$nPZo)CpeYiXOFS<-V?cAdQU8JVItt}|2p^`g*)N9nX`H#hW{ zUD}_wfedOT9XadOapS#Rs$E;FX~|$=_42;7fRVg}ZY3C&g5x6JxeL=mlMNr0d^F8< z>#H%4w+<0>+t$1DTy9bQ(Qg~{ne+g%GyH-eo(R=j2ahEU?JF5U-;ZoUw}Y%2NwvSO z**yzEq|m)*9uD9H73dKC5&46-DM|@|rlv6pP?LALQlyf?2mG%jFe! zk`hY|uPbByn>A|#+ht0ZQ$%^AsAuv8vb6VpxT#4E1=Yvcm&5`{o#Xp+wP9q_^9m?= zCps{H-z}g41lhtvYKozs<(5}uaD#(RCVlDL!Nj3T#KcSC?uX=q07PiQss64yC*tu8 zUe3)lDEKjQ*lug6=^`X@XsW?)otS^V9y6STAekpX%kv$O{qzU$AjE%NC?`pI-<3C} z0E`VfEq;`d>-t7cOC2;S%?@qJh#UBhBJL36aJG;i@P7boK$E{?y96vo>d%*Gt+m$9 z3^;3eZ}3XkekFm>p5gppm`V#}!4S-J2~rIQH?ErX>a@GgpZ3VvzrAzo%FiA?y!-=s zbS-2RR3)eh+5!L~4$c`T4aRWeg=cMAxsYi)+`T7svNKx@Fi`N}+b(OWEQFGbF~H#l z`{R!MPY=HU2Li=A7mmqsv(jCRAUL3cKm$}G5QLI|lf!J#|AKDuf0!sm(5O3>*HFA? z(NEv~<p-zpe1lfxe>$ zpL+hd)6YB0-&nP8?e}xvf8eW!CM^D7GSHx{1`sh~PUbadsHv_kFWA*@P|pL~)`k7= zVPVqQa6lkQ>lQ7@PIE;W0U`y`IC1qi&w#(l5QRgV4Gjs0+ebnJBw^Q-Z2I=m2hM%r z;S25U)8;=p>DhDJUfQqIwL{aMy(+tG*Ox#oNHGGF%_fR1!;J&sU&OQhuMjQ-f=zLp z=Kefw^vFJpYBa3S`5$_bP;q94;FH&1*QaYMls8t@Rs+hRhHz3y8Pgzp{^wt3n`S#+ z`SdHV-}UOu)J|heM;Ya1G2`-tG6jg?dOT7xOrFgXj{aOq^z7l6@7fkpx&aA=1{-T4#l|C56NR0t;{ ziGt+R-X)tzR#$ACI_-|GRI~V_oBCegFR4!yPRVthlIfXtNB^?buTc5&AK$x+lwXJ9 z=r)lpZGWhI3MnEx`0tY9yze>rw`xdE3W9#q1EV- zotb8d5fKc!x~Up&@3~iBJ8jBMELg!=Z55<&*^SH4@e z@vRQ235R#CPfSgVHyZ2wWv=+TI5!}N&+l`8fn7CbY==V!^H8yD*^-6O1Twk9|HA+>psX#6e!1k* zksH_M9V^UBPf2dpvYb@IiNktba9W>?oH$qOe*FgaCc`j{2mlN!l#Qf0DN`|*V&aS| zZ*S5jn2W$EOezIV1v_`f#<9#y%>s3uI|lb}T*HL`5n~1^fN2JvzkOeyHp$OFb4k&W z!-se74*CN^I0*uOVfg*sDkMO$fB{uqxFm1OY|B^SZJ)hi;WsYfitpanl^5)mR$5+I zkeL=gbU;>*u4#?6HC9d2(VZ)kn(7C4jJRO(g?-OCAHsO^v59w0`2uDtm?qd9?ti1j zPfV>|u%K0TYHf|b%vYVd`sWcNA4Bj6-0c_uMmE7DJaX+7ojPW3-M+h5msF2o$43j0 z1Y8^d>Bj1c%vd^O@&I>2Onp@_J*OKHC*ojWBox54#hAf3cL7lP%4=_M*gF~1A_S!b zgDx#RJg`rv+}1G#hYKS2&Efo9=l}_i0t}%EoY}Z;@_D^l$1V8fx2*J}hMFVEJtLe{ zB*xf@T0ii2t6v2f!60EZmdQX_YHWr<%*b@RO|5&UM8+lU*sum7f`oF&!3p5788^VWEo}!#0fRL0kiG|ya!Bnd0`~av z=kGsUf25${@a}^4J=z@2+pI}5Xve)%v}a>(n)l6lOHz_DLAKlDZ`~>l$~unuZefe! z?|2~$H)##Kyk^&zA3kzxL-D%gXptD5ShQ*DmTmsAlkQovc85DHIXkCyU1McTR8!X; zy&~MQxVU!Dp3;WW+O3=OQqwzTCUsDXfA`%Nm1T#U3O1P1(qLQx>fgsDtf;=ee!!qH zXP$R;W@@ZLV&1Nwd-mu8G=ei|Ei`@n=Ckp!=74i1r?u%Bu$rP`IHebkD}BaxmQ-3}gTxq~ai$+)44^nhec3I1dup;97tfpma)<*}mI=3$A~1 z_K%w*-L3K$PcJVk7SzZ{GR_(4d#=AMB{>o-q9#CIuQw^llaP_$X)Tz>?9opczq zvKgz~y6{D-{@8g}-`MT6$tqIL{`5`hNu7B6gJ)iP*T8kjX#=P*rwU-X>R<>=WGx7h$gZ95og8rKH zjvm+!rK85TeyQK}OK|VJ`Yqp-Y@X#- z^`_JU91KSb_QpmdHMc{T5#tilT7UQXJjjy1gK`RX?B-f&t>LRni7}ph?(MRI{mSL; zJ+Qk+M1yQ!Lqm&Q|Af4*lODoCAFJ8^L5#a1IwG-EmvmI_?>OYFj@^fs?Oo@M^$Z?+ zX61oB5eCxQ^>KL*#U%Dw`O~bfIoZ<}|J-lv;FqU;K6A#@-CO1+cI+)w?6qe<2bYzc zgc1Fc=6rO0zfl+VzThdX9E7bV#bH3hX5gHJWC6p0sW%HXgO;F~($E4Xk;NGUObSPw ziD?BTz!D+Y1ADql0BU#PMg0c9nJGt<(O5>qQZ zk&jKC{^+IWNIkHicIjE?O=0yl@W%fB-MfQ(wCX$R0#}UN8@qexIo>_THka1zsS6AU zhh$B|jPuJT-Lx~%SecPM4DbmV1tBb^UBnFz5N|hh0!S@-_t_)+b_&*%)ob9`3-17n zvcNf%0c-iZIc_EbLFHi)!!NsX#q^icQe%tvzgJOvZmte;!#sb?&~|O2_SV(*?l&qX zHGbq-osVwY58r`?hSY@P+{he&M2H*WFIK-}5$;&GFuv<4xot-V{bJ|5xzpZy^QV`e zKeFy;+X^5Uob~aX+}<&!X}3y^-n(Z{f*I&{=D_$i34;dp7;(ywYbT8@D?i$O@VEo} z?a34GZJX^q^UThJPU(E{O^;vqf4} z_V|^r+oXO6w>>Ma|#YQW_rB*R!Xf3Yx( zfOY}mhP&>q^P982T@@D>J*Zd4-p$L=P}3pFd&8{{$RGm~6DOX{$a2LcRg~;2tEp1Q zSGr~`7X3*#|3$ODEZK7CqgUTJx<7x{jze2^G`dOD71i2S)UbgUKYH6~`MXyqrNvj4 z7finRio)GnY8$KackdfMdgPoR=7@$Pv3C6*5dlck9r-ecK`JbB4D|yl!H@p*b<5Iws$6*2tHixO~t0Z{y73VZCA|j7^^~ zKBG;hZ|~0e(_X*fvXL1#o!)KT_aDHjVcH*pQ7CN?7m&ws7NJ?pA;7?ehJk>o8b5q= z5?obFf1b_2DRi82fIDU=K~ab^?F0pR)%RjKs9T(Y9Qw?Dd_ulZp6M1{9 zyzZ2hKTYr4d*u61-(OXJq=|X@j~ELkGIQG^!d;^ynwkn26O1epVZ12mW(D9chTkE& zJok!g)3c4Ln&6|)&1l=b^X-A3~5oOD62WRIO1W46zV z$&P2b>~Q}!31j=_v`^(R5w52CN>f-%7cZRo(YJHHU9@k@=2&;ll@|~EV%`TI{XDf( zubjD`z5dkA{eF4xGE{DZ&|q9?<-83!L2d>B%GrDwKy2~!7lp1`Kj-t5*kb~kam^TW zmN>y6n1IR93;{+cT*>6-^{eY@i%ZInfOCK&BGOFBTK4_I2<3*qaK_YU+V$=>?Y(Jc zR167jdLzrrteR@gxal@5D8CcB>)vBfWs{ux+zkH_-neODL`(u_<(erMX9O(>jGzF< z4b9xdVUd7gaKkbFBp8F%!9ZPVW_)2qi6*IGo^{=A`;XTB^4|Q7s~3ZOdv>gTa<_+VCFQvo6@+FD+W>ViBd~P3yMq9eQSUOlo{uO6!5AUbb<~Pcc#M znCzYbGc~4-4IW!jeVEF(xJ@G^KC)MK^r14@HaXJQDC3g6kbyT+@|!aNm)ifB4Mrt7w;!dCIASqf??{(^Ahkx5F8iy&9;fSh?)Is)Gds#$T4v zZIWc}Fwj6rl7gF@95Q99Em{-Nw4-}=Y`U>GA-kJK6=$g-9EApBP66F;c)|hR5I8dc zU4HCvN{6_EMTPAKi~w=XT~EF>?cKXBYLnab^3em#=;Ukfo9>Ct23(9m7_N#se`<1; zH!{JD(RO2#;fi4lhM~q?cWx>GE^>xjiU9y6vOaFZTN|sC)aPWrw(E zh!t)g85?06s*!wkO_Hggmi0}+{YR?Xcj?r#XDh_${=){?zF^Q-<%)|-%pD($h1~W zDkcPXGl#;0381EM&-X!Ik(Ha(ddS4eDvR4(YY=O;fH`0@I4fQO+SUZdr351$Y^+a8 z%Vd$UPKq37u9&P&MrOw&Wwq|egx&*3{=Q^0B4VK#6lW6Jl^)^Z?#P&inu2}%_Azpf zC3g4IFZm-PUViQS9^FPa*6bKCqUX9L>t+2B*mYnMOn?JiDH(JzKqMh3>;{X&V8jWq z?WWxJ*;ySrxs(G8umL@E(uD!HR|aKjM%LXAKU-Z^1rb3EU<6^5)FC1wPDDmWCaT(+ zB0v#{F{bHwtnj3(pWy0o%30C8==KMmc<|b16%=_jo%>F$x#>_~LZ>)%SWgK!xn{IC+0x>$G zu~mnGE9U;#IXgWyGhy_d_pko$QQ@AmCQ6;%PBbwj6&IXA0y+Z120p}xApYepuerw;YHmwtKosO#SnXl+3<2*$!Tu97|4 z_u6=5cTT@PT1Q32(3T}L`kZ=~hF}m5Zc&9aVGUwnTyV|-!7K!V9+%OjW2XpHFzsYD z5tw=7lW(m4>>+Nj+aG$oHV~mSV?uKh#1NN|n;2Q0w{Amb+b)OmJ>C2FFpww_G?-`Q zuDqA;zk1=!SGo;u$1?Z!$?0yyu|s?E3iI-FI<#%wxd&`JDmpGI3Q8Xq=w_)V2F<{s z^sX%%Vq)SFQ`+0{848x*ZfFM12TizY-M6n8RTe58HMVFkj>i4B?TbS-hANdV8bGwB%CPHc^T=9Wm zo%UDO7jL&4{B67BCU!i%b+>`BswRJD5%EYPAuWGjVc!0O1ex9{DzjBo=iId3-CGUp zn?109&e%~o{d%Wmq{a#pHrbJ}G4XL}h>ApFW^(J!yVh-TODi%l%jHU7nkfzj$%uh@ zyY?KuYg0jwE;;dTpSM-t%mlAxc7za|fx%*AunQb!)b44pA8Mr4he)E!Fi;k5VakHbZFdS|7@iqgZ|m(TfO+UqkOxO&i! zU(FeP^^@+zEVmKOv=6-g+A{}THF+Gf1DPEA_@%p2*FF4Gg6YQ`jcJPDjEEtM8b+x2FIC(^@hWkZ95*`$<(`0Vy( zRL_Ikca?1UA~vo^?~5POl*YM34Jv~$+^`4t8dP?8`{Vasa`kKH zz}#;>^G13E;BxbTZTSOo+_IE4eR+EOE;fS+K+B_r`%=<6xDDku zJtoMoxy6DmgXe8pLU1WVMRBvCvAU))Fks|FVR{+U41OT;?}i`H62zns3>vo5+(hHj z*&qJ$@pG*@4}I?Kc^j8co%ZS*_dReylTX$b7ku&QqEV;xEUHlXRi>=ie&*<|fncK< z;f;*r9uX1WDl@Ki=eV>!O_Hg~Z7V*X9v`2uKd-P;-yTCx9R)jhWZ(XVrpDN$wAj|U zk%?)-6AMo)6hYNN`hzt^P4x{COiOK>Mx-Y;vAo`niingl7~xG~ajnTnXI5iF-mg1W zt!_2++O|E;0%PDJRAz$#O7`p7W%r)Ey1Y*+tu`4Q$3VztFj9-$iO{=~6<`K;wtA2R zSCAes0j4F_0)~PTiZRF3U_A5`2j4<~QeXtmNofWH!UTn%KmfGECk2vFei#O%2xW0H z12D8QnE;5G1PlgdgEVXa3^3?x3=W z3>MOO`QM%W&|Gj04kB=2G6C4|M8=4KT)A%DrPrRDzi(${RdG#agW)x5>lE>b$Y^(Z zbmaXX&AE11wuVVsP#_?!ShynsRdsdxfY%erUCB!MTv47@$q54n_c~l!x^>mk==iwA z^z1fS?O_PrSX+N&XJvIoV{N1DhrglG-{kYe#MRf7Mz`t|;dPhno)?#x;fhZha{2_- z7_CIS;3-nXm~P|kx8EPpf55z%&)oV-KX}q@RnHJ1IA=hR%S}6WCA!^PH*QGnm<0wP zRFsUMDTK^H7#z)+%j@)l0_O}i36~H6K*}HjBr(mH3jkm#KrpTxEmA4YO(x9HKnv22 z4$8t?3pAM4FrmT8%|s+*5W)>Wh8w{I2oQ|H)PN!gFq0W@<`B39aS#^0 z0LB~?F>%2t5=z^GnLy+=&A=&lQUy!riJ z(@e8fKnqjAc2F7by#Cn!E%S2woDQZ46yo1y&@e@)3=iPovluv_6f>M57j7t}3?Z}$ zK=E*17J*<2Vitn{1VRI;YzPC4!VG$Z5I!FOvlVzKaX`Xy!DR?1)%tkaujbGihF0L3 zxNtJ;8Nel!!Gu9@%7{Z~Qe1%vFeqpZ8*p)$VQ(gxBmo1AgDEG%q+u~b0$%)$;m4T* zwBU}5&@>EA3~PgmO|3ugK+*m^M-J>dRG3$Kte~>6pt>Nh z`p^-+W_#18KW?qHtjM%h-z?m7q%NYYS_CPsOP|4)-S^eul3-m`u%IB%U%KC}+rv~H ztmy8iT)lVC)`bffzw+)EzkTs?#lE?mARN|1E};C8f$~_7s;bBbv<5kS&A-Me039|R<~9Y+l)uzB@Nh9h9m(iQ;74dT$mxdzkV;oug5DXB>+ zSOftQ1_9ijyX4FK#ZRGrZzxBKG&EPxidis1Ng4(VvnwztC?+&ugGmY0l<&1m<`^hp z1aQf<+%RvNsrL)zfIFmfFa;R}85B$~O$?m57`Z~De6rzZWFqX5KAy11tyb;3!>Z2T zysmBg9^PmpXx1HU4A#bX$WHJqT3hwq?|DrYa@u9OViL;1O7zPhTasGzp+kPcXh z89k24gubVq9~7LlFtz*W!TLi-0!K?_bzMYhl_+cCN6I}bwl@BeRGQ;>j144!SX+L#ntOReN6|-Jusm`jBCfZ7CfA$6S}P>K#V(Oz(ojaB~BZE z(d^HEtvt94sFa#CxKkv!a8EwuVMc}%;Al<&BbW*t+GJ!Jgr>5JrXvTpELlL>Nd>fi zc=zG0v)=~%mKF*Ih(l`^m=R*+a2(8N-t|v@_7fNb!ATNnuD2;#<+QUKj%xy0?#hZ}zwKO_5e*HTbK%9eUH9l^XZ197Y+c6C=ngzAdITW%OtyZoC@rzsuNE~U-D@~1f{i+F?z*&o0Re#`pbXXl22Ve=sh?&gr zBxJSjJfisM{6NK4Pue&x(5p@6omX5t=*p*vxqtcejk8bdz*0ss9-+0fmxQMj0~kcm z60#Jc0U$6J1Vg|lJnjoGyQFA;UQ)+{1}lcvaG9{=WyAX{Ui-eM?L{!-Ehv+7XA@x# z&4-i7C#1*Ci+2_GId393woA-3;HR_R@AGrU~JD#68@8FU0qs2`#UVeD-Z(seq zvG~-n{S)n)oqKi$S={w!v|<9?29Mxy*H+|b=Jrg4?)!9`=h=E7xZ z@b@ zKfhSSrxF8*9ZyJMeuSxTPv``~=Wo7b)EBrt5n7TjSl%YxTjMi%WVf<|OQStHCZ=_O zSpK1WtNc)I2lr`{CMNd1A8={OnGlRM_nrpnhN{DEmjNb(usH>^Hi*R%8cgApBuQIF z&?eIjGeY^4O?BS5HZZ(SYG1gW$BAAvsOr#$>PT^Cyh8fGylf$12o8x3^tSpf@u&_OxAz##8pQR?0ERa z2QIk$mh_Z%=T4gZ*}M(&e_i<4ZC7kvvw8V}a>;}7N}hiD>4%T5Ii-y^GRigf(n)u| z_@(cN)w@$RYO5RS8h@E)tH;Y>yw=#&y4?J@m9BA0nIAa)g1Nkc$!m-2am z&h4`{?LA}wsmY0lE9&EuQ&~;X=N~+G-BpkBxENvb&tAGGJH9+)$V9`Fvh=eD${K0L z^o3t8SeM+UZ&6ucQ$WSXCM3lrat@_PfI&l=T7YZVf<$<|{!wgY8C)SC036x5v`v?eHcyj2+ZD+$cs14GoY{Tev4Ky8|&Z0NX{R9V^1wc5utAej)=Wp-d zzhmvr9fftRb33lvv^63!%4%#JGI9KzpH^1;b$}D+W)w5sddmVx!$kQfZTw+rH=g#Vc)hM6{_AB7~PC zGSYpZuv|*C?Ub|gz~KXVht4_Y?1F=NRv_^3)#KMK`+ZfuY?W-BH>m9;S6|v?{J70a zR`eY_TYOqFXiR`p^|6B2?!NGW=kH7%a0^6gXq--1MPWi7NWr)SGi2Qp z7v|n~_p>pBFMv?c281O`w{BTFBQy7^)IO&PW-y^ooB?RQ4@knUgK2G;{o;V(Ifx$v zku*4?)dTljG-7nuvid}(v>WaZKl}8|b0_Au%gE?DS#l*5V*(1iB~#PMRX=cI92y~X zHj_*SH7PGDsdoRM9<38xp1I4nG)R`5o>o-HzL_!a&O0t^w0)!$BN>;R=xgvNr6gNs z$}P_=*x!)yBnR*$s zOG4c4%@N)|bpvB8T!5bM+OxAUSRUYZt-sM?fuO&3@0PWzm#*<^O9lP$X_-?#o@Yh% zKUQ39X#%uXHt0{lYEqmT(40$viTVZ&1fUxc^uY?k7c`X5rOPw><{E-AA)6C7L1?K$ z+6;;tipPSxD{E`uN=9w@-Zk6S9z9x8URAJnznPHLX~>|Qk>|bm&Qw>^j*Rv_GzAR@ z1O-lzszr&`ze8Myf?+zu=fH$rePn%-*xk2h``vqs2lq=$OpaQ0pgtoZaq>uO+QK7q z7OrzyyuKj_1|n_Sc0_b!dR!z$8K3{UAzIrvJTPP8=x*^zY5vB7pJ&hM*?X|&fe1JE zx)Z>;(n<(HL`>Re4DYjH`{pDQk%k9MA^2naG`?k&VNFSOi-+1SvKE2X9wQGOxVsy2 z@wUA{8BPdK6EoDGI)aEoWUr>|Hl!c41Uw)O$To=yZL&%bn}z6HCM?6bN#m3;;QPV!csE0+agIpm#qQ~@z8FiNf;{J`+rU< zBu-$45vZ)6HRGpIV}?Bc)br0gbsxC9U8l~;$4{#KH`cJe+jbP-j7b7RbERaE4Q7IW z^XdZ|md%RyFt6cCO^a)&wx9lS=h6BgXM)2910Wpz{Ks#;yXo2+rLr1iAR`uCTgA1C zi>qy@B{RCTw*IRx-^yz51xG_wpr|JJ&DV3Dy7!j6qSE%guLzgmfKxZ@uUIv)cJ11= z-@osUjup(%P>f6B%Bn6udvNPgL~q_*Wg3zzlW}iJ$+5m26J0K&%Ne(4X0-+vI6nNL zg{!3s*6yGC`7`I9e)hiITe=JzhKMvUA0VJ@G}XgJP|1CIoU&}^3o$8oLJ4qJc=%g@ zV>Jgb?S(tq@q-zix^^6Y>4y*9e&bs|<;{OPB`Gp00mIXv-FMx2^DEE1 zc)_GIKl*MKanm4!!{I052DsMp=38$3YUa05Ubto8%#p)3?%4Roedi9n<#TWbXeS(Q zG(V2ChMm9ahj}v|igrgtM@FT!N}V}#!OQcC5>rzF$9)=di7xVZ`{wqH}*nQ)h{pUV0t`$d4LZpYgDr@VME%zPRuWTYo zQc6uq63I~UUm{Xu2X4CR^8Rg;dS|7M@1E5y20y(qmV6~z5|PqmODE~jpQFZ}GjZNEG~ax=+;mFw@^{qf!5*J;kk4E-#nCQY-y{B+B#H);;7-Zk?^ zvW}6mD7Y{0x9g~6@#oLoO8(tsm(}n5lNtK=DV|J&Oafd;Ehe?MH^R6^{cc4TYho)ZWu8Ki>(+GhXjWXc4*_x$cT%K@*X!A-Ye-h?LegBPeD99AwP+=;Oq+35s@-GZvK>^h4#Nv6nJwQ_GPFMs}#mwa|ZJ*deS zY_iSYH|+4ax>OZ52*YLD3V;wT@KgklBG}p@9n{i_fEAq{m6pF_HnCQ=r}emVFWkOv zbD)evc!SEcB;dSGxJ99#HMn5V4PU?eO7F8T4}e?B24`TVRatrTNFEYfbsc;vYz3pP z(O+#^0q6wcQ5r7CeFtp{;%;ibZ-@j21Q03GfCRxNaHSQ44eMaA^p}kbW~D}_RTQ~a z?KXKvdPG)keo477T!1F-7`cwE%39ESgnuIdR8&`#(>DHzI|t-#n74Mt!o2m1H9|o# zyF~(uL3Iayd%oe=^0f5UT(|<#uB|PO&5km-a67%h3^0R*bQgm$!G($DLUs%=O~B9~ z&6Hvq1X7qb<8v3hJJ%N(ygs{AY)!!yMqDyj%qA}JC&~^UJ{ks$ID<#$#wN9oO>P^R z(s9+?-|o0+h%4i)Qzl*=fuk|;(cX+M-lXjKv~JO@`Xy%e1QXm4M5M!{Iw9ji2?p50 zGQFlL447EHa&3B)W>MKPqIEz-2OH`<=~;kwNm3`{Kj2`B4jn1}V!>J%2~a`U76=xT zg%wAtsx&AyEwk;MFTMapaw8BM8TG~!S2C=GEjbVhIWrwjXF#Y7l?Z`i8Pf^^3Z_;{ z2!gID**$0H#&t?ZefZV7A|HNPvGqtr z7F}}Asr3zI!V2-17~FySYZ0jb_`=>Ym z@WQs=-eXbww|$IySCk6|IfTD8tGJSGSM8$2csmQ`O~_u-RoxDhk`h1(Z@Gu1l!A!iFelc9@kiZxxXl-atO-DBTIQOHE{C+WNTx&t) zJYd}W)bfDWyYRp=ib^OdD|eCl#ry^7efF!>`2!`|iJNVrk(L7rA_@-1f`; zJJz-DH&P&Yc<=UWueqtZyrRCU=9%ky4Ij~={LrzI8n}|uXYVeL>)TO9XZ_s_`^#bD z#56eY*tHj|S+_3HBYU^OpmPQ;`0ndIV^aDQaexjURr6x<-igRGMNs7TSoecLcNNCC_tI&sjn0X!-O-uLHg9=$>YR(tIVC;4M?q;VJkbQsh!by)Zv2HX z1%MvE6-4(X`^X4}P2e`q3lmt2sYun4~?#B{Pmkp<1x~kRq}i z4i-&{8Vcu6z4o5**#{TD{QSh!?;q;<=_3;}Bk}Z8j|G&UlvBMWq=-s#3Xc4-LQ1np zDHqMSe$`u}XWTpBwM*JBd%pjXA1*l~10AxH>Z&R=5e2HJ-9L8iyOTe-vD?~rF1=x7 z=BkfxJa1^$&6iEGZ98Or=s&8@|By%`@_q5##d)8fQ!@Li`_D*T^uoBYIXL>$z3<(9 zHQ9bkt8l{=orG-Wz<~o_zIDg)-#%$5-9i2el1bk|BK=Fa`T|EAh5~st0p%w%}tq7FeFs9XWSDi%-wSQ6G#gXuhZK7>UX1{zz zPioj7AR@ADhk%CyL?!o~(c!m`o+DjH$`0F86f&>E^`0nP;wegAkbJ+ zRCVcjBm7L4Hnw^E&5ylaC~%>J`Pr-0}N|PQ;e9h+&7nZQCwa0OSQg zWGD^;4%ec?%qa7B5JYGepY&Er z2RJt*89X!xZ4HwHAsSr(S^*#~G(zk(e~uy$bO=EKO{6&7aOwaujZi~41C%1p6qxZ> z8$S?cb8CLOQV=|ps00m%W0z?H6mc*zh&c>^rUnmHC~kpkWkgQWvkcdgv~4g`84yq; ziE#rQB*6>?a8k_i=>m@055@`nFP)~LH3UF`aS*c^gaQ}NvziHqNkIz|wk9T=WL9Vb zmgaf|_jR!#nCApbk?4;T#wOGf1B1TLbVOx$fgc8=2 zwhb;?00lINQyAR#5BvQ8BmY;+zYodEf8<{v{~7-Or{zDx|Npf7XZZi0mVdeG7uGSu zg-9IeQpnmyGvj?T?ux=Dc(YC3k{b0t@_(8r*c^gs2SVbIW3+HA9w*F_41ne>OM?DG z(rh>Vv7{CL2!T8S7sFeAyTw=jeB)3}oIhT9!tWuHdf<4tq-92Ei_8D`cFp&1`66g} z@$r^BM8HPqvd|qhF()}gG_MiGG#qaIKUl1PUdrr`AOE2f{`IC`=(TmT7d$+Wj)i>O zem>s7ziAQsa}|SsABx!j8zofB@AxPqJgtxa9QIQFX}J|B?S*VJ)Vu3P;cc02s{^o&JAp+2nw-05GuT#M!?(vz+t_ zS7@SXg4PTnI)?CkBgP$O%jS8gSZHqwVH3k`W-vtfSPE;YPBZ=#-#*@e6BTV zh;S0e-^+0*dguY+{i|i5O2PO??$tv6A|&~*KTC-mK3S$L(agN+WHNFor5}(?+l(}n zli)1;lsaK7YM&lSi8~3UsF2@ zzXaJjtgaKda{(zO8e_W~mm+Suuk^`i{m|)OgA*h80C}cWnXeETRIWPx*8glPA zD0TklE!O$l`S`E#G5?YOCLswhV#2nSi&J^=p_Jrk+wX7iQ9?#*FfKy`I!xJ87{6FrTllSe*$9=qymPJs~61seA>*buDW8tkO4d{St&0}PEHwI zvY{0?fe7GW0^raD@DTs%i5}Om{Kp;eKPd#8!E|`2*DjiK{pII8_TbHvuexf@%I$F} zZMzH}s)%uBIE9LVzq8kzEGs$@?)<}B&%gQh%kNKrwOjvw^M6}2Y{c17iCHazN1;{3 z!n*)5D5(v>!yYHCNC|E#rTmR`6~~S)m^~|R*9Kp0naP80H{3xk1bO3JDd|bxsOY-7 zx|*6AL1YCRl%k zi6^f=XU)2`Q{Q{H+bJU!|N7gYp(7#_(iAaac)~ufFdQqitI1|G9YS6J2}W8A=1>#a zwd03(@7zB7h1cF^!gHXgrfb)(+;jmTVvMm9u;wk~FFXEUZvP81l$6{A6BMjIn3JgM z^Ow(_y03Qs=wFtsfBEBIBU9UG4%-e?9XeQEbhM=U(6OSDgNF~37F~Px8F9+!tlSO` z#IS`mb$reL$Nc}F6-|sgIoJVNR&=;+deXkl%YXN%ahKk{Z)ait?j7yA^de}+xYpqR z)#3+2mC+evN~x7AS3dXHqu1Yjq1{-7V4LjBnjTLDvOHht7@8>_Eqm%9XxEc8Pa!)-xxFgti`|oK61o(;f;rKO6G;$LNF)xslb?) z`e=?z{bW#XBeES95_*vYAJu||NrOLe+Y?v+)dK#%%c#Jofwn= zhXP|9ObQ-^s;xM%!PAic%k=lUbd7)P*{7Bmwk0XvB$jp_eW1V^P5^;iCZ7x z00|4O$RCk_(m-4>WrH+;Ae07@oNNej^H09Ne%aEp5GbBrv;6%rbEXD0Va5ABIRzlD z2J53T>jH*W4KsK9i1+`i8w0ZecL>(K^uwS9%B1TAFsU3)1d>2kq-k5MV{3q-ySJ>J zIdkmf6TkiXzh2(Ic|(ae)VAy3rk-7n7V5X0xr@&op`2$Pc~#d*QOf6)6=mg>!$ud^ zO`U&sA>zGH-}f5_p^GoO4mkzVQB2pRl8kf-B^*cBOm~A^frGhK$Lt)qRDb}Jfbpdl z_4WF1mjNj0Kq2L%8V~FhO544AAROom>pPlOy)bLm8K11$6^}Y2Crwo(EeI11z*JUc zjD0$}ZPfwaMdGYaQ!tes7vOz|+o+kh; zNSgF`r5BQzQjR1o2qN#u!nrjdu4ekcj1ppgwn0vwD(64T(a zJ2Smu>+XQzi}c6W?`$e63N)-)Qd{ml>sx1jv~1@)(e9@X^%T!8K)P$rR+q3gPV(;!yxVEXOY2<`L08&XeOmLZWvbQL^ z)EAkf{+q*)2Ky6~k;JgUZFjs(*ur205r>GW$idYs-VX(u$4;4sj&>^+Nu=A$0!4e? ze8SqjGc0Jpw!$HG);XuW_}W|bg;gE(i0G(!#twjU5e*dvd(dF8?G8&?rCf8QWBpoUomb>)xrI{=jd8~QQ<%= zTIdgbt^j!W#ZKElyYjos-gstYmG{sK!;2>V*w;vKzxx~I?T^K~}nggtWRjM|Uie)+f)&OyM)PTb;%tX2auqk@K#X_D6O zuDfQ-NAKnsk~mBQ?X4|3uyft2u_w(~vu@qU@lzEPBM!JV2$sc4Nes=pzTg7By8Wvx z-XPPjkeQ;rNP|g3TIgwA`QhK2_pO;fbKLC7<&fh){^zstuBKEfHg*2uVfEu4zx&Sx zxka`ilIh;lzjflf@4h=~WLYF4n)bESR_E6ZV;-Fux{604(KaXFuea^_)JgRgm;ees zUG_;L>I@%NkY}bssdoF|rUSjZ-gtD++HHHT{_(FSEvz4HBcV*MTChUY)>*W024-GBY_Q=2w#8#Xey<;_nfoP7N!A8fOws;nIa z9s)pcWh)&8CEO`m#UL4HcFXq7XD^yJX>`SjXDo7LeA&A@2Kri+olM4hWPe*uK=18r zD=aQ`t7VK>#tFy_VCRvWf3R=e`z2vqebqU>kccW)Jz_eHigi1d&0D-EQ$be-X8;&y zU@nS=n48x^A*1|83}8;C?k_<^q2j0CUdfOK*JhNC8qBhVlFZcw7z73}K+0He&%vEL zVaHBCYtH<6b+hMAdEtqFb$9fHYd_O`?Z=&V)N9W^d-7QqX=Vtz27*vhkoJ?>~6$m5C$Dk3N3J`VFf&K?CLZeVqsPPxa}JV-Iw9h6+pFo+ke{q{Uyl zzOwx*^QW8!)(z(OxKUf@+y`B4~j>(-n`y5B4cQx+wNA_0~Dwa14TcuwHtg(4ICOMpZLWcB?>&3e zg0nZS-cEG zVPk3O7+-ERh)XFM<4R@nbVv;ZNfM9*MT77frYi+K^P;5uCq`a07(tm z2A+ZEgwql6#yjE zBVxV1TDmchw={hA4y*{2kP;dhnlglo^t5cQzBc~<<;9^v@U3gtwd`-?ny+rm z9M9+lwbM@+J$A~$#;y-mY{@Sw?m4hx|H|hk&zuqMcUqe^L-d2vifkw%(l}g!BstK! z|JEN|J-oEg%nSVRSGSItaZ)s%XQg7Hps%zfub{v)(6h@7SjvgUdph8<{wfAA;tY^* zk`Lc|dn!ed1m>N5jIXTNlUElE*8r?(*S6Y<3V;A1nIqtUWVTJ`HWP#^XQrSlGNen2 zqErTjLrgIS&J>hzNze%rjv`3Lz<37Slr=B{hfvGkTau$oJMEh?{kSQoUKl7DmrUh6 z{p8Yt{%|U$KXTWvl5HDi%^3CiYtJZqK!eTTXs+{6L?9^y?8M*h_~oj%{&n=6iRWE* z<=NNWJZ#itkf{`fLV-Y#2Xoj!q;ph#ZKS_TIw>MWgB6iXRRx11cJ9tTx4!cE@4(<7 zXbK_$IncJ_qy0PI(Ng{K?)3c8mB&x7_UGuKaImJPM$5~MH}vk@zH;xr&XyL%%)$e` zjm@3i_uliM@|a6MeD9RAPlo2S?%%06yx~AP(iQ3N8J)AZxV&`i_}V>t_T&VDsTA6K z)PX}C1%)1;&-5DQ|9bw#V^2SB+@jO$1N(Pu*<4Up!Oh&JZEL!_+NVsP)85*?Ve@DA z-}Z;2j{D}K~q>!CPek(+&jdr_6*__=7v2{MCgQ z?%%%l^2;B%^pg2`dUXG`x2va~cG~%8zWvg_7A!u|msyJL}_~q|?FnavdxYU(B5DJHa0hyN*=xjSsF=~VcXP~z`T;v0>!`w_RyLYw{ z@THRkU)lb-l0=H6YT3P}uj}J+^~LE9Ek9>$aMV-;ieT|%tZV-G;nBQz#zdnZT zBSw!kxDS%RoUWz=Kl;{LW2(x0A@lZo?p?8RWy!D+2>2$>nf~m1f4%VHE9yr0y7~|0 zhIFWS&FHCZtM*9}8MZlhXpb``EMcbv943*7t9Zn=C@C59=%fr!!m>>;shD!-1f;`U zU@6%O4A2RH0Ic5EpS`bf`>LwKP^71K@7@;1curmz!Xa0{PjjSnxT$&kd7~!JUv%0< z@Ro9AfF!uC2ugu5_2I|wcXW2tSJtxPD((+%-L+%<)EPhi)i196_P0t3OWt|ylkZ=B zqSthKdbSFKFJ3VJ(@)kdIQb-SD0m4V$QS8( zmyelLl_TZS*Iw{xMnz$9!?IT+eZ3+T%gM>*{=BN9u>|YDfMvA5>I;{73r8iRNj-1G znzbA2tB`9%c#yX5Y@M+1l#1DNx;C#VsH^c#TWIb)kiTYo>&}MZH6>$5RPSE*c6ot6 zw=DncZ+-KLC!c+H#qz(s@((N8wROYNyu9M7kyCj^t!(YS_R1gbT+>}!nG?+S`2(SG zW2*fDJ(w5v_M=b55ib1c3m}aU|E6 zR8mT*F+S*(lv3Hjnn7?_CZco5CUCA8GC~zcR5a4U(YQts3_0R%mUwKV$ zZ|`%D{iS7p@k`IOUhtdqTKBBlvGeswb7rska6>wnV^q{ZSPbc#zyHmWP*OO!>Gu!4 z`SGUlQzzDp9S<_cPMC4>>DAMZsXEx)=&uME`H9YWLwUsl!Hka9?$WYyH^5~IAf8)3 zs;G42Kyyw5fC9YX z(=Pp)JCmmDcx?ZU`)|87K9Fu}ZX7eJfbm49Ym2AO+ zg^Qkj{DJenbpgD^5Z21qUwZI2Hy(e?q7h^3&;QAfUwP@xlTJDd2>Q!LOqnsItf;JD znBCIG;YZlJ-|AXllskHNQ)j`j5sp%Z$Tmfo%mhantP#T(82bJr`yYxCjvQFyVdOYk ze~T6N)a80Qygt5fcZ=2EC1a7cj_!eA%xm`eecWRv{az+?Pjnz*h8d(dd%+2|C7yrb z7S7rw>n|%08PwmmZMCVJT^-$fAAMlTgvm~kSTJuRWmR+PL7tUKW>y%U8edVS4 zQs100lj8?BMpCKKVAW1nRx!(oFfCp?YE1R;Y2N%= zGp`n$V71jup7`2x@0?Ws)112LMJ2_aU|0yD6H1CoCrp?zdhEE8sxmUTok(}KwzRb# zY&o!R_m*vY8yXV5tyVfNWXkU$pI`TTb)V1U@pwq%3b2$=U_xo}gq2K7je87#PH9KJuqL%v$Jb$CMO9O5Fk;ea@+;zH{H5qw0#^dHMa*Pns=c zYj+Na@7uRQibqdmP3|&`n0JyfnGMz}DdoMKI4Ao6K*h?!v+8B!_ zuDj{%;kDjPjm2h3^`@2UM~|8~a^`H1##DCl5lRt<#K3`$b<0;*4XZYT=7Pm1wRa78 z!$mOt3c|?Ad*kEP*IxWBksi4FPcK}3%gM!M1?!f7m?QP`EW9uEcDvULj$YWf`gT{2oRo4RjuMP< zsVF;U3w79QOFl&A=d0QOAg&NVPEP2$?_7G!;)N4N5AWE!ZQJ^_UXTCXw^vS|QaP-; zw!POVHbMo3K@#!)9;e4ndrI?bMojwI&;It&vZfi6y$?NbYj4-q{r!i0rcpGk(&v-= z8@D6|XwIUO;|CACyJSgOUD(U{sy99wHFEr%`3uHPn1Lj{_4@lq&l+tGm^z0M!>X*vGt$_k&??Ct9A>FQ;0OpoLBG2t}Y$r!~3G*7Nls;IW?gri4O zbk}=px<1{$C2C87<#)U=V~2uDj-ip=lezjZPHDVDsCB zU2y`)hGn7ez{`)`x@X_EUwr@izdmrw6ZgIFovVLv`HjEyaMRU^(v+zN=T8ow_ELcp zc(z=`4$s#q9Ql(tf{{UD&GL^6^SweuCr%sJ+`M1YG-x`QCKY2EyWpokFD(c@_xNA7 ztlaaq@$u}LVxX;M*=sK^IQvRS+hftDH|-i$T_?FB&ZUy1IOD;~uDNO7k~e!Jowk*J<=K}m z`rc$ix4RFm%E`@}I&H#|x0WqDChX5Cl1f(uFipT^mOgA0lm*Yr43-tjP6bR##^5h1 zqXM7W57Dsw&i<7kbBVyD0ONxsNNwd)zJCJJV zKA3K7SnVnDjhF(Fj-7eld7mwNZ{bn1w(aUpS=NbXEcAHHoV;)_6mkNUQV%9Hzpt!1 zw_Nvowf?^SeLV+K>4b`OSkW%S<8k0v=`=%Z?1WrXFa299I8C%2+Lzh+AHN%~1(0cbu*fpl-QWqZ@cS2u3hvSVjUZcfSg zMdvI&_5?kg55<|`Q&J<+6=#&;q8Wk-8NzjueX6eZf?JMOOe9*@E?K_h>F(a9ks~WA z!uC0f$J7;`HDlhyuI8ytYU?$bQEGZ!ubGXN4wlExIg#TBDAZQoN^7f8hosd5=paXS_^)6(e`=?D)L zN(s&w2+~oZpzpfdZ@=W*=jZza58u0j3v=Y~;^xMsAH4F(1wXy(t{fnZ$&Igv_lO_2^qmzjMlhVcyyo9(}u@tia3p#V0Sk=+bLe zef;XM>LM+#>U+QX<4bS6e)RFD3et6MLMlk5G%dfp*7W5M^jVd|rmWtu*YrgLmOt8k zs351Rb#FsSSs4T&qhaL+k1T`M!O)ZBtJ}Z39O*9_HuL0*DnEMZnP30@vF-b;iYjk? zP3ihQyF8>OkD2tqQ?Gn>0E%;@#H9K$b~;!)Chyo&j`{xe-(C0g?Wt71FF5S6M_)f- z{`B6~gSxIq6X}7t6X|Pg+|!g7F6c`{db$SsZMA*xfpNZ??)J8klV^Ivo|C?L?6{+k zhpz@H2|WRx!v1}cwl>Su{DGh+ubg>8kV=TO=`-^SDu}_8=QMJ&E$bxcsx)N>Eytn1G{(c+_7ry2iuoYx!ZQT|N*3CcWyimn>qJUCNDb84SwgSRY4riPW zbHAxZ}Sgurzz|`PysRERw z!{<3uLn-buJX!7rn43cm`BbJPR=)94>w%`}$4^X4RaZam!_T&lDIX@3TcL1S&N-Op z{2%^&L`C6?e}CB5<_-CiIlnLihnXW45n6%>|?ow)!?=ei3e7D_212?;17rfWnH5{je* zBcTyMwqqv^@<3ROq$4bVN$~9G4G9TOke0n})vAip5|8O0H*Q)g84Gwl{$Q>fxN#6j*lP11;{#kKe@Z57R#hVh}IQl` z$4VN5>_8&_3b*1e?OWt~|tkCZ@^!$QQxS)Lctm!*T3{ z#fvK{YKM*e;Ju~0_UtX)*^`sQ!eOJhFy9x@{CHu(o1TkRD$UQuD}_YN)1klNl+#Y00dMY#rM>eN?m!Nf|X{) zq~lLdNxvtz6i(sZhV`wj?XN%o&PCt5(UViCNJ<4)X^oHpx&csdGJ~{~wfw_D0*N8` z5z20Zgjo9KlDwc{CGAm@CnhZEfEk(x&|UDVl7g591xRz+=@%wFIjdj0_w4h&b>F>z zX*k#(DlEVLCpR(5*|%rkv8SH}ZYre!MJ}cWfC4X@!#r)#NPk|4H|*VAT2{_gXDX%_ z<&9kR>5lT+QIHmKP1ke);7m$Q3u@1P`2M=(A6)H*Q+JVAiD8p1x3VMd$uz!>!U}8VrhvLn#Sm6c%57>mOf! z;{JI1p_;0qPuFd7gjO(o>OBwrb<@VpM=xBY`E$Tc=_tkt4B)OV3M;4>wQGA6Tnhwz zj>tF6fUYNDHC5FX?B2I+^!OP>3U0~S)t<{zYRE6xKmYZwfBn_$pOI}ljCsPvWn+d{ ztzEl%(oyqgj;Vj;^|ya|`_jjjY<}^R{e4ON>$#^dx%krG-f>q|p7-*LFMZ?nS0_%H zv}*mjhC{6%yuad_%fG*Q~4Ggp=qCN4bqj4>0vY9`UVy*4bu0E%|Cw;Ij+7%TYJ&Eq#R9{c3uQ!&CIb?y-(y~3h zJ&A^f1B#U8Bow9VhF2OIPbZSeXd)Sp5yxHE2fl$nkm9{??MW z>{P0)tLL&G-cVFIeDk*5$DjR8XogfuF`-B@A`rO>uv|G#G}_XzdH=R;@4WI}qP;88 zy;l=GK`bis?y>W2wcFv4oI9I{}DW(`H4z8C~RA2Ig?_crVZ;vQ5?MO>oW8;?9 zE8_h-{JcG~Z{?2FZ+3RK78K=ImQulM2t(ti45i~96x>5-mM=gyH5({@tC*V_t*y?Evu`aP*^iU za?Mtfks?yIbihbT#mLdUvTgVFp5{ZFKK(>XwNpa3`x7DEQ#gFQpUf@m)^@gcg~GX- zVKPQ;YNH$noahT|pkH-u@{0q76`tH;=FOGJG4&ECBW({r#9;S`Xp@#Yux0(S&OMgTL!lfL)sC-P zcyY?f)l9!8`Kh`B&j^I4z9IF|&(nrj4F*ETFq8-41~W0+K^;C82nRf`Z|b z_m_O{oKva`y-f#_i;vdMK4;vMh7wBh}#s?o@w1r~O)0XzYqG=R)68Jraz z>>&?XiXesJTmW{WuRR^>?QT2t```Ymaod4$BdW($3AL51cm4CU6s zFw!!qF(wq#Nq0{nSdBa0efz1u-ha`hSC)*JzN4|@s8dgZ(p;T0L2&{x=uljeQlLYd zUVGxf2jk6$oJb!NX@gtUH6ii^4@C9SVUz1ePRz|Mjf2lS=6D_qNoW#G%SJ824P<1B z!-9yQtzqB#ce)R3vC{29f53uAC_SEJws2azI~~as`G^~a>Fw<9-LZ9dRb{Pa`28Fd zZHxAHju0?BC-1YHH2pu59bPZEzi7nh zs=9iOYZ+QCrNG?>dxQu0>h>=kV$713#ta6g954dxR8M!yrtMp&&pIlUlMe;hDWp4> zzyD^AwfDh?{sPT=@ppgl?#G+{{*Tvh|J?;gO`r0YyZGR$#Sr5m|}o0mJI;-@kj~>J?5b>hbx!L2rI>QF~W+ zDwT@#MoitDFm{4r7>qPq3gRG*TTVKbh;!4U>$+*`nrY~U#}fz!L%F&?438J4FT)0D zCm{tif^9?7VOwzGfK;|6rQ|x7ww+EV)3&3SLByC;wry*=&UB60%u#^Ps|N~w!K#$y z@#rB?a$w(w|9s@0`s$I~SLCgnFnPflnzsVv7t-cjcPrFj4xkk2(w$LJ0+Mf8zwY!? zPSRBpPQteF!sAy>TYP*=bC(&cEEqNy6aYC23V_Tg0v;yA{Ga9{mB>uVN}*B-r4&;N z%$;2oa8h6rG7a~P(fra33h10%+8>rlDHK2gN+}XV1k!|1;I8DM?ZWd0U(ighA=3~7 z?wp{I?j#3x(#aWD;%0W8xe%@D;M=Ju6BF-{qoJ(Yq?!%09ma1!wANO!_8 zkk%m$D8R8{a1aA|z&+5sAQSKmdPxb35fg$)fiY64D8v96fRG>!l0yi1bdZD{0~rur zc*B4OMgo!%Bb6bw0ZGUt7=zG-WF(W!G#zLH%1!VxSPxPll0tAU;l#iclv|B*X$M`N zJee7GB@KdsdjQQ5&^Q1{m1YFM{C{QtkbrU|R|*`1(wTr#5{v{9hg*$KAkqBfBlj04 z4=h`;#$QmneSg=+y}gc{Zd)k_t-+XJg zt~p~zm*$7P(sqQm__oL1jV4rmX>MJqZ^D?u(jq@+PBIx6P^RH!e%oVsb!F(f?(uVG zn7Th``tw4C)xO*^W#&ht5rakS{5Kb<)m%PvV=nrluE{>6SwT75JHM{DmlR5 zh;&jZvMig3Ow-_;LpaiwO0rNvktesPpnMoK-A*JN$1%7e9A-n)0!2o!n2ZpV0n)5! z%V!@wGkIju!L4h0I(wSC(kxJY+BdH8mW>4WLQ1#hFW@lJNM*s^%AL+2D7kCfw(neg z@y?w)zk4FP_WEB|jyd|^fp~TOJZK(psgxq(L(R-h__M$fcYWRyD5YE_N62h7z;P_y z~_Zi|RuB22D zjBzP##<_6hAp4yViZLR$wn>?Pl&xh-C;>o`%PW`p1OUkBbGSE^i6j2X{g(~^0&#Ev z!jWMEJlTpS`vH$_*9AQj_WkgJE8 z^~gY0?33HJ(hUM!(PvU%0?O?=9^SFaqSD|HQ{=jMb$Cqoa|M9^iVTNo1PI}{eHQ>A zNsv-Wf*}E>7%2n3lEo*Szwz(CPe+p#!@M=a%9|3#c9FW||~GyFM%!IMS zN4GY%9vW3Y&hN|d_(BP2ni0~u=2$jkl4+V_E5jG6udVp|V-HN6Fs*XLr2K-;J$nz_ zb<3r5<{v-*+#58%&xLgfA;6g+Fk)PR7?Muf&~f1%e`7XW0%!hJg#rrLN4N3}ps> z#sQE6QXE83hR1{(PjFY`G&{a~1lOw@0FzRg$#!>RjF?g&GKI)cU%KiXjAv{=^MivB zN>^i+lv}QMuSmgnU06Fka>Ogj$jR4fregpuYr zGLcGJwxbx?j!an&Dcg}uD$NmG*dm=0$&^T?6>*kKtIn={+jn*36?o?!wZJkwpMJLP zok+7UlpD9!5OGaPM@fhC_KwbI3}+oTZ1{-KoxgwRJ6Bz74MaP3Z!5^n(ep#Ta8cT7 z_vO`c(@?glb02J;KWgfv=|^?9b#Tp>S5Px!(fHG^8n$Wq$G86ItVxsSo_)bp2o@U5 z02l+4($#)ehO3sW6r=!8e&h6`4t}z$zpY8NZ%|Wnj(30HwG~(ybJu%;fG7Qynz8WuYKN=D-E1tU8FaR5~q<0j_(X6r={` zg(Bz-Lb#POcegyFJK{Dnz!{(%p#)=ma73650ZkBGr)L9-DFezi4!5-`L9nHQf&oq@DF{UU%mbh2N>iT%ieHut594GeuF?v0g4%sbTT$>>f}?t`yDt=SHrfC zUVkCr^Q44z*;U^!Dyv!Y;im&aU%9qr!syE3Ri#BWl^=Z2FmXzC{e-E3aG5d-R<3E- z-`F{-I?reDg2IAuAl%*DrAgAgrbCKL<_KZ9QOWyK zvOlc`EEN?jAyitV%BqX+dH9Zhz4qEu&#v$46<)9B`RCq<45VkxJ-T_%R+UPmqg|Rx zlN6e!L(8#KjGKj(^^@YA`};ea6p7OE%4@E<@y&Nu{o$^=rY)M$-LUM52XBo>duv9I zAf%Z{13DBV&Lt#+f=YC*UApf5*B8yJG`*TKy*B)LrS*#WWJUvn5h2UTD+$@dowD!m zV5>3vq$&HBGXh9bCdzjcPI43}22zqziAV1JP1D}@a*RIaM2(;cW`jUNG4Koxuu_oL zJ-@y7gV+8tcU+z|(5&Tzg=8Az91IRffrvx#49C&IBt(Ad-|37!Yt76N%}B#%-VMSn)*v!IgCZytiuO~Mz zf6tEH?|-<#G*xeJ=lo;l?rYw=<3L;e^ocKixb4%u9sX434}bXGU*GZf=iXfT_&+~+ zdC97{t#@=rkC{Iblzi*G9VKPCVSli>xose3$751j1Af0R8ShI+Bk6%YJ3c^GOoMHu zZKWtwSj~flF-Pq=)R9+MB)HMp(iKlSfEi1ufdT62r@i|l2U}9DT~=$4)6!+N^`txd zMSD+b-=W@y16{kD5)B9Y8xF;H?CagQ^H58Bbmoky6UUDBuvmL*=jt^LUHufb%p?Vb z9!!!Jab!<2)saj_Np;!rE<4ec5bZtv&;D!4u4qvT%8T@N5A<}Jgku&iSh4)$D}V9Soqu?A z*Y52npS)<%3FG&#d1cv>XSS^QINsS5?`usA^d8u?^_`cW`SrDzee(9R13ia$&|Y}b zIj_94Vb)RS7ua0oUji^~+4gLDi? zgTNT`=w81Hzy8{LKyv>4sXKRVE*)M;T!8>(fdt5cigU8LNFCa|?c1lFHfypI_Bf>b z30{IuM2aNHA)*X%Q1(75;wnRv$w)Cs4rru!He(WMp!dax@0&ELK9h-^&P7X)13uHdR4VJQ{0nwH?wC(l3-?DhYlwFPO+{l?T@0ca8 zy!p)I&m1*x>i9{cMoyWvz0Ll{#Xkw>RUBw)^XaA%wrh%B6ea9bGAHEcI#U`meEwi4H!Wl!6wWKI z^ySy)6<3pK5>a1E`!8 zsd#U9Z$Z9qT>WsrAshGZk0k^*f)0p#%!Fn4#nOkm`)p<^W=g@No+2f4{N9ky%bD!x z=n>qTN;=Rr4;MU{{MOk=U3K~QZo2W8Tes}b&kY&^k!bXk(?{L>iyyS_-3ygYkzG(( zTTnAi_Y`Y91kKv?#-r_rcFdf;VB5Cs-@EhO*)wKaX*=568R=*w6`e9=^qiR!rj4!R zQX~>i%2KhIh(rd;%ZfFIzrFb8h*6Wichj9f0NfCgfgDbQk-t2gbCUyz&((*&)6JYqV06M!&S8mZWy@4Wfte?EEh zkAAZF)H6_C3(~+L(~0+9e)ZNHuDR%(ap!;gn<_Liw`L-YVNxi77}uo)z}S&c-NBd9 zO)MNsXu8_B<vqS{OFa1b0-{s=C?|Q zk4bW`W_VRv=#1M+3WYVR*8c2gKmXCWlll^J?g{73JK-EHRN|0vxCoKiM)nqEzjMTW z`>OUYV6%*?%{sEd5^Ltq4C>f*JWN?k_H23OHq+|pi45#IaOm4t{kW?u`NV@y?b*B~ zXxj6SIeOkH=l|=Kx9}v!__9nnAfAF1x8GsJZVqC;nEr%i zg)2*{YsYNa*!bC+&3FIxvx59wpRPWJU(##+0$;l^^VJ~xca^2y8}M2$Iv4E(Lg?)eB^iIs?9?U+fB2u za`-e^Sd)`q0P1eryz%{4-#PV!Q+My%`>R{;Ms5CCIpu$(3_C^AVlV0|t>{L(d85d^?& z=MO)+GDmjTRpyhf5pgCJV~n^Ia6-9Wzu(`}9bL9!-Se-kDXT0yc1BTUMai6bladK* z|Dgyek8Uu_vWROY=QU+TOeG`nj_&>@oAu{}eWLb;nKNdSZYWEU?#a|F4wtgzkUv#+ zZ-S835pz3e1cIex@=tgC=8V%$9adYX8zFEv9*Ji94ieCGN7N}2vZV^eceTg=f}61qd0Ai+6j3LcH?OlgoLoS@f}o9iW} z^~ckWLTgJ`d1+C8e*X5IyAzfyDK9(!f=lkb=bo~nTszjAh@^&9`tSYCRqY-9H~joD zhr!XA$KwkbR9j;H@utflVkLE>e8rW@Ec6!Tp?${#ciwu|`4_acw6FeTbvU==k$=1# zOX22QZaeGzOJJDLb)`s>#=sm~>Y51!$&^xq!I&g)w-qE9;Oehsf;gF>;{MXuf9MO~ z(m-TKLX{E(P=*U$WSFO!0y$91ow0!e(g*f$c|1QScBs93?8M`dHxH@=jsfCefJ`;6 z{ph-@F23iXJL+c61}g-Gq{Wz~3uR|ghHT0yT_LY8?sLfdEdT|f9nQ)bNd*<}+O*`S zSDbhBoJpbF5Cy_!AO|LMEIY>+U`%6vPb!sgVzJ87lBU+?yn^yQdwL?a|NLuy9?UDx z{H`y*KSSM6X17^aWJ5|06EeNz$-DOLS~qrNl|SI|`HiI?zR}&h{g}mz6$Pt?jfzB~ zU0q#cj=JF8*Is+&Z+{zJSAEN$Zp$A#0a`wEFGLEAU_0Oj1cMaczwDxl@{((B{E0VQ z2!s^0GzkVUH=4>c4Ts#7|0Vm+P81IoT{1zxVjw8tb|w`RQv?NRH^+Mp=&@aYf8dX~ zW@sR)wm0^DwxzK<0&XC$I6pTpC%>Rz?Ps6KH0nnWYfE?i_{TTI`>mU9y`w88G_PNg zu!O@H7ipy=XTtH3T~?H5nx;}JnzWo)pCQy)$Bmgkb;8FVzHJ12-jHwHl<~)$dd`mh zu?x<-a!f^NbZzbC?T!7h)P8USDD?UbFs2}cZR+4q44gRUhR-3DOvn2B`{PLw3&;G_YckbS!>0YJaM+9jsoRl|r&a8u-=?|8z zY;I2ly(sV_-^XhzN~@|%C(j6b zY~8eBcT-DuR6z6kYle*|FRiF4udFJs$R9hYxS|@wLEMpyn9jhY5RALV^o3IYzp4F8 zDJiQkbNFRYilAUC*v=2XcPX5{{IHjM49Aw73{DEl(lj;@P4)LR@7lWIj8p5s@$LEB zx3+KJCi@0Fn$KgAV|etv+c#;E?imw?bh zc<12W-Cp1HNvB*5Pcg`^ge1m5&S4AxvitPKzY@0O8UtL=gzH0Msg|{e8dpWEeG{in zgI%f@P5|-;2CO@-x&mbV?hn6M^XY4vI1r6SD@H8n?6$lfjT|uLQP7f3N+?S=CFgA0 z=8tPf&7Obywa|-|i@%YF(GvpNpw)AHiU0bq@_!oCC;wv2QxJ$UWmjP(Vv&{)3k&`0 zUwSy+c~B$oz<}uL7Tqyw=!&l1(kL`iPnCUZpe%)&*ziE^dR+N@h zR@IHFtgWpYR-RjspMgraqxcel)3SBhPk-|L)!TMeloffU<54g;H#J??SlUkImF6}c zY_yV|VI%5yG`4Kp+XkQi#M93F)7^KK78OC*jEERhiX_p_UAuqz%U>;d{S6BF>|{!V z@*=G#oKaQmj5CgzFl9=|fZVuw*Pd;=TlVcv#=vY;6=B-s;Dq|=Prk79(Kr5CK7I<4 z7E}u9)^xHHR@90mthn9X+2e}Xk+5`414P2+zQPgnkGp^u)dK+`h;hn{g2-&QpT6{X z_&+ZJKuN9?V1Z(QlbPO^I!HmKGOfS<{rfjPUsK`T-`r9&c0NkxK@}jw!s|-ta0nN7 z;H3JS2NDBCW!2yY5CkBFBqCxO6mw_nv!DM(l?x}+c>*z^vVeExNTKocYY*N2*FXL4 z%8O6%g>sy{Vep0>1qQCEEDpi3LCJ)X6(#aq%hZ|)iA!dIl=aU7e0 zb9eZc+~nVu$k2joUl!l}H}U`HV+l7UP!2IjcdASYAdcvsJv-NVRbxpwxNpPCNJnQZ zF8T-3g7nCMGtir4f%1(929~bgT3A?^?C<*i#V1XhFybeFem$13R<8c6VQ*tPVfFPz zMvod-Gjc@cvzP>!qRcSkqmMmt`>$^7>FHq_<>%)QMB>bLD#Kwb5lb?ePA7{)UY}{~ zInY0ITAklu`8k0*Ui`@G^Sder%4Knd!@;HEZ0K-=Qmzi2B1zzm1D#3q?0NX!-@WzL zn+3Ukli7Yl=YpGtA*CG%1i*NAS6|d9d-vltX^;0CmtJ|tU3U{;WDX)Bl_b*Lu~|j{ zoW7o}pZw^@Z@%`1#}|ktl1WE_Gi6%=-7YYlqFj`h1uIK(EAqoWLo+>`F_w;Lz0ru& z^|_0WpL@nPI`-||y<^p(=EmOszIXuw8~x-gDQu+~x+NXWYmS>ZarBsRBWlNhtJSYP z=g+MkKmQ8oc|){i2Z#JLl|`BTJ3z>ws@z~8kWQ!L@pyOhCXE{sq$F|DG);GGcSu-r z0x>D2!xh`Jb;XMJ{_^c_EUp+^HxTzGG1`)0rny{d#K8pwNs106@4o%l4I4ka?&|Yr z&6x;@;P^{Ip)k{RC~`4KSpeS=h3CPqoXq>_Z~~wroh`{kcV14=$jygsUvus$&3iXb z7+rSd_kUPE|4hIKW@plPMId+U3f+g6J^%2gjqB%~@U5w*UyO8c)#}w#rq_CcI#^|< z@1Q8tdi)<&mAG%SZP$?+iq@z5mjaE~KOI7h+q`#d6%ibeX03qqk# zXxq-_IWxw2oZf}Ar!M;boi#OedS>d|$xcUS*wM0GZ<%d(x$Iip1`J48kq@4I?EP2& z7W6o|L7%iN2IlkVpk#S@WoLV=yKCTv#TP+Z7Jd_V}v75p5!f?r2%b$KW!kWQ!LLhRUah%|V-JTf4P^Du8l z*_ctalctX!J!W*}@KKP6#}oddO0W>1KXcC?WAVPruf1^N`i7Ac&+_M1fn22U5F=uT z`NeN9DyZkyL;+}i&nm>0=A{oEvqKj58UGen8FDTv1;0Pr&(%F#DRbbMs zK4v=?Ni}OOt(JeuR9MGYbJbZe*%V^Y|K<%N$w`!w*hl2XYO({+F= zMX_k4Vb7k6zk9`}`}QrWn=oDJADT6A^gIpd?fZP)JEI9R>jkj36WcI1XfD%a;A`EID@v5u8k5DOK0vReqDHH@4XQ0Elg)iEh!xU3wm<-AWC#F$n zw5xo0&D$SryY0^3Pa#sCSGtyWrzbssJnGhvjkq5|*(Az+|$ z>$5qOe)H)SL8EZtP1iEUSVnA;aaaBH^Zsbai$oGiNhV3-ia=z2ztI00JR=5EFSq&OP@)B_VylU0Vxsy&?tf zrq`4SDv)7fkbp9vgSnV+1xDaZF++g~M{1fD427mnow{w~Iw-ke{aT;L96f$26znuK z4Wu2>d4ZDm+;!W}Z@jtN$+`OaKVJX6MW-DgsF`1UZy2xQCHu!(j|kSRTWWHl(9c@zhJtKRtIg zpEaxEja99^OLp7N3ks$y(#V;DluT)k6l*uF9afb$W>{e9i+2Z$MwL~MC?9u9CRQQ1 zJT@6%%fDHgiva`yI#Wv6;EomR?M)1*v=i_k2S_tz7kKQyTzg4K_YIpejTw4MS*E)VtwE&Tu^8jK4iH*kJQ^9w6>vHBot{bB%T!d z+uE-C-X+uL9Cg*te}Uq<{(aj_k4M@L!2{cb5!CVxuwof&RJ!+I^M1W(B&uf>j3{{U z_qP@2X{Viercqc2gTZd^ZrbCGM19KfmeeDE1e6EFJ;dESj=Qhx5gmUV-O}gtj6P0@`cXAx+l+X3za_PtuHLACI`zEMXPtYpBMsu2$+e6o zoN{Gjgd4vO-g5y4a>1^UN^+*baj9E10YGyp`Z8LS08N=bODUz0mLT0@0B|!4t{4<4 zMnck$esYsv3*7jV>n7HQR)4g5WWImI{JgSIptGx&hlA1X1L4vNPpC{WQ^6#aeOV<4 z*_oGr69EuWhD;{g0#r(An)ZWRe+`j_CSA&0KvRklF~EV6Ac17^8z-JrQ5pFCE#EUm z*Lj!UaOaITE;#MPna7<1xJ*F~z#ugc2e*|{L|S%UO@X)&f^*$f!398+p2#?e{I1T{CicQOVIihsK4nIRQv5IJVVl-~Qm%+pfdH39Un2;SBF^D8e|Fbh zbLUKW{pkm4OPtZ=sZ=7d=DnA`bN=OAzM49?vtv*9@^{}l>ck6mC}j(9&3#T_;0j7I z&Y(m};~D_Xj=_p7dE(9w-hAT3<0ecyWl_5@A}McwXP4#pG{fxf>#eJ+Ywqmw<#=HC zYrYZ;y~&(1wc;=gn%+-ql5h+J#oP%)155Ko> z(?{z*crDi~-MD&p(de>ZMb!Y0mXE0qju^gw%lh(KZUoAdW(cB8=bs~kQT-olL4(J> z`|f8gz=UR|m0}=WX7Km`9BGh~w!6Ehj;tM5i)*j>&guqs!gp>04g1bd|8T{n$6VF7 z_vppP^Kdzk4+<(p#0|$G09?~RL~j2Wig8^bBWtUaLYBMu@KQ&9Eg2_+GYLqC+m0a} zE;I<8D{u$gPH0JAt{L)jBb`7x4vUDv;X*Jwo#+pFdDuiG(Vs1elAn>ul%^}8?86tH zxfTEBW@V2kSA7BC+*|OQ$6tbCPy|MR6r;~mQZr& z{rc~eIhB*tGzQoJX`Dd;LIXJ!`Jq{pMvfY$$NCR)zn5#iPd|KP%BX_Ao|Ztsc>eDX zPntSER9Hyv1uC$NjI1QaAeBzMZP(8C-+pV;TMs(vf$<|sZo2A1fu8*v)+TJHt8*X~ zQ)N|kt(&$=Px*@Yi)eS>x>d^``r}RW z$L3u1$BTV_eZ%@S4VyOY-PJgA(W#LXSVwntUB#x2pG=v15=n!T4zR)K8rcbs|6)rz zSpo{&gkq2u2pXpso_hS3Ke*;Q=PfSCp}H}%D`uZ1v^*|lL0QdGmIl76>;L6baDVk zXk5TaLozT~Qs(>N4VNu@?Zv{vd^nA89L6=qltyWj$6k5h;l7>$Lo-1Pf`gb~8u|UY z&y!7(zRIm(N+`vkfoaOIG|m78p+K6DhDDmA@l5quXodd5-`srXb?1Eh?mK_}*897T zIwc=n4PXSRN-IiX=!msJBv{{oo)-PxJsu|h{NNK%Dam7Y98Nl6=GjCX?i&JR=oP>) zh)q870c+xLraK7U1_7KH=bD5dNTE`i?Ax~VnTE|PIyP=-ZRr_^5aYbG(mQqfi2AX^ z4y@~rclJd3^uIl`;$SyRag*g0ENh7L_B-RIO}YK{+h@<2qiIY5hR%f$-1S6<`)&V? z<-3cZ!A`YqT=us|9(w#AZzpVbWE^7)v2acyM2X)AFE^vns6W>jKVd@ip)nu)EE!@fVMqcWn8TIVxuo z06SX@)q?3`uBqMp*{3nb+OYIZa$*Jf-VZ-ows79u{yyo+<%50D|8S9#I&pViDkA{n z_Fo9(*!^AYA&+LWB%CO;V&Z_mIB(igp z%&jBZr!K$97IB+qmMiOjtB3n7*?x6Bgal2-1^%azB|3XBtPs+ z+w|1aFL%XMT*6yW(j6JdNhTH_GyX@{T@lDHeE;1~Zn*hDZ^^LBuKoFUFT27KN^>tl zYD2qw|96*^P*9u^(sp;_!+*GLdJQPiQB^z2R-We0)WeTGzrP)}L~$`DjUVrETE|bC zdCHj=-TtS))lHap?lnJ=ib(gkdv&)g0AxeIuY3Vke|LLFVt4j8h}6ap-+JY-huU{aXScc0sXh|5Z&yz!94>r{DF|_OMqQU-?+nQaQ-}}SJ>dFsZe_`2&?|vTXa-J)_1}opR!_D%OARJul@KdoR80norj+`*8W%ZTpZ@7`X0+UtWIo4@uV) zfxF525KWH%57ReT=GE6fUb*(*YwxWws_VdXODfJdbBA0HcXN>q2mYs$a0bzkJp(&BI`ZXK zEw=<_F35l*p!uMDfR=$6WK2^IeuluHIF)<6C_r)rk`lIsXymzP{(1aqCx$Dlz;qBl zvL3>|^y?$47SbYS2!JFQ5bHYh!IEbd&0mmHJr>*p#)N_r&@?7pwMLnZlgY)DY1xDW zfCH=l$v@wH;(~d_6Q_U$pn27iWCZ``HCSJBw@QOJE7`Pt!wY}C;gtBqN~6IIw9cBgzT-`uh6Pj*^ByuWWchNkuRiWK2J7 z1JVI$kS-wbi1oP|Q`Yh&prDWeFnwWtG49F?qQqL9v>lJ7b&WOb+1Aq1;*e3CSJ1R~ z2UDq{%6!wGQ!{*exL}y(4Y3S^n*w7Fqy|Qi!b)@96hbo1uvLnb5(&#RbRpBqv8A2^ zsSLxD!ETdOBvV$(WB4f(IUi1*Kc~j|e`mRRb#9ic2wYk=(@jMXQb1T55u_s=hkLw` z5ROfpDV-QJDJ3b!SXMK4=mV$!v*#Lo1V@Yj4VH`*2trA6H46uc^f;XCGv}FHBU5a4 zGJN<-hhmTph`^Krvz5zV0RY-yl5%+c&v)1sj^f+^ARs{y%I4%Ur!yhA63}&mbTWpO zsWuA*2p3o8-esYPh%*3ENQ=9SL~0Oy_@Az!Y|B~WaNtrlF=WQB1d|TP5JWQ5O^5r_ za?r3Hf|SZo1X7AA2a-z-3U&tOlVLh#nFn!%{VPJ&x&J%+Ka8$}%X6e0kPbzT1F2vz z03xYz2FC&tB(UpO=WgZZ=1F9jjMIWl@U43@Gv zah~y-43Hdx0VMUzXAzXNh%pBQfJ2aCaJV~VsRkQQZl8%92!LsB(54_&rv8-0^c_Z7 zd`W%fe|-t}NxR;hb0G!eirD?hn9( z<7gU_QWDdoa+td(nSJ{i;O3zj(a*z9DvN`ZQc93U1W1P%Q}Vwlkqp8;aM%lEcvju% z2Ujwj14NJ_Od)ymngZrp#P-_7k#tuW1qD}CiX^~YE>_{PK4xsd z29qfvbZ&4k2sqr8y|6hW0Wc5=PT7Z#46Lyi|k*?ijpbbw&F+Bq`olY|f&A9U1*zZx_W_kYNy z3>PBjgHU&sHI)B&9qx0hFE}rfKw5!F@vM9}Ktg5Xe-0<>C^H6|6kVs?PT@q_4WFC{r~Rz+Wx;@U$6h~uCML?>-F{e c|L*#K0G;n`jw>;*NB{r;07*qoM6N<$f(LhK^#A|> literal 0 HcmV?d00001 diff --git a/static/images/missing-face.png b/static/images/missing-face.png new file mode 100644 index 0000000000000000000000000000000000000000..c9be652f3a00afeed1cbf0503423e229bf491d87 GIT binary patch literal 4379 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 Sklg)UVQyk&Tw&yX<9`5vwBf%1 literal 0 HcmV?d00001 diff --git a/static/images/notification.png b/static/images/notification.png new file mode 100644 index 0000000000000000000000000000000000000000..a13f65320ad6b35e19903064196164256a65715c GIT binary patch literal 1187 zcmV;U1YG-xP)l7qWo zL=2dt3lW#Nf}#=;f)G!7h~G;xo$5E;>7ME8WDW`MPrdiL>b>`O)ztJYiw*R z1&>=$not@iF#;646wGeHI@&}eNdjYyiU%6HRW(ThRtpUZW|aWzy+0@bB|0I#Q(zMq zudl_itq`E7x!^p7)PV=!7|^m7#|cnF-)gWEjKYp3u?SGW7;u9M9)V&IRc6rfAgE>h z9@?BGX96T%Lslt#F>M?vBi0=-I+q|h5g?iD>!(RL0BEVgu^X%c^S~TX1h#@JpaE!E zh~olr`_X14SrZ_M6u;LeO9j3usZ?rCDwR3_&Vfo$1u8%}SWcfoU^9@<3ymw2(asRR zD{W-SiU7f7+4vQ|n&OJU)3D6+X#mIRHxmeH8dnye9R-mkG69MoL)0>$Meg`n?F_Ra z@e#<<(j-dAB{LNkqUm~M0`%Sw^qTKO5whmFl$$VKNK~rP^1;@*RF`Hm5&`bWT)OMs zW(CRX@!OCc1o;WlG7Kfswj7B7!BzrO9C;_^AB-^1dS{6T`fS#g}{@5 zST@{xL$E?%s;ca^vaOlSf)My&1nkWcmLEli%d1A2fxg}$&O2q>HeaZKeU$AnqY%&m z%I=&}=a}}-sqYwz)i(A84(f+9@ZRU?cK*h^1 zvy(ta&qwDBre{>t{4VM}PDr?=zODmw{Nf71_bD@hoENow$0 zWhY^NRzYJC&@-Tet6cF-zUd{0dGs=rr931ka^MUwNPdMCsDTn(xe_to8&SKXZv(#K zOMv2g&|43x=I-3Z-yR|dU}l~z)HKUh00ar3+fVH=atJgrj zi9E)vr#?Bwb8E{WAXn(LjJ6k$mlI*o&n~iC1&xuog!M>JU(-K=nnr{Bo{<>71n@g_ z{te{iM4O5N42AmYaUDQOG!X z8(GKpRfGNwlmjg?TiTbE9XJD7MR6Q?Zt~l`PE?+*fWKc8YB%aCiwNgB>;(rDtNE#IO7aYbO4h94HJs~f( zN1*rQ+6M3p-J1Ld00960Sp`Oe00006Nkl34EPyS(r~YH;twu8?9}Pq@(FVI=o>xegDnYx>{^c2#lti?=7Ul z?@dr~T%g!(0=#ZbiikRa@J%FRUm+D48BRu@9(lXv2CLs}?V1P-Z)?7>kP3fllGp=) zYoPkA0g*OSu{c&pMxLua%Qk0oCxH3 zj3R>stA~bYs<*;%*hY%gZh!wy^v6>e?Mb(saQNutl68q-LIB8>8=F6 z>WwY}%Opi$eh40K6BEZI=C2Cu(*N*^HpO;ST?v>-cd3zx@Ov%8LT}tKbj&1@ zBr0$wP;RNHHvFVJ@?rZ8}UYFl-80tgzwIRNT#XT_`876{ra22oMFfYt`w z2|)P{OoiSZ>#r*To-8$d0<4*U>sUNR&6{HpXhKEek!Z&DtGNRz-n`S#5;)Vhy950Fs)0itwqSc!wozGnA%MmCo~Em(Yiim%kWWU| z5@3@SNcz>$>by06R^ZMRe&3Udt*MR#276jBMot9}_oCxtu%_*cNP0)_8sjCbF+G=$9;&9R*r1XsOOdU^p3x2t>=u8|`G! zzEZ?#I*`E4YEyhcTMFsOCu*70Z3LL9ZBdE4&V$nVbV{f*vj+)Z*4iX!l?!ZYnT-Gt z*$5O;5jqpXbHFAwS*g~`@W2V4(X#E%a)qHFOWF?bWHR<3e|tIso@5w&+0o~`?)^EXX% zmBiP?4WH`;nb!s4*(EDtnVc5Oh9dzkhsJd~|CQ@BZekWeA94v=!AI-KCytb3x!)cn zLAUUm=EoAdEPPczEBnlJZbmmJICrSr4|O0`uSRy>l~0R;Mw4JLt9lz$_~`Ty6x zqCtmvX5V6m!jP4^2*1md<9}h3=!HN$Q}YV9Cj>(6yM7>_DaYq; zEd(4*nf!`GuFJ7 \ No newline at end of file diff --git a/static/images/room_book.png b/static/images/room_book.png new file mode 100644 index 0000000000000000000000000000000000000000..1293533dc7fdc77c0655455c6c2e184593334c9c GIT binary patch literal 1131 zcmb7E`%hB`6h61*7S@NtmSW38*kGH0FnK6r!*VATS{p&I6H^AX+h9D#bE1TyT){CU z=#cm-&zlNT&=dw@0R>CUHjoawF<=2E47E^dk+1?O&vpNS`{A4~-0+s{G zyrGxL3Owr$Kv$@yb;l79XP}huT62&>k9|37LIBoh=X-}6NT8ag(rY+O0PXSVwRNLt z-q?0EtLjx_aG)+S`Jht`$4l_l#{#s&e!JB;W6)O4n-=xYvil!)Ass!nm*Xq8_I4)f zJ8g>yCtUeUrRnMhyD=~@|Ma@dtKnOj2gpVG%y!P+?A=$48*-%OwU0;?nEY zfR*?ATR~p;H6JqY-eHs50G#0p_d z8TyFk#xSj3?@fJbm23^LW(_!JGb_aZYy2q+SaSjU8G=1x3TSgKWmHW=++ddljdptJp-!TW1(O+3oFu#qodi)iFOjr(-k%m5<39!GScpot+Vk z{!V+an@`&_^8jh(P}5*KZFF@ZY+10GkHKPhRi{lV$eD9lIa_(hY-wT`gz=5>C`hfLen&v1k z2??Og@n5LJ(K5$AZ>*;0xq2tGk^?Ax!(`lRWYNFCPUOtQv?Wy4C8B%MN=CYy=b`L{ zPROKa>SyRgIt+qOR2A|eIfJ4(x3XXwAlkQ+gkh)*?ei2HFwi*i0>0A^&vHq)!UHm# z@O2nJ_cxu;-8;WWgr|`_aa)Y0S)qAi!%5_bd+?Wq2+SH`xN%mA>(_NBZ|hzJbv|j{ zKXPiED;&73zzIJ2?NeGEV@Z#i \ No newline at end of file diff --git a/static/images/room_line_2.svg b/static/images/room_line_2.svg new file mode 100644 index 0000000..398df4b --- /dev/null +++ b/static/images/room_line_2.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/images/sharer_line.svg b/static/images/sharer_line.svg new file mode 100644 index 0000000..94de0a4 --- /dev/null +++ b/static/images/sharer_line.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/images/sharer_line_2.svg b/static/images/sharer_line_2.svg new file mode 100644 index 0000000..1421a45 --- /dev/null +++ b/static/images/sharer_line_2.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/images/suc.png b/static/images/suc.png new file mode 100644 index 0000000000000000000000000000000000000000..6e01b2b25d91e0cfe172bb5680c89334e5470eb1 GIT binary patch literal 2847 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 literal 0 HcmV?d00001 diff --git a/static/images/task.png b/static/images/task.png new file mode 100644 index 0000000000000000000000000000000000000000..86e4daa9b86d11f26d35392232bdc7b35df57543 GIT binary patch literal 2389 zcmbVO3sBQ$9It|%ifpJ;w&89en+m!#Y5Jnk>S&9CT0|a#Zd1}ErBT|HCfK5)lY#FI zPKTSyWO~y%CWyC9!52C`@qzSozL-owoB~rpPY)kc_k~AKcj`QIm*mU${l4G-_kVo< z%aWMrvHrc^=`E2+{G%d`vEYq~cTXvJCU(EK2)ueZBB$^YiC=&5?j~7N@Rmf<;~E>E zBqW(85EN&Vku+y!WNw=Spe2%#qumaYn#l-|nMq;oI=E$51q`vY4o*~=Fq6Z;SlP(g zP9|=4bUZbCCZ(m}(W9V|ZUPY47=eV`wp2S$xOH$lF9F8lGzvrQ5Mibc4i^nVNv0Uc zz&RO6B~v4mT!}*(txT@Qw7Bv^2*>0a6w{z`1%k;5Oid`XQ0D~$Yfjoi#2UwR+5%rX z*eVDP0!3Xem&~P*an2M}uGMN$3`cPs0SJW8unVLcvGebDF&G)1aZvt0aotCI;@<) z@mB6R)ZXQ%41my@OkNw$)MB%FP4Gg*EZ|0GK%R-_<1-u#8q4rpx|3oeW&xS+i{3a0 zgOecz&Kb{fsa=VR>5>c?3}Rx!ppZn?PIE3k^oc!;krWsmjAOVO!Egjq#LGeAa6+XS zj)f5z)&VtfG;7ItCR9zRR8K)c)zG9s{x6uO2n*-5k-%rxMy4>R!=3^|-bfM#E|qfv z!$6(l$@wUQA;!sB*i^8<$BxxQQ4t2UT&q?ixJ=$I*JL81?7TqQDJIIOgF$>`EK3s> z2B#@p9)_qXl^n6Cl`6!HDU=9~Db)&anbj(D*M1{MrHfV2wVww26`C-MmI|X0il!Mv zqf}}Ul458?tztAviqdM8YNl)dL?;VQA({HhJmT3D%ZG?$d63wQ&eIdeq;-x`S*X2Y z2$B*{f)1v{5@2Y!bDDid1YXXA4qBI$0i-Xeiw+piSp*m9WWrNGv|gt4(C6vr$yqN} z|8n_zf%+#)^%d232A8su_7ny*R}>cgLB%%Iks9>BS!-W=qGff#K_3){-UbXlye*uu z18OH|(8v4Q5+o9zH=>N;@zw>`YfPKJN*Gjm)3Z1)C=f9&-8??aFK4-LcwSjh%b1Vf z{AR1~0D8#6njvSif&yi}^;v#_IfH)*nLcoD-remzKMh#`T{(98C)QU#>4VD+m#P|9 zEBKoQ<$O!6yrLEJXg!ZJuC$Hdr#<4=O-)F+zna}M5Sz9xs8RKMgT8q3_^qD(K}pz@ zEV%ko_Zx@u5o&u;QRUd*UXPEfJ2z_8g`%QEN(}FjU0HdepU>#%Zu_r)>93Wp8luVk z!ZiCp?`sop_t72ScO~SmX7{O}>$y{Ytl4+w)JMb@vgOseb=4pAdUsii(xXRyCTG;; zH~!OX3~Bys{E2(lZksQnw8#HcMqowqnF|=LHXTY zg+uO)Z$+jpZmw=PSeDP=51WGPbn6pd+t%~FdW2jvN4|7dR_@9~(oFL>PAZQj1~M}Do?_Ri4rwLARgo1w&j5{k1sO1hQhrt7!gx9qtQJbB5MOmr<@xA zz$COJ^n7O750LAq3fo+MXKZufq76IWPAaI~5mz&8%Ol-^^8Mw~>Pv;2|Jj(_EcA0J zLR*duSW${(W`qv`k+*ekVy9Z`u;yJWa zQyl4EkXyaz_B_{`*2*9E=dAiE?(V~VBgq|G8y`wCA1&Mz-n{#4W&Og^Pkgd%2bbvv z&XX1%+z{*YYm$3y+rjMO13j+GCSX@v6Q{0L3&o~mZ38^D`ZKPP-G#K!#}8Jn;KU!F MsEBA|i9R{&U)3de`2YX_ literal 0 HcmV?d00001 diff --git a/static/images/temp.jpg b/static/images/temp.jpg new file mode 100644 index 0000000000000000000000000000000000000000..eb93ca60e9a88a3a26aa259d15dc8548b47f1b56 GIT binary patch literal 5857 zcmeHK^;Z`s z&Hx|Y*Z2Ml-!GoE_Sw(cYoA=t*?XT@BLhteQWjDG06?LwrEUTM;2B-xbP}TLo@V4z zF91NUYwqyZfFfr$&Oi;oNbP@mUvM<^S0DK-Gvot;(rIcaMn>bSZI&uUAbl?e4 zpSM9|Jh^~hbudtHC?%2sXbF8-K#4hIhbjP+P_0%j6~K5XM}L@6TeMnPmmEJbAo-@t zfKS@ZvcW@}EPX3-vNcISs;M-a4-ud;gUb-~-C3F9TUZQxl>AF-fP`$%a#PcT0O~ST z4~nPi)VfE^Zc3YuIDPS_W+~l+OnvC4fw;FFoQA30S%;9)ACQbiw!tJST{Ey)ZBB3vlALsLRADkMOWVp0Z zCLK-b_o+$3mmV>zq$*`(=s6$i9o5#D0!Hepy1Bdgv_+^W$>P`MdW4V!p7gV{^B~T_ z1Q(%Swl3&7(oj8wh`2D#W73`tLTDsO44CWrz;FTuc=pYm5y$)Fb1}C?Cr?MY5?09~ zaO>x0D$UX&8uqr?Ia2?z_3$kXXD{r;V#I$yf1Y*CH?o=IyoG0-+LM@-io3^kNm;YW z5)W>17RXI^Gxqfh`6)0pepnajmt%5ycfrRyO^#Q7iR!Pr7<*ie1 z(eo$LfkxIM)dzocWkiT{;$4PQ^468U6yzi$kv(U@e$Q*=r}hqKas(*WJrYslp>b+3^{pD zqhC-~TQPZ2R!?3+#;NL8nE4z(-+bdZz+?S%;4PE#FMc9A{8-6G#r^o;HG9-HSry$_ z=Th{>;Zi;-^^10ZdZWQ6_hSBC0otpZPSTsu^Otc}#TS`mi?mOgzlSw4nnn*bQr1%K z`nYUH$6}Sog_E2F*V3J%E>n(IoKf9VMzhK6g93pBa~U2N7%i|RIK!UatrjwpC_nvi zH3a@DIP7@*oC_;I`|8po_TFboJD2*D*}z?rX_C!ZpXwX#{RujUsO=zbOKY{|$Bu`N zYV2J~I0^-GH$DuTJ9{vD#{d?6HdS)q+L_Ir&Bfs8xG|N5dfizDkFtt3_T$&&cL5Zy zFrMw~=zrX8dAa!!f@Ht}!)Fe=y1Keonv#A1c6}ojI?m)=M#Bpzod9DJzPH!#WTJIJ z1gGgn5pw!eOh9ov3giz0tC##JLLeuBI#fD|oUdzBd{ve)!p)8$lS)UK*^KgG#E~7{ zEa`Kof}N5pfo7++H<1-VMwh=gV{N`C3h!6Mi|^u4PTt74FVqS>O!dmU)clbz19*U1 zOtcZaJQZ3*-0HjocO8KyuTpt-lJ99ze4ujEFyKZe8>~yBskiRi@Dv!4gH;elYF}yD z4g+#u8}=f<>!OZM4O)R--LN&P z!!R7{OC1r;SsHl~4^>*O2$6Ur)pAY`em3shSHTrIs01zEZR(mBPj3((9Xv)nRyT$< z=BS6R$6(E24G^n7$upPSs+G)3DOg~tYN0u=FKf`Oy3H4AWb#n#;WHCbQypVkA$mcu zz@CY0so(vrtVx#-vUAW~l>}bQfcU`hz{0@2b=`GOv`ZXOZ`|7b*dj;cjR(^v+X7{R zCjwrnX=(atOKC-EghQCr8KDEPVj0fptSGKDu7*_C2^y#FR53)EMkmw&UN)*Q)vW|c zL}eRV>(mtHzgK)0W>iukTmAtYSm_JC17{ zbc|8t8S;>8ifE!V?{XMRtqsMTH1qg}`kytIG#@q3_$zHq9O3=?aP)9fVtZ+(|LEya z(NWo!*H@*Q6)6+ zUn-}!^CiB`_Xkz_BaS3k-&1t+EjUMvI$3_5?vR z=}~#kvCy#|77uHIji!{Pw5PmJ8BYn)%t+CG^V(3S$M)d|o3Ed?tDw8C*P?x)*9)?U*v+$Hy$^kw7I9~{A1K|ZaY z0{jD~+8(q?1;04UJoOH#4COe>K0}8zU=rERn@Jf{=nb4Yi zDkFbG#ncfLazc=C<2IeA-p6d|(6uw|^OR?N?0MCaS>k8PLR=D}{*Sg94S374#gqCB zs&sac9~#{oK>_Wp;8vS<#*W;pyGwW4IPVc$FGD-*+wuzikEzNTbh12=0VF zcRWtm?aJ-RJ+~@Z{JQ8|SSn&UE7|Kh^h+?0Th2JP+`Y2@>$eBk-omxLK&|DT*3yuB zr#vgd_31e7K(p`GM&>Aci_ahNrzA?r${NP&^6CTn;Ga7`uQ;!XH;G%iWQ}Ai?W}ri z?B4TDl5z93KxU8L%U@6cxh{{LrJl`UAfRV=g+M_qoIWbL_4bFYYyBMr7bcePEx3i7 zn!fn1mfk<*?s}il>%a)J#MPue3Mw3_uYSKfOuPSVE;x7=-_Z=%GAZSp~R-F-2*gx zXAT=;yWP%;RXb_muwyHibM>j)rrtAh!=Dr>D(n!2*H;NPRlsG6n-IP5pI_{wyX6ux z*(&5KL;dDNhw9fHBKpY^sdB0FHs!K>&^|ls(=BCh4XoW?d+tcH2c0iwb&8jbiH&n8 zA^rCU0uwQ#j7*Fypk^Bn*B5R|zgmV5qGhe*ScIFbpEU1=HI?{UA?xobJ~FU5>Im9k z!Or*Y(9Fnr^{h1d`+gp+wQRLiXz=yyXnx?0#4H7#keuioRIR`Q>`?E{sdALITdZ0V z6n{ZxF9nV#miia_LHX+nXOq^r)bo#PS%>g!jDC<5 z%~s2HIt+0(kG}V7p{;ANONB;rB>95WuI~NT7NB(*2#{a~u*eq}_YIFjK0pV?tHlT| z>Cy{moOk-|HB$U0RaAg?RWq{v>SlnkB`B%{@s$U<@cC>G~PSBe?9Pw-r@g?0qMV8rFEz3 zuhk82EpuN0fZ_IU0cxA@qONUUwAEEi1Au$86E5kYY(%KN3ttU6*I|Jg30X6Z5vG)w zWb=t?-kQPr5yzaY>=<6!WSRw)Vs<|fct=G;ON9K2rNV;$Wnj$7%t77-rfbK2nIVChe#UG}NYnaM_v)&B;L5kEN5gm8 zAy+p0nwpx!p;*-3Lc?1n$YqEO6*+k-2H`$4bf-P+!eXD8n79ZtJ8KrW($%FBczJ%b z^D_(r=~zrmOw7PeQC`m}I4*UuxjPfjD%ITn*vkvH&d*bXc6s*y=6hj0~GK8&#kU3Ib=^d2%m?FnirQGq7O{91h>pk~!Gl zPsc4TS~Wq=&`wPq!6%+gN_%y1_=Egg%*=vF?8!mFaon>G1Ol9IYi1^Jl9QA3v;AU6 zA>_1feIc3=WRr@#r4aNrK^=)eAkgg_*m^kC9%gOrap2X^kj|h|==sOR>%+A!Hmtmu zKbwQQ{0tp!S~&0u3~ag{Us6(n4q503wXwFo2Ma*2YX`O;?i>f=PJISpFjz(a<_d-x zpSnCUl=JfNNIg*qK)q{)ZCRqT3JO5uwoT7UavK^NQf7`8TVBBASHf(uxb1IM=*x|R z;4(u@=$A9Mb|u+^g%!imlhGB$D>fqt8CK>uS$>n`Wj+VK4%t5#h*ua6q=&}R{b3Ke z0Q`X$m+VogiUUME^^OaI#aza=4}Tzco}C8Iw`m ozx5RfA$d8qUhY4|7AH!n=W}*X@GEw?--Vy{eFODcRXgba0i!}FrvLx| literal 0 HcmV?d00001 diff --git a/static/images/time_line.svg b/static/images/time_line.svg new file mode 100644 index 0000000..3303038 --- /dev/null +++ b/static/images/time_line.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/images/warn.png b/static/images/warn.png new file mode 100644 index 0000000000000000000000000000000000000000..b6bc4cc023584f7965c0d63484b650efe1c9c013 GIT binary patch literal 2984 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 e@WBWFEBptP%MuQ8-_EcA0000 { + commit('setSiteData', data) + }, + setDeviceData: ({commit}, data) => { + commit('setDeviceData', data) + }, + setUserData: ({commit}, data) => { + commit('setUserData', data) + } + }, + getters: { + getSiteData: (state) => { + return state.siteData + }, + getDeviceData: (state) => { + return state.deviceData + }, + getUserData: (state) => { + return state.userData + } + } +}) +export default store \ No newline at end of file diff --git a/store/watermark.js b/store/watermark.js new file mode 100644 index 0000000..13fee4b --- /dev/null +++ b/store/watermark.js @@ -0,0 +1,212 @@ +/** + * uniapp全局水印插件(支持排除特定页面) + */ +import store from '@/store/index.js' +export default { + install(app, options = {}) { + // 默认配置 + const defaultOptions = { + defaultContent: 'Cannot get user data', + width: 170, // 水印宽度 + height: 170, // 水印高度 + fontSize: 16, // 字体大小 + color: 'rgba(0, 0, 0,0.1)', // 水印字体颜色及透明度 + rotate: -30, // 旋转角度 + zIndex: 9999, // 在哪一层 + salesSupportPaths: ['/salessupport/todoList/todoList','/pages/playerDetail/playerDetail'], + }; + + const opts = { ...defaultOptions, ...options }; + let watermarkEl = null; + let currentContent = ''; + + // 获取当前页面路径 + function getCurrentPagePath() { + const pages = getCurrentPages(); + if (pages.length) { + const currentPage = pages[pages.length - 1]; + return `/${currentPage.route}`; + } + return ''; + } + + // 检查是否为SaleSupport相关页面 + function isSalesSupportPathsPage() { + const currentPath = getCurrentPagePath(); + //console.log('[Watermark] Checking path:', currentPath); + //console.log('[Watermark] Configured paths:', opts.salesSupportPaths); + const isMatch = opts.salesSupportPaths.some(path => { + const matches = currentPath.includes(path); + //console.log('[Watermark] Path check:', currentPath, 'includes', path, '=', matches); + return matches; + }); + //console.log('[Watermark] Final match result:', isMatch); + return isMatch; + } + + // 创建水印元素 + function createWatermark(content) { + // #ifdef H5 + const canvas = document.createElement('canvas'); + canvas.width = opts.width; + canvas.height = opts.height; + + const ctx = canvas.getContext('2d'); + ctx.rotate(opts.rotate * Math.PI / 180); + ctx.font = `${opts.fontSize}px sans-serif`; + ctx.fillStyle = opts.color; + ctx.textAlign = 'left'; + ctx.textBaseline = 'middle'; + ctx.fillText(content, canvas.width / 10, canvas.height / 2); + + return canvas.toDataURL('image/png'); + // #endif + + // #ifdef APP-PLUS + // App端使用CSS方式创建水印 + return `data:image/svg+xml;base64,${btoa(` + + + ${content} + + + `)}`; + // #endif + } + + // 更新水印 + function updateWatermark(force = false) { + //console.log('[Watermark] updateWatermark called, force:', force); + //console.log('[Watermark] Current page path:', getCurrentPagePath()); + //console.log('[Watermark] Is sales support page:', isSalesSupportPathsPage()); + + if (!isSalesSupportPathsPage()) { + // #ifdef H5 + if (watermarkEl) { + watermarkEl.style.display = 'none'; + //console.log('[Watermark] Hidden watermark (not sales support page)'); + } + // #endif + + // #ifdef APP-PLUS + // App端通过事件通知隐藏水印 + uni.$emit('watermark-hide'); + //console.log('[Watermark] Sent watermark-hide event for App'); + // #endif + return; + } + + // #ifdef H5 + // H5端使用DOM方式 + const userData = uni.getStorageSync('userData'); + //console.log('[Watermark] User data:', userData); + + const h5Content = !isSalesSupportPathsPage() + ? opts.defaultContent + : (userData && userData.userName && userData.userId ? userData.userId + userData.userName : opts.defaultContent); + + //console.log('[Watermark] H5 content:', h5Content); + //console.log('[Watermark] Current content:', currentContent); + + if (!watermarkEl) { + //console.log('[Watermark] Creating watermark element for H5'); + watermarkEl = document.createElement('div'); + watermarkEl.className = 'global-watermark'; + watermarkEl.style.cssText = ` + position: fixed; + top: 50px; + left: 0; + width: 100%; + height: 100%; + pointer-events: none; + z-index: ${opts.zIndex}; + font-weight: bold; + `; + document.body.appendChild(watermarkEl); + } else { + watermarkEl.style.display = 'block'; + //console.log('[Watermark] Showing existing watermark element for H5'); + } + + if (h5Content !== currentContent || force) { + currentContent = h5Content; + const watermarkUrl = createWatermark(h5Content); + //console.log('[Watermark] Generated watermark URL for H5:', watermarkUrl.substring(0, 100) + '...'); + watermarkEl.style.backgroundImage = `url("${watermarkUrl}")`; + //console.log('[Watermark] Applied watermark to H5 element'); + } + // #endif + + // #ifdef APP-PLUS + // App端水印显示逻辑 + const currentPath = getCurrentPagePath(); + if (currentPath.includes('/todoList/todoList')||currentPath.includes('/playerDetail/playerDetail')) { + //console.log('[Watermark] Path matches todoList, checking user data'); + + const userData = uni.getStorageSync('userData'); + //console.log('[Watermark] User data:', userData); + + // 组合用户名和用户ID作为水印内容 + const appContent = userData && userData.userName && userData.userId + ? `${userData.userName} ${userData.userId}` + : opts.defaultContent; + + //console.log('[Watermark] App content:', appContent); + //console.log('[Watermark] Current content:', currentContent); + + // 总是更新内容并发送事件 + currentContent = appContent; + //console.log('[Watermark] Sending watermark-show event for App with content:', appContent); + uni.$emit('watermark-show', appContent); + //console.log('[Watermark] Event sent successfully'); + } + // #endif + } + + // 初始化路由监听 + function initRouteWatcher() { + // 轮询检查页面变化 + let lastPagesLength = 0; + setInterval(() => { + const pages = getCurrentPages(); + if (pages.length !== lastPagesLength) { + lastPagesLength = pages.length; + updateWatermark(); + } + }, 300); + } + + // 全局混入 + app.mixin({ + onLoad() { + this.$nextTick(updateWatermark); + }, + onShow() { + updateWatermark(); + }, + mounted() { + // 监听用户状态变化 + this.userWatcher = store?.watch( + (state) => state.user?.name, + () => updateWatermark() + ); + }, + beforeUnmount() { + // 清理监听器 + if (this.userWatcher) { + this.userWatcher(); + } + } + }); + + // 初始化 + initRouteWatcher(); + setTimeout(updateWatermark, 100); + } +}; diff --git a/uni.promisify.adaptor.js b/uni.promisify.adaptor.js new file mode 100644 index 0000000..47fbce1 --- /dev/null +++ b/uni.promisify.adaptor.js @@ -0,0 +1,10 @@ +uni.addInterceptor({ + returnValue (res) { + if (!(!!res && (typeof res === "object" || typeof res === "function") && typeof res.then === "function")) { + return res; + } + return new Promise((resolve, reject) => { + res.then((res) => res[0] ? reject(res[0]) : resolve(res[1])); + }); + }, +}); \ No newline at end of file diff --git a/uni.scss b/uni.scss new file mode 100644 index 0000000..9c2ccc4 --- /dev/null +++ b/uni.scss @@ -0,0 +1,105 @@ + +@import '@/uni_modules/uview-ui/theme.scss'; + +/* 页面左右间距 */ +$page-row-spacing: 24rpx; +$page-col-spacing: 18rpx; +$page-color-base: #f8f8f8; +$page-color-greylight: #f2f2f2; +$page-color-light: #ffffff; +$base-color: #C39A4B; +$base-color-light:#f5ebd9; +$base-color-danger:#c04b41; +$base-color-active: #937438; +$base-color-hover: #C39A4B; +$base-color-notice:#f5d9d9; +$base-color-disActive: #8b6d35; +$base-color-approval:#fff7e6; +/* 文字尺寸 */ +$font-min: 20rpx; +$font-sm: 13px; +$font-base: 28rpx; +$font-md: 30rpx; +$font-lg: 32rpx; +$font-xl: 36rpx; +$font-12px:12px; +/*文字颜色*/ +$font-color-black: #000000; +$font-color-white: #ffffff; +$font-color-dark: #333333; +$font-color-base: #75787d; +$font-color-light: #909399; +$font-color-disabled: #C0C4CC; +$font-color-spec: #439048; +$font-color-highlight1: #e34327; +$font-color-highlight2: #C39A4B; +$font-color-approval:#E9DABD; +/* 边框颜色 */ +$border-color-dark: #DCDFE6; +$border-color-base: #E4E7ED; +$border-color-light: #EBEEF5; +/* 图片加载中颜色 */ +$image-bg-color: #eee; + +/* 颜色变量 */ + +/* 行为相关颜色 */ +$uni-color-primary: #4b86c3; +$uni-color-success: #4cd964; +$uni-color-warning: #f0ad4e; +$uni-color-error: #dd524d; + +/* 文字基本颜色 */ +$uni-text-color:#333;//基本色 +$uni-text-color-inverse:#fff;//反色 +$uni-text-color-grey:#999;//辅助灰色,如加载更多的提示信息 +$uni-text-color-placeholder: #808080; +$uni-text-color-disable:#c0c0c0; + +/* 背景颜色 */ +$uni-bg-color:#ffffff; +$uni-bg-color-grey:#f8f8f8; +$uni-bg-color-hover:#f1f1f1;//点击状态颜色 +$uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色 + +/* 边框颜色 */ +$uni-border-color:#c8c7cc; + +/* 尺寸变量 */ + +/* 文字尺寸 */ +$uni-font-size-sm:12px; +$uni-font-size-base:14px; +$uni-font-size-lg:16; + +/* 图片尺寸 */ +$uni-img-size-sm:20px; +$uni-img-size-base:26px; +$uni-img-size-lg:40px; + +/* Border Radius */ +$uni-border-radius-sm: 2px; +$uni-border-radius-base: 3px; +$uni-border-radius-lg: 6px; +$uni-border-radius-circle: 50%; + +/* 水平间距 */ +$uni-spacing-row-sm: 5px; +$uni-spacing-row-base: 10px; +$uni-spacing-row-lg: 15px; + +/* 垂直间距 */ +$uni-spacing-col-sm: 4px; +$uni-spacing-col-base: 8px; +$uni-spacing-col-lg: 12px; + +/* 透明度 */ +$uni-opacity-disabled: 0.3; // 组件禁用态的透明度 + +/* 文章场景相关 */ +$uni-color-title: #2C405A; // 文章标题颜色 +$uni-font-size-title:20px; +$uni-color-subtitle: #555555; // 二级标题颜色 +$uni-font-size-subtitle:26px; +$uni-color-paragraph: #3F536E; // 文章段落颜色 +$uni-font-size-paragraph:15px; diff --git a/uni_modules/lu-data-select/changelog.md b/uni_modules/lu-data-select/changelog.md new file mode 100644 index 0000000..10a934b --- /dev/null +++ b/uni_modules/lu-data-select/changelog.md @@ -0,0 +1,120 @@ +## 1.0.62(2025-11-23) +优化 +## 1.0.61(2025-11-23) +优化禁用逻辑 +## 1.0.60(2025-11-23) +优化功能 +## 1.0.59(2025-09-11) +添加手动弹窗方向,direction:up、down,不传或者传其他值默认自动判断方向 +## 1.0.58(2025-07-14) +优化兼容性 +## 1.0.57(2025-07-14) +兼容vue2小程序 +## 1.0.56(2025-05-13) +提取公共方法,功能未变 +## 1.0.55(2025-03-27) +初始默认列表报错bug修复 +## 1.0.54(2024-12-23) +修改bug +## 1.0.53(2024-12-23) +修改bug +## 1.0.52(2024-12-18) +优化 +## 1.0.49(2024-12-01) +修复bug +## 1.0.48(2024-12-01) +添加搜索防抖 +## 1.0.47(2024-09-02) +修改bug +## 1.0.46(2024-09-02) +初始化数据 +## 1.0.45(2024-08-09) +添加vue2支持 +## 1.0.43(2024-07-28) +删除边框阴影 +## 1.0.42(2024-05-18) +删除注释 +## 1.0.41(2024-05-18) +删除无用代码 +## 1.0.40(2024-05-18) +修改bug +## 1.0.39(2024-05-11) +删掉多余代码 +## 1.0.38(2024-05-10) +删除log +## 1.0.37(2024-05-10) +修改回显bug +## 1.0.36(2024-05-09) +修改默认值问题 +## 1.0.35(2024-05-09) +修改回显bug +## 1.0.34(2024-05-09) +修复默认值问题 +## 1.0.33(2024-05-01) +添加开启虚拟列表配置virtualList,大数据渲染 +## 1.0.32(2024-04-27) +添加是否显示省略号配置,添加选项自定义插槽option,具体看示例代码 +## 1.0.31(2024-04-27) +优化微信小程序显示问题 +## 1.0.30(2024-04-27) +优化代码 +## 1.0.29(2024-04-26) +修改截图 +## 1.0.28(2024-04-26) +修改禁用颜色 +## 1.0.27(2024-04-26) +添加多选模式,选择项的折叠配置 +## 1.0.26(2024-04-26) +添加禁用选择配置,设置边框,单选模式设置选择框高度 +## 1.0.25(2024-04-24) +添加git地址 +## 1.0.24(2024-04-24) +修复单选模式,回显数据匹配不到报错的问题,@qidaichongfe**outlook.com  感谢这位朋友 +## 1.0.23(2024-04-19) +清空bug修复 +## 1.0.22(2024-04-08) +修复滚动条问题 +## 1.0.21(2024-04-08) +修复bug +## 1.0.20(2024-04-08) +修复默认宽度问题 +## 1.0.19(2024-04-07) +添加文档说明,修复过滤输入框点击多次滚动的问题 +## 1.0.18(2024-04-06) +添加change事件返回数据的格式配置,changeType:"objectValue",表示返回完整对象,具体看示例代码,修复单选数据为空报错问题, +## 1.0.17(2024-03-31) +添加自动判断弹出位置,若底部空白不足,会自动切换为顶部弹出下拉选项,防止遮挡 +## 1.0.16(2024-03-31) +修改demo注释 +## 1.0.15(2024-03-31) +修改注释 +## 1.0.14(2024-03-30) +修改为动态获取元素的高度,添加回显滚动动画 +## 1.0.13(2024-03-30) +修改文档 +## 1.0.12(2024-03-30) +修改文档 +## 1.0.11(2024-03-30) +修改文档 +## 1.0.10(2024-03-30) +修改布局 +## 1.0.9(2024-03-30) +更换图标 +## 1.0.8(2024-03-30) +添加多选功能,长文本显示省略号 +## 1.0.7(2024-03-30) +添加选项是否禁用属性 +## 1.0.6(2024-03-29) +更新文档 +## 1.0.5(2024-03-29) +更新文档 +## 1.0.4(2024-03-29) +更新文档 +## 1.0.3(2024-03-29) +更新使用文档 +## 1.0.2(2024-03-29) +修改说明文档 +## 1.0.1(2024-03-29) +添加示例代码 +## 1.0.0(2024-03-29) +数据下拉 选择框,支持单选,关键词筛选, diff --git a/uni_modules/lu-data-select/components/lu-data-select/lu-data-select.vue b/uni_modules/lu-data-select/components/lu-data-select/lu-data-select.vue new file mode 100644 index 0000000..13b7036 --- /dev/null +++ b/uni_modules/lu-data-select/components/lu-data-select/lu-data-select.vue @@ -0,0 +1,1055 @@ + + + diff --git a/uni_modules/lu-data-select/components/lu-data-select/props.js b/uni_modules/lu-data-select/components/lu-data-select/props.js new file mode 100644 index 0000000..aa62b33 --- /dev/null +++ b/uni_modules/lu-data-select/components/lu-data-select/props.js @@ -0,0 +1,106 @@ +export default { + // 数据列表 + options: { + type: Array, + default: () => [] + }, + // #ifndef VUE3 + // v-model值 vue2 + value: { + type: [String, Number, Array], + default: "", + }, + // #endif + // #ifdef VUE3 + // v-model值 (Vue3) + modelValue: { + type: [String, Number, Array], + default: "", + }, + // #endif + // 是否可过滤 + filterable: { + type: Boolean, + default: true + }, + // 占位符 + placeholder: { + type: String, + default: "请选择" + }, + // 过滤输入框占位符;为空时沿用 placeholder + filterPlaceholder: { + type: String, + default: "" + }, + // 是否可清空 + clearable: { + type: Boolean, + default: true + }, + // 是否多选 + multiple: { + type: Boolean, + default: false + }, + // 是否禁用 + disabled: { + type: Boolean, + default: false + }, + // 是否显示选中值 up, down + direction: { + type: String, + default: "", + }, + // 显示文本的键名 + labelKey: { + type: String, + default: "label" + }, + // 值的键名 + valueKey: { + type: String, + default: "value" + }, + // 空数据文本 + emptyText: { + type: String, + default: "No Data" + }, + // change事件返回类型 + changeType: { + type: String, + default: "" + }, + // 是否开启虚拟列表 + virtualList: { + type: Boolean, + default: false + }, + // 边框样式 + border: { + type: String, + default: "1px solid #e5e5e5" + }, + // 高度 + height: { + type: String, + default: "35px" + }, + // 是否显示省略号 + showEllipsis: { + type: Boolean, + default: true + }, + // 是否折叠选项 + collapseTags: { + type: Boolean, + default: false + }, + // 折叠数量 + collapseTagsNum: { + type: Number, + default: 1 + } +} diff --git a/uni_modules/lu-data-select/components/lu-data-select/utils.js b/uni_modules/lu-data-select/components/lu-data-select/utils.js new file mode 100644 index 0000000..f2a33e3 --- /dev/null +++ b/uni_modules/lu-data-select/components/lu-data-select/utils.js @@ -0,0 +1,68 @@ +/** + * 防抖函数 + * @param {Function} fn 需要防抖的函数 + * @param {Number} delay 延迟时间 + */ +export const debounce = (fn, delay) => { + let timer = null; + return function(...args) { + if (timer) clearTimeout(timer); + timer = setTimeout(() => fn.apply(this, args), delay); + }; +}; + +/** + * 节流函数 + * @param {Function} fn 需要节流的函数 + * @param {Number} wait 等待时间 + */ +export const throttle = (fn, wait) => { + let timer = null; + return function(...args) { + if (!timer) { + timer = setTimeout(() => { + fn.apply(this, args); + timer = null; + }, wait); + } + }; +}; + +/** + * 数据处理函数 + * @param {Array} options 数据源 + * @param {String} valueKey 值键名 + * @param {String} labelKey 标签键名 + */ +export const formatOptions = (options, valueKey, labelKey) => { + return options.map(item => ({ + ...item, + value: item[valueKey], + label: item[labelKey] + })); +}; + +/** + * 搜索过滤 + * @param {Array} data 数据源 + * @param {String} searchText 搜索文本 + * @param {String} labelKey 标签键名 + */ +export const filterData = (data, searchText, labelKey) => { + const loweredText = searchText.toLowerCase(); + return data.filter(item => { + const label = String(item[labelKey]).toLowerCase(); + return label.includes(loweredText); + }); +}; + +/** + * 计算虚拟列表可视区域数据 + * @param {Array} data 数据源 + * @param {Number} start 起始索引 + * @param {Number} pageSize 每页数量 + */ +export const getVisibleData = (data, start, pageSize) => { + const end = Math.min(start + pageSize, data.length); // 限制结束索引不超过数据长度 + return data.slice(start, end); +}; \ No newline at end of file diff --git a/uni_modules/lu-data-select/package.json b/uni_modules/lu-data-select/package.json new file mode 100644 index 0000000..c5db486 --- /dev/null +++ b/uni_modules/lu-data-select/package.json @@ -0,0 +1,99 @@ +{ + "id": "lu-data-select", + "displayName": "lu-data-select", + "version": "1.0.62", + "description": "lu-data-select,数据,下拉菜单,下拉选择组件(单选、多选),返回值配置,自定义插槽", + "keywords": [ + "lu-data-select" +], + "repository": "https://gitee.com/lu-my/lu-data-select.git", + "engines": { + "HBuilderX": "^3.96", + "uni-app": "^4.07", + "uni-app-x": "" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "", + "darkmode": "x", + "i18n": "x", + "widescreen": "x" + }, + "uni_modules": { + "dependencies": [], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "x", + "aliyun": "x", + "alipay": "x" + }, + "client": { + "uni-app": { + "vue": { + "vue2": { + }, + "vue3": { + } + }, + "web": { + "safari": "√", + "chrome": "√" + }, + "app": { + "vue": "√", + "nvue": "-", + "android": "√", + "ios": "-", + "harmony": "-" + }, + "mp": { + "weixin": "√", + "alipay": "-", + "toutiao": "-", + "baidu": "-", + "kuaishou": "-", + "jd": "-", + "harmony": "-", + "qq": "-", + "lark": "-" + }, + "quickapp": { + "huawei": "-", + "union": "-" + } + }, + "uni-app-x": { + "web": { + "safari": "-", + "chrome": "-" + }, + "app": { + "android": "-", + "ios": "-", + "harmony": "-" + }, + "mp": { + "weixin": "-" + } + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/lu-data-select/readme.md b/uni_modules/lu-data-select/readme.md new file mode 100644 index 0000000..f40fa7a --- /dev/null +++ b/uni_modules/lu-data-select/readme.md @@ -0,0 +1,189 @@ +# lu-data-select + +# 数据下拉选择组件 + +单选、多选,关键词过滤,清空,空数据插槽,标题过长显示省略号 + +数据列表较多时,选中再次打开,选中的数据项,自动滚动到可视区域 + +# 示例代码 + +```javascript + + + + + + + +``` + +# 参数 + +| 参数名称 | 类型 | 默认值 | 可选值 | 说明 | +| ----------- | ------- | ------ | ------------ | ----------------------------- | +| v-model | String | | | 选中项绑定的值 | +| options | Array | [ ] | | 数据列表,见下方 options 参数 | +| labelKey | String | label | | 作为 label 唯一标识的键名 | +| valueKey | String | value | | 作为 value 唯一标识的键名 | +| multiple | Boolean | false | true / false | 是否多选 | +| direction | String | "" | down / up | 弹出方向,up、down, 其他值无效,自动判断方向 | +| filterable | Boolean | true | true / false | 是否可以筛选 | +| clearable | Boolean | true | true / false | 是否可以清空 | +| placeholder | String | 请选择 | | 默认提示语 | +| disabled | Boolean | false | true / false| 是否禁用选择 | +| border | String | '1px solid #e5e5e5' | css属性值 | 边框设置 | +| showEllipsis | Boolean | true | true / false | 选项过长是否显示省略号 | +| height | String | '35px' | css属性值 | 选择框高度,单选模式有效 | +| collapseTags | Boolean | false | true / false | 是否折叠 | +| collapseTagsNum | Number | 1 | | 多少开始折叠 | +| virtualList | Boolean | false | true / false | 大数据开启虚拟列表 | +| emptyText | String | 无数据 | | options 为空的时候显示的文本 | +| changeType | String | " ",可以不传,默认是返回value | "objectValue" | change事件返回的数据格式,默认:单选返回value值,多选返回value组成的数组,objectValue:单选返回对象,多选返回数组对象 | + +# options 参数 + +| 名称 | 类型 | 说明 | +| -------- | --------------- | -------------- | +| label | String / Number | 选项的标签 | +| value | String / Number | 选项的值 | +| disabled | Boolean | 是否禁用该选项 | + +# 事件 + +| 事件 | 说明 | +| ------ | ------------------ | +| change | 选项发生改变时触发 | + +# 插槽 + +| 名称 | 说明 | +| ----- | ---------------- | +| empty | 自定义无数据内容 | +| option| 自定义选项插槽,返回值row:当前选项,$index:当前选项数组下标 | diff --git a/uni_modules/uni-card/changelog.md b/uni_modules/uni-card/changelog.md new file mode 100644 index 0000000..c3cd8c4 --- /dev/null +++ b/uni_modules/uni-card/changelog.md @@ -0,0 +1,26 @@ +## 1.3.1(2021-12-20) +- 修复 在vue页面下略缩图显示不正常的bug +## 1.3.0(2021-11-19) +- 重构插槽的用法 ,header 替换为 title +- 新增 actions 插槽 +- 新增 cover 封面图属性和插槽 +- 新增 padding 内容默认内边距离 +- 新增 margin 卡片默认外边距离 +- 新增 spacing 卡片默认内边距 +- 新增 shadow 卡片阴影属性 +- 取消 mode 属性,可使用组合插槽代替 +- 取消 note 属性 ,使用actions插槽代替 +- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource) +- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-card](https://uniapp.dcloud.io/component/uniui/uni-card) +## 1.2.1(2021-07-30) +- 优化 vue3下事件警告的问题 +## 1.2.0(2021-07-13) +- 组件兼容 vue3,如何创建vue3项目详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834) +## 1.1.8(2021-07-01) +- 优化 图文卡片无图片加载时,提供占位图标 +- 新增 header 插槽,自定义卡片头部( 图文卡片 mode="style" 时,不支持) +- 修复 thumbnail 不存在仍然占位的 bug +## 1.1.7(2021-05-12) +- 新增 组件示例地址 +## 1.1.6(2021-02-04) +- 调整为uni_modules目录规范 diff --git a/uni_modules/uni-card/components/uni-card/uni-card.vue b/uni_modules/uni-card/components/uni-card/uni-card.vue new file mode 100644 index 0000000..c87e349 --- /dev/null +++ b/uni_modules/uni-card/components/uni-card/uni-card.vue @@ -0,0 +1,269 @@ + + + + + diff --git a/uni_modules/uni-card/package.json b/uni_modules/uni-card/package.json new file mode 100644 index 0000000..f16224d --- /dev/null +++ b/uni_modules/uni-card/package.json @@ -0,0 +1,90 @@ +{ + "id": "uni-card", + "displayName": "uni-card 卡片", + "version": "1.3.1", + "description": "Card 组件,提供常见的卡片样式。", + "keywords": [ + "uni-ui", + "uniui", + "card", + "", + "卡片" +], + "repository": "https://github.com/dcloudio/uni-ui", + "engines": { + "HBuilderX": "" + }, + "directories": { + "example": "../../temps/example_temps" + }, + "dcloudext": { + "category": [ + "前端组件", + "通用组件" + ], + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui" + }, + "uni_modules": { + "dependencies": [ + "uni-icons", + "uni-scss" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y" + }, + "快应用": { + "华为": "u", + "联盟": "u" + }, + "Vue": { + "vue2": "y", + "vue3": "y" + } + } + } + } +} diff --git a/uni_modules/uni-card/readme.md b/uni_modules/uni-card/readme.md new file mode 100644 index 0000000..7434e71 --- /dev/null +++ b/uni_modules/uni-card/readme.md @@ -0,0 +1,12 @@ + + +## Card 卡片 +> **组件名:uni-card** +> 代码块: `uCard` + +卡片视图组件。 + +### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-card) +#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 + + diff --git a/uni_modules/uni-icons/changelog.md b/uni_modules/uni-icons/changelog.md new file mode 100644 index 0000000..62e7682 --- /dev/null +++ b/uni_modules/uni-icons/changelog.md @@ -0,0 +1,44 @@ +## 2.0.12(2025-08-26) +- 优化 uni-app x 下 size 类型问题 +## 2.0.11(2025-08-18) +- 修复 图标点击事件返回 +## 2.0.9(2024-01-12) +fix: 修复图标大小默认值错误的问题 +## 2.0.8(2023-12-14) +- 修复 项目未使用 ts 情况下,打包报错的bug +## 2.0.7(2023-12-14) +- 修复 size 属性为 string 时,不加单位导致尺寸异常的bug +## 2.0.6(2023-12-11) +- 优化 兼容老版本icon类型,如 top ,bottom 等 +## 2.0.5(2023-12-11) +- 优化 兼容老版本icon类型,如 top ,bottom 等 +## 2.0.4(2023-12-06) +- 优化 uni-app x 下示例项目图标排序 +## 2.0.3(2023-12-06) +- 修复 nvue下引入组件报错的bug +## 2.0.2(2023-12-05) +-优化 size 属性支持单位 +## 2.0.1(2023-12-05) +- 新增 uni-app x 支持定义图标 +## 1.3.5(2022-01-24) +- 优化 size 属性可以传入不带单位的字符串数值 +## 1.3.4(2022-01-24) +- 优化 size 支持其他单位 +## 1.3.3(2022-01-17) +- 修复 nvue 有些图标不显示的bug,兼容老版本图标 +## 1.3.2(2021-12-01) +- 优化 示例可复制图标名称 +## 1.3.1(2021-11-23) +- 优化 兼容旧组件 type 值 +## 1.3.0(2021-11-19) +- 新增 更多图标 +- 优化 自定义图标使用方式 +- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource) +- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-icons](https://uniapp.dcloud.io/component/uniui/uni-icons) +## 1.1.7(2021-11-08) +## 1.2.0(2021-07-30) +- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834) +## 1.1.5(2021-05-12) +- 新增 组件示例地址 +## 1.1.4(2021-02-05) +- 调整为uni_modules目录规范 diff --git a/uni_modules/uni-icons/components/uni-icons/uni-icons.uvue b/uni_modules/uni-icons/components/uni-icons/uni-icons.uvue new file mode 100644 index 0000000..53eb2ea --- /dev/null +++ b/uni_modules/uni-icons/components/uni-icons/uni-icons.uvue @@ -0,0 +1,91 @@ + + + + + diff --git a/uni_modules/uni-icons/components/uni-icons/uni-icons.vue b/uni_modules/uni-icons/components/uni-icons/uni-icons.vue new file mode 100644 index 0000000..1bd3d5e --- /dev/null +++ b/uni_modules/uni-icons/components/uni-icons/uni-icons.vue @@ -0,0 +1,110 @@ + + + + + \ No newline at end of file diff --git a/uni_modules/uni-icons/components/uni-icons/uniicons.css b/uni_modules/uni-icons/components/uni-icons/uniicons.css new file mode 100644 index 0000000..0a6b6fe --- /dev/null +++ b/uni_modules/uni-icons/components/uni-icons/uniicons.css @@ -0,0 +1,664 @@ + +.uniui-cart-filled:before { + content: "\e6d0"; +} + +.uniui-gift-filled:before { + content: "\e6c4"; +} + +.uniui-color:before { + content: "\e6cf"; +} + +.uniui-wallet:before { + content: "\e6b1"; +} + +.uniui-settings-filled:before { + content: "\e6ce"; +} + +.uniui-auth-filled:before { + content: "\e6cc"; +} + +.uniui-shop-filled:before { + content: "\e6cd"; +} + +.uniui-staff-filled:before { + content: "\e6cb"; +} + +.uniui-vip-filled:before { + content: "\e6c6"; +} + +.uniui-plus-filled:before { + content: "\e6c7"; +} + +.uniui-folder-add-filled:before { + content: "\e6c8"; +} + +.uniui-color-filled:before { + content: "\e6c9"; +} + +.uniui-tune-filled:before { + content: "\e6ca"; +} + +.uniui-calendar-filled:before { + content: "\e6c0"; +} + +.uniui-notification-filled:before { + content: "\e6c1"; +} + +.uniui-wallet-filled:before { + content: "\e6c2"; +} + +.uniui-medal-filled:before { + content: "\e6c3"; +} + +.uniui-fire-filled:before { + content: "\e6c5"; +} + +.uniui-refreshempty:before { + content: "\e6bf"; +} + +.uniui-location-filled:before { + content: "\e6af"; +} + +.uniui-person-filled:before { + content: "\e69d"; +} + +.uniui-personadd-filled:before { + content: "\e698"; +} + +.uniui-arrowthinleft:before { + content: "\e6d2"; +} + +.uniui-arrowthinup:before { + content: "\e6d3"; +} + +.uniui-arrowthindown:before { + content: "\e6d4"; +} + +.uniui-back:before { + content: "\e6b9"; +} + +.uniui-forward:before { + content: "\e6ba"; +} + +.uniui-arrow-right:before { + content: "\e6bb"; +} + +.uniui-arrow-left:before { + content: "\e6bc"; +} + +.uniui-arrow-up:before { + content: "\e6bd"; +} + +.uniui-arrow-down:before { + content: "\e6be"; +} + +.uniui-arrowthinright:before { + content: "\e6d1"; +} + +.uniui-down:before { + content: "\e6b8"; +} + +.uniui-bottom:before { + content: "\e6b8"; +} + +.uniui-arrowright:before { + content: "\e6d5"; +} + +.uniui-right:before { + content: "\e6b5"; +} + +.uniui-up:before { + content: "\e6b6"; +} + +.uniui-top:before { + content: "\e6b6"; +} + +.uniui-left:before { + content: "\e6b7"; +} + +.uniui-arrowup:before { + content: "\e6d6"; +} + +.uniui-eye:before { + content: "\e651"; +} + +.uniui-eye-filled:before { + content: "\e66a"; +} + +.uniui-eye-slash:before { + content: "\e6b3"; +} + +.uniui-eye-slash-filled:before { + content: "\e6b4"; +} + +.uniui-info-filled:before { + content: "\e649"; +} + +.uniui-reload:before { + content: "\e6b2"; +} + +.uniui-micoff-filled:before { + content: "\e6b0"; +} + +.uniui-map-pin-ellipse:before { + content: "\e6ac"; +} + +.uniui-map-pin:before { + content: "\e6ad"; +} + +.uniui-location:before { + content: "\e6ae"; +} + +.uniui-starhalf:before { + content: "\e683"; +} + +.uniui-star:before { + content: "\e688"; +} + +.uniui-star-filled:before { + content: "\e68f"; +} + +.uniui-calendar:before { + content: "\e6a0"; +} + +.uniui-fire:before { + content: "\e6a1"; +} + +.uniui-medal:before { + content: "\e6a2"; +} + +.uniui-font:before { + content: "\e6a3"; +} + +.uniui-gift:before { + content: "\e6a4"; +} + +.uniui-link:before { + content: "\e6a5"; +} + +.uniui-notification:before { + content: "\e6a6"; +} + +.uniui-staff:before { + content: "\e6a7"; +} + +.uniui-vip:before { + content: "\e6a8"; +} + +.uniui-folder-add:before { + content: "\e6a9"; +} + +.uniui-tune:before { + content: "\e6aa"; +} + +.uniui-auth:before { + content: "\e6ab"; +} + +.uniui-person:before { + content: "\e699"; +} + +.uniui-email-filled:before { + content: "\e69a"; +} + +.uniui-phone-filled:before { + content: "\e69b"; +} + +.uniui-phone:before { + content: "\e69c"; +} + +.uniui-email:before { + content: "\e69e"; +} + +.uniui-personadd:before { + content: "\e69f"; +} + +.uniui-chatboxes-filled:before { + content: "\e692"; +} + +.uniui-contact:before { + content: "\e693"; +} + +.uniui-chatbubble-filled:before { + content: "\e694"; +} + +.uniui-contact-filled:before { + content: "\e695"; +} + +.uniui-chatboxes:before { + content: "\e696"; +} + +.uniui-chatbubble:before { + content: "\e697"; +} + +.uniui-upload-filled:before { + content: "\e68e"; +} + +.uniui-upload:before { + content: "\e690"; +} + +.uniui-weixin:before { + content: "\e691"; +} + +.uniui-compose:before { + content: "\e67f"; +} + +.uniui-qq:before { + content: "\e680"; +} + +.uniui-download-filled:before { + content: "\e681"; +} + +.uniui-pyq:before { + content: "\e682"; +} + +.uniui-sound:before { + content: "\e684"; +} + +.uniui-trash-filled:before { + content: "\e685"; +} + +.uniui-sound-filled:before { + content: "\e686"; +} + +.uniui-trash:before { + content: "\e687"; +} + +.uniui-videocam-filled:before { + content: "\e689"; +} + +.uniui-spinner-cycle:before { + content: "\e68a"; +} + +.uniui-weibo:before { + content: "\e68b"; +} + +.uniui-videocam:before { + content: "\e68c"; +} + +.uniui-download:before { + content: "\e68d"; +} + +.uniui-help:before { + content: "\e679"; +} + +.uniui-navigate-filled:before { + content: "\e67a"; +} + +.uniui-plusempty:before { + content: "\e67b"; +} + +.uniui-smallcircle:before { + content: "\e67c"; +} + +.uniui-minus-filled:before { + content: "\e67d"; +} + +.uniui-micoff:before { + content: "\e67e"; +} + +.uniui-closeempty:before { + content: "\e66c"; +} + +.uniui-clear:before { + content: "\e66d"; +} + +.uniui-navigate:before { + content: "\e66e"; +} + +.uniui-minus:before { + content: "\e66f"; +} + +.uniui-image:before { + content: "\e670"; +} + +.uniui-mic:before { + content: "\e671"; +} + +.uniui-paperplane:before { + content: "\e672"; +} + +.uniui-close:before { + content: "\e673"; +} + +.uniui-help-filled:before { + content: "\e674"; +} + +.uniui-paperplane-filled:before { + content: "\e675"; +} + +.uniui-plus:before { + content: "\e676"; +} + +.uniui-mic-filled:before { + content: "\e677"; +} + +.uniui-image-filled:before { + content: "\e678"; +} + +.uniui-locked-filled:before { + content: "\e668"; +} + +.uniui-info:before { + content: "\e669"; +} + +.uniui-locked:before { + content: "\e66b"; +} + +.uniui-camera-filled:before { + content: "\e658"; +} + +.uniui-chat-filled:before { + content: "\e659"; +} + +.uniui-camera:before { + content: "\e65a"; +} + +.uniui-circle:before { + content: "\e65b"; +} + +.uniui-checkmarkempty:before { + content: "\e65c"; +} + +.uniui-chat:before { + content: "\e65d"; +} + +.uniui-circle-filled:before { + content: "\e65e"; +} + +.uniui-flag:before { + content: "\e65f"; +} + +.uniui-flag-filled:before { + content: "\e660"; +} + +.uniui-gear-filled:before { + content: "\e661"; +} + +.uniui-home:before { + content: "\e662"; +} + +.uniui-home-filled:before { + content: "\e663"; +} + +.uniui-gear:before { + content: "\e664"; +} + +.uniui-smallcircle-filled:before { + content: "\e665"; +} + +.uniui-map-filled:before { + content: "\e666"; +} + +.uniui-map:before { + content: "\e667"; +} + +.uniui-refresh-filled:before { + content: "\e656"; +} + +.uniui-refresh:before { + content: "\e657"; +} + +.uniui-cloud-upload:before { + content: "\e645"; +} + +.uniui-cloud-download-filled:before { + content: "\e646"; +} + +.uniui-cloud-download:before { + content: "\e647"; +} + +.uniui-cloud-upload-filled:before { + content: "\e648"; +} + +.uniui-redo:before { + content: "\e64a"; +} + +.uniui-images-filled:before { + content: "\e64b"; +} + +.uniui-undo-filled:before { + content: "\e64c"; +} + +.uniui-more:before { + content: "\e64d"; +} + +.uniui-more-filled:before { + content: "\e64e"; +} + +.uniui-undo:before { + content: "\e64f"; +} + +.uniui-images:before { + content: "\e650"; +} + +.uniui-paperclip:before { + content: "\e652"; +} + +.uniui-settings:before { + content: "\e653"; +} + +.uniui-search:before { + content: "\e654"; +} + +.uniui-redo-filled:before { + content: "\e655"; +} + +.uniui-list:before { + content: "\e644"; +} + +.uniui-mail-open-filled:before { + content: "\e63a"; +} + +.uniui-hand-down-filled:before { + content: "\e63c"; +} + +.uniui-hand-down:before { + content: "\e63d"; +} + +.uniui-hand-up-filled:before { + content: "\e63e"; +} + +.uniui-hand-up:before { + content: "\e63f"; +} + +.uniui-heart-filled:before { + content: "\e641"; +} + +.uniui-mail-open:before { + content: "\e643"; +} + +.uniui-heart:before { + content: "\e639"; +} + +.uniui-loop:before { + content: "\e633"; +} + +.uniui-pulldown:before { + content: "\e632"; +} + +.uniui-scan:before { + content: "\e62a"; +} + +.uniui-bars:before { + content: "\e627"; +} + +.uniui-checkbox:before { + content: "\e62b"; +} + +.uniui-checkbox-filled:before { + content: "\e62c"; +} + +.uniui-shop:before { + content: "\e62f"; +} + +.uniui-headphones:before { + content: "\e630"; +} + +.uniui-cart:before { + content: "\e631"; +} diff --git a/uni_modules/uni-icons/components/uni-icons/uniicons.ttf b/uni_modules/uni-icons/components/uni-icons/uniicons.ttf new file mode 100644 index 0000000000000000000000000000000000000000..14696d038d828073edac09ea4e5ba1dec2f58115 GIT binary patch literal 35824 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 F{2S@rCxHL} literal 0 HcmV?d00001 diff --git a/uni_modules/uni-icons/components/uni-icons/uniicons_file.ts b/uni_modules/uni-icons/components/uni-icons/uniicons_file.ts new file mode 100644 index 0000000..98e93aa --- /dev/null +++ b/uni_modules/uni-icons/components/uni-icons/uniicons_file.ts @@ -0,0 +1,664 @@ + +export type IconsData = { + id : string + name : string + font_family : string + css_prefix_text : string + description : string + glyphs : Array +} + +export type IconsDataItem = { + font_class : string + unicode : string +} + + +export const fontData = [ + { + "font_class": "arrow-down", + "unicode": "\ue6be" + }, + { + "font_class": "arrow-left", + "unicode": "\ue6bc" + }, + { + "font_class": "arrow-right", + "unicode": "\ue6bb" + }, + { + "font_class": "arrow-up", + "unicode": "\ue6bd" + }, + { + "font_class": "auth", + "unicode": "\ue6ab" + }, + { + "font_class": "auth-filled", + "unicode": "\ue6cc" + }, + { + "font_class": "back", + "unicode": "\ue6b9" + }, + { + "font_class": "bars", + "unicode": "\ue627" + }, + { + "font_class": "calendar", + "unicode": "\ue6a0" + }, + { + "font_class": "calendar-filled", + "unicode": "\ue6c0" + }, + { + "font_class": "camera", + "unicode": "\ue65a" + }, + { + "font_class": "camera-filled", + "unicode": "\ue658" + }, + { + "font_class": "cart", + "unicode": "\ue631" + }, + { + "font_class": "cart-filled", + "unicode": "\ue6d0" + }, + { + "font_class": "chat", + "unicode": "\ue65d" + }, + { + "font_class": "chat-filled", + "unicode": "\ue659" + }, + { + "font_class": "chatboxes", + "unicode": "\ue696" + }, + { + "font_class": "chatboxes-filled", + "unicode": "\ue692" + }, + { + "font_class": "chatbubble", + "unicode": "\ue697" + }, + { + "font_class": "chatbubble-filled", + "unicode": "\ue694" + }, + { + "font_class": "checkbox", + "unicode": "\ue62b" + }, + { + "font_class": "checkbox-filled", + "unicode": "\ue62c" + }, + { + "font_class": "checkmarkempty", + "unicode": "\ue65c" + }, + { + "font_class": "circle", + "unicode": "\ue65b" + }, + { + "font_class": "circle-filled", + "unicode": "\ue65e" + }, + { + "font_class": "clear", + "unicode": "\ue66d" + }, + { + "font_class": "close", + "unicode": "\ue673" + }, + { + "font_class": "closeempty", + "unicode": "\ue66c" + }, + { + "font_class": "cloud-download", + "unicode": "\ue647" + }, + { + "font_class": "cloud-download-filled", + "unicode": "\ue646" + }, + { + "font_class": "cloud-upload", + "unicode": "\ue645" + }, + { + "font_class": "cloud-upload-filled", + "unicode": "\ue648" + }, + { + "font_class": "color", + "unicode": "\ue6cf" + }, + { + "font_class": "color-filled", + "unicode": "\ue6c9" + }, + { + "font_class": "compose", + "unicode": "\ue67f" + }, + { + "font_class": "contact", + "unicode": "\ue693" + }, + { + "font_class": "contact-filled", + "unicode": "\ue695" + }, + { + "font_class": "down", + "unicode": "\ue6b8" + }, + { + "font_class": "bottom", + "unicode": "\ue6b8" + }, + { + "font_class": "download", + "unicode": "\ue68d" + }, + { + "font_class": "download-filled", + "unicode": "\ue681" + }, + { + "font_class": "email", + "unicode": "\ue69e" + }, + { + "font_class": "email-filled", + "unicode": "\ue69a" + }, + { + "font_class": "eye", + "unicode": "\ue651" + }, + { + "font_class": "eye-filled", + "unicode": "\ue66a" + }, + { + "font_class": "eye-slash", + "unicode": "\ue6b3" + }, + { + "font_class": "eye-slash-filled", + "unicode": "\ue6b4" + }, + { + "font_class": "fire", + "unicode": "\ue6a1" + }, + { + "font_class": "fire-filled", + "unicode": "\ue6c5" + }, + { + "font_class": "flag", + "unicode": "\ue65f" + }, + { + "font_class": "flag-filled", + "unicode": "\ue660" + }, + { + "font_class": "folder-add", + "unicode": "\ue6a9" + }, + { + "font_class": "folder-add-filled", + "unicode": "\ue6c8" + }, + { + "font_class": "font", + "unicode": "\ue6a3" + }, + { + "font_class": "forward", + "unicode": "\ue6ba" + }, + { + "font_class": "gear", + "unicode": "\ue664" + }, + { + "font_class": "gear-filled", + "unicode": "\ue661" + }, + { + "font_class": "gift", + "unicode": "\ue6a4" + }, + { + "font_class": "gift-filled", + "unicode": "\ue6c4" + }, + { + "font_class": "hand-down", + "unicode": "\ue63d" + }, + { + "font_class": "hand-down-filled", + "unicode": "\ue63c" + }, + { + "font_class": "hand-up", + "unicode": "\ue63f" + }, + { + "font_class": "hand-up-filled", + "unicode": "\ue63e" + }, + { + "font_class": "headphones", + "unicode": "\ue630" + }, + { + "font_class": "heart", + "unicode": "\ue639" + }, + { + "font_class": "heart-filled", + "unicode": "\ue641" + }, + { + "font_class": "help", + "unicode": "\ue679" + }, + { + "font_class": "help-filled", + "unicode": "\ue674" + }, + { + "font_class": "home", + "unicode": "\ue662" + }, + { + "font_class": "home-filled", + "unicode": "\ue663" + }, + { + "font_class": "image", + "unicode": "\ue670" + }, + { + "font_class": "image-filled", + "unicode": "\ue678" + }, + { + "font_class": "images", + "unicode": "\ue650" + }, + { + "font_class": "images-filled", + "unicode": "\ue64b" + }, + { + "font_class": "info", + "unicode": "\ue669" + }, + { + "font_class": "info-filled", + "unicode": "\ue649" + }, + { + "font_class": "left", + "unicode": "\ue6b7" + }, + { + "font_class": "link", + "unicode": "\ue6a5" + }, + { + "font_class": "list", + "unicode": "\ue644" + }, + { + "font_class": "location", + "unicode": "\ue6ae" + }, + { + "font_class": "location-filled", + "unicode": "\ue6af" + }, + { + "font_class": "locked", + "unicode": "\ue66b" + }, + { + "font_class": "locked-filled", + "unicode": "\ue668" + }, + { + "font_class": "loop", + "unicode": "\ue633" + }, + { + "font_class": "mail-open", + "unicode": "\ue643" + }, + { + "font_class": "mail-open-filled", + "unicode": "\ue63a" + }, + { + "font_class": "map", + "unicode": "\ue667" + }, + { + "font_class": "map-filled", + "unicode": "\ue666" + }, + { + "font_class": "map-pin", + "unicode": "\ue6ad" + }, + { + "font_class": "map-pin-ellipse", + "unicode": "\ue6ac" + }, + { + "font_class": "medal", + "unicode": "\ue6a2" + }, + { + "font_class": "medal-filled", + "unicode": "\ue6c3" + }, + { + "font_class": "mic", + "unicode": "\ue671" + }, + { + "font_class": "mic-filled", + "unicode": "\ue677" + }, + { + "font_class": "micoff", + "unicode": "\ue67e" + }, + { + "font_class": "micoff-filled", + "unicode": "\ue6b0" + }, + { + "font_class": "minus", + "unicode": "\ue66f" + }, + { + "font_class": "minus-filled", + "unicode": "\ue67d" + }, + { + "font_class": "more", + "unicode": "\ue64d" + }, + { + "font_class": "more-filled", + "unicode": "\ue64e" + }, + { + "font_class": "navigate", + "unicode": "\ue66e" + }, + { + "font_class": "navigate-filled", + "unicode": "\ue67a" + }, + { + "font_class": "notification", + "unicode": "\ue6a6" + }, + { + "font_class": "notification-filled", + "unicode": "\ue6c1" + }, + { + "font_class": "paperclip", + "unicode": "\ue652" + }, + { + "font_class": "paperplane", + "unicode": "\ue672" + }, + { + "font_class": "paperplane-filled", + "unicode": "\ue675" + }, + { + "font_class": "person", + "unicode": "\ue699" + }, + { + "font_class": "person-filled", + "unicode": "\ue69d" + }, + { + "font_class": "personadd", + "unicode": "\ue69f" + }, + { + "font_class": "personadd-filled", + "unicode": "\ue698" + }, + { + "font_class": "personadd-filled-copy", + "unicode": "\ue6d1" + }, + { + "font_class": "phone", + "unicode": "\ue69c" + }, + { + "font_class": "phone-filled", + "unicode": "\ue69b" + }, + { + "font_class": "plus", + "unicode": "\ue676" + }, + { + "font_class": "plus-filled", + "unicode": "\ue6c7" + }, + { + "font_class": "plusempty", + "unicode": "\ue67b" + }, + { + "font_class": "pulldown", + "unicode": "\ue632" + }, + { + "font_class": "pyq", + "unicode": "\ue682" + }, + { + "font_class": "qq", + "unicode": "\ue680" + }, + { + "font_class": "redo", + "unicode": "\ue64a" + }, + { + "font_class": "redo-filled", + "unicode": "\ue655" + }, + { + "font_class": "refresh", + "unicode": "\ue657" + }, + { + "font_class": "refresh-filled", + "unicode": "\ue656" + }, + { + "font_class": "refreshempty", + "unicode": "\ue6bf" + }, + { + "font_class": "reload", + "unicode": "\ue6b2" + }, + { + "font_class": "right", + "unicode": "\ue6b5" + }, + { + "font_class": "scan", + "unicode": "\ue62a" + }, + { + "font_class": "search", + "unicode": "\ue654" + }, + { + "font_class": "settings", + "unicode": "\ue653" + }, + { + "font_class": "settings-filled", + "unicode": "\ue6ce" + }, + { + "font_class": "shop", + "unicode": "\ue62f" + }, + { + "font_class": "shop-filled", + "unicode": "\ue6cd" + }, + { + "font_class": "smallcircle", + "unicode": "\ue67c" + }, + { + "font_class": "smallcircle-filled", + "unicode": "\ue665" + }, + { + "font_class": "sound", + "unicode": "\ue684" + }, + { + "font_class": "sound-filled", + "unicode": "\ue686" + }, + { + "font_class": "spinner-cycle", + "unicode": "\ue68a" + }, + { + "font_class": "staff", + "unicode": "\ue6a7" + }, + { + "font_class": "staff-filled", + "unicode": "\ue6cb" + }, + { + "font_class": "star", + "unicode": "\ue688" + }, + { + "font_class": "star-filled", + "unicode": "\ue68f" + }, + { + "font_class": "starhalf", + "unicode": "\ue683" + }, + { + "font_class": "trash", + "unicode": "\ue687" + }, + { + "font_class": "trash-filled", + "unicode": "\ue685" + }, + { + "font_class": "tune", + "unicode": "\ue6aa" + }, + { + "font_class": "tune-filled", + "unicode": "\ue6ca" + }, + { + "font_class": "undo", + "unicode": "\ue64f" + }, + { + "font_class": "undo-filled", + "unicode": "\ue64c" + }, + { + "font_class": "up", + "unicode": "\ue6b6" + }, + { + "font_class": "top", + "unicode": "\ue6b6" + }, + { + "font_class": "upload", + "unicode": "\ue690" + }, + { + "font_class": "upload-filled", + "unicode": "\ue68e" + }, + { + "font_class": "videocam", + "unicode": "\ue68c" + }, + { + "font_class": "videocam-filled", + "unicode": "\ue689" + }, + { + "font_class": "vip", + "unicode": "\ue6a8" + }, + { + "font_class": "vip-filled", + "unicode": "\ue6c6" + }, + { + "font_class": "wallet", + "unicode": "\ue6b1" + }, + { + "font_class": "wallet-filled", + "unicode": "\ue6c2" + }, + { + "font_class": "weibo", + "unicode": "\ue68b" + }, + { + "font_class": "weixin", + "unicode": "\ue691" + } +] as IconsDataItem[] + +// export const fontData = JSON.parse(fontDataJson) diff --git a/uni_modules/uni-icons/components/uni-icons/uniicons_file_vue.js b/uni_modules/uni-icons/components/uni-icons/uniicons_file_vue.js new file mode 100644 index 0000000..1cd11e1 --- /dev/null +++ b/uni_modules/uni-icons/components/uni-icons/uniicons_file_vue.js @@ -0,0 +1,649 @@ + +export const fontData = [ + { + "font_class": "arrow-down", + "unicode": "\ue6be" + }, + { + "font_class": "arrow-left", + "unicode": "\ue6bc" + }, + { + "font_class": "arrow-right", + "unicode": "\ue6bb" + }, + { + "font_class": "arrow-up", + "unicode": "\ue6bd" + }, + { + "font_class": "auth", + "unicode": "\ue6ab" + }, + { + "font_class": "auth-filled", + "unicode": "\ue6cc" + }, + { + "font_class": "back", + "unicode": "\ue6b9" + }, + { + "font_class": "bars", + "unicode": "\ue627" + }, + { + "font_class": "calendar", + "unicode": "\ue6a0" + }, + { + "font_class": "calendar-filled", + "unicode": "\ue6c0" + }, + { + "font_class": "camera", + "unicode": "\ue65a" + }, + { + "font_class": "camera-filled", + "unicode": "\ue658" + }, + { + "font_class": "cart", + "unicode": "\ue631" + }, + { + "font_class": "cart-filled", + "unicode": "\ue6d0" + }, + { + "font_class": "chat", + "unicode": "\ue65d" + }, + { + "font_class": "chat-filled", + "unicode": "\ue659" + }, + { + "font_class": "chatboxes", + "unicode": "\ue696" + }, + { + "font_class": "chatboxes-filled", + "unicode": "\ue692" + }, + { + "font_class": "chatbubble", + "unicode": "\ue697" + }, + { + "font_class": "chatbubble-filled", + "unicode": "\ue694" + }, + { + "font_class": "checkbox", + "unicode": "\ue62b" + }, + { + "font_class": "checkbox-filled", + "unicode": "\ue62c" + }, + { + "font_class": "checkmarkempty", + "unicode": "\ue65c" + }, + { + "font_class": "circle", + "unicode": "\ue65b" + }, + { + "font_class": "circle-filled", + "unicode": "\ue65e" + }, + { + "font_class": "clear", + "unicode": "\ue66d" + }, + { + "font_class": "close", + "unicode": "\ue673" + }, + { + "font_class": "closeempty", + "unicode": "\ue66c" + }, + { + "font_class": "cloud-download", + "unicode": "\ue647" + }, + { + "font_class": "cloud-download-filled", + "unicode": "\ue646" + }, + { + "font_class": "cloud-upload", + "unicode": "\ue645" + }, + { + "font_class": "cloud-upload-filled", + "unicode": "\ue648" + }, + { + "font_class": "color", + "unicode": "\ue6cf" + }, + { + "font_class": "color-filled", + "unicode": "\ue6c9" + }, + { + "font_class": "compose", + "unicode": "\ue67f" + }, + { + "font_class": "contact", + "unicode": "\ue693" + }, + { + "font_class": "contact-filled", + "unicode": "\ue695" + }, + { + "font_class": "down", + "unicode": "\ue6b8" + }, + { + "font_class": "bottom", + "unicode": "\ue6b8" + }, + { + "font_class": "download", + "unicode": "\ue68d" + }, + { + "font_class": "download-filled", + "unicode": "\ue681" + }, + { + "font_class": "email", + "unicode": "\ue69e" + }, + { + "font_class": "email-filled", + "unicode": "\ue69a" + }, + { + "font_class": "eye", + "unicode": "\ue651" + }, + { + "font_class": "eye-filled", + "unicode": "\ue66a" + }, + { + "font_class": "eye-slash", + "unicode": "\ue6b3" + }, + { + "font_class": "eye-slash-filled", + "unicode": "\ue6b4" + }, + { + "font_class": "fire", + "unicode": "\ue6a1" + }, + { + "font_class": "fire-filled", + "unicode": "\ue6c5" + }, + { + "font_class": "flag", + "unicode": "\ue65f" + }, + { + "font_class": "flag-filled", + "unicode": "\ue660" + }, + { + "font_class": "folder-add", + "unicode": "\ue6a9" + }, + { + "font_class": "folder-add-filled", + "unicode": "\ue6c8" + }, + { + "font_class": "font", + "unicode": "\ue6a3" + }, + { + "font_class": "forward", + "unicode": "\ue6ba" + }, + { + "font_class": "gear", + "unicode": "\ue664" + }, + { + "font_class": "gear-filled", + "unicode": "\ue661" + }, + { + "font_class": "gift", + "unicode": "\ue6a4" + }, + { + "font_class": "gift-filled", + "unicode": "\ue6c4" + }, + { + "font_class": "hand-down", + "unicode": "\ue63d" + }, + { + "font_class": "hand-down-filled", + "unicode": "\ue63c" + }, + { + "font_class": "hand-up", + "unicode": "\ue63f" + }, + { + "font_class": "hand-up-filled", + "unicode": "\ue63e" + }, + { + "font_class": "headphones", + "unicode": "\ue630" + }, + { + "font_class": "heart", + "unicode": "\ue639" + }, + { + "font_class": "heart-filled", + "unicode": "\ue641" + }, + { + "font_class": "help", + "unicode": "\ue679" + }, + { + "font_class": "help-filled", + "unicode": "\ue674" + }, + { + "font_class": "home", + "unicode": "\ue662" + }, + { + "font_class": "home-filled", + "unicode": "\ue663" + }, + { + "font_class": "image", + "unicode": "\ue670" + }, + { + "font_class": "image-filled", + "unicode": "\ue678" + }, + { + "font_class": "images", + "unicode": "\ue650" + }, + { + "font_class": "images-filled", + "unicode": "\ue64b" + }, + { + "font_class": "info", + "unicode": "\ue669" + }, + { + "font_class": "info-filled", + "unicode": "\ue649" + }, + { + "font_class": "left", + "unicode": "\ue6b7" + }, + { + "font_class": "link", + "unicode": "\ue6a5" + }, + { + "font_class": "list", + "unicode": "\ue644" + }, + { + "font_class": "location", + "unicode": "\ue6ae" + }, + { + "font_class": "location-filled", + "unicode": "\ue6af" + }, + { + "font_class": "locked", + "unicode": "\ue66b" + }, + { + "font_class": "locked-filled", + "unicode": "\ue668" + }, + { + "font_class": "loop", + "unicode": "\ue633" + }, + { + "font_class": "mail-open", + "unicode": "\ue643" + }, + { + "font_class": "mail-open-filled", + "unicode": "\ue63a" + }, + { + "font_class": "map", + "unicode": "\ue667" + }, + { + "font_class": "map-filled", + "unicode": "\ue666" + }, + { + "font_class": "map-pin", + "unicode": "\ue6ad" + }, + { + "font_class": "map-pin-ellipse", + "unicode": "\ue6ac" + }, + { + "font_class": "medal", + "unicode": "\ue6a2" + }, + { + "font_class": "medal-filled", + "unicode": "\ue6c3" + }, + { + "font_class": "mic", + "unicode": "\ue671" + }, + { + "font_class": "mic-filled", + "unicode": "\ue677" + }, + { + "font_class": "micoff", + "unicode": "\ue67e" + }, + { + "font_class": "micoff-filled", + "unicode": "\ue6b0" + }, + { + "font_class": "minus", + "unicode": "\ue66f" + }, + { + "font_class": "minus-filled", + "unicode": "\ue67d" + }, + { + "font_class": "more", + "unicode": "\ue64d" + }, + { + "font_class": "more-filled", + "unicode": "\ue64e" + }, + { + "font_class": "navigate", + "unicode": "\ue66e" + }, + { + "font_class": "navigate-filled", + "unicode": "\ue67a" + }, + { + "font_class": "notification", + "unicode": "\ue6a6" + }, + { + "font_class": "notification-filled", + "unicode": "\ue6c1" + }, + { + "font_class": "paperclip", + "unicode": "\ue652" + }, + { + "font_class": "paperplane", + "unicode": "\ue672" + }, + { + "font_class": "paperplane-filled", + "unicode": "\ue675" + }, + { + "font_class": "person", + "unicode": "\ue699" + }, + { + "font_class": "person-filled", + "unicode": "\ue69d" + }, + { + "font_class": "personadd", + "unicode": "\ue69f" + }, + { + "font_class": "personadd-filled", + "unicode": "\ue698" + }, + { + "font_class": "personadd-filled-copy", + "unicode": "\ue6d1" + }, + { + "font_class": "phone", + "unicode": "\ue69c" + }, + { + "font_class": "phone-filled", + "unicode": "\ue69b" + }, + { + "font_class": "plus", + "unicode": "\ue676" + }, + { + "font_class": "plus-filled", + "unicode": "\ue6c7" + }, + { + "font_class": "plusempty", + "unicode": "\ue67b" + }, + { + "font_class": "pulldown", + "unicode": "\ue632" + }, + { + "font_class": "pyq", + "unicode": "\ue682" + }, + { + "font_class": "qq", + "unicode": "\ue680" + }, + { + "font_class": "redo", + "unicode": "\ue64a" + }, + { + "font_class": "redo-filled", + "unicode": "\ue655" + }, + { + "font_class": "refresh", + "unicode": "\ue657" + }, + { + "font_class": "refresh-filled", + "unicode": "\ue656" + }, + { + "font_class": "refreshempty", + "unicode": "\ue6bf" + }, + { + "font_class": "reload", + "unicode": "\ue6b2" + }, + { + "font_class": "right", + "unicode": "\ue6b5" + }, + { + "font_class": "scan", + "unicode": "\ue62a" + }, + { + "font_class": "search", + "unicode": "\ue654" + }, + { + "font_class": "settings", + "unicode": "\ue653" + }, + { + "font_class": "settings-filled", + "unicode": "\ue6ce" + }, + { + "font_class": "shop", + "unicode": "\ue62f" + }, + { + "font_class": "shop-filled", + "unicode": "\ue6cd" + }, + { + "font_class": "smallcircle", + "unicode": "\ue67c" + }, + { + "font_class": "smallcircle-filled", + "unicode": "\ue665" + }, + { + "font_class": "sound", + "unicode": "\ue684" + }, + { + "font_class": "sound-filled", + "unicode": "\ue686" + }, + { + "font_class": "spinner-cycle", + "unicode": "\ue68a" + }, + { + "font_class": "staff", + "unicode": "\ue6a7" + }, + { + "font_class": "staff-filled", + "unicode": "\ue6cb" + }, + { + "font_class": "star", + "unicode": "\ue688" + }, + { + "font_class": "star-filled", + "unicode": "\ue68f" + }, + { + "font_class": "starhalf", + "unicode": "\ue683" + }, + { + "font_class": "trash", + "unicode": "\ue687" + }, + { + "font_class": "trash-filled", + "unicode": "\ue685" + }, + { + "font_class": "tune", + "unicode": "\ue6aa" + }, + { + "font_class": "tune-filled", + "unicode": "\ue6ca" + }, + { + "font_class": "undo", + "unicode": "\ue64f" + }, + { + "font_class": "undo-filled", + "unicode": "\ue64c" + }, + { + "font_class": "up", + "unicode": "\ue6b6" + }, + { + "font_class": "top", + "unicode": "\ue6b6" + }, + { + "font_class": "upload", + "unicode": "\ue690" + }, + { + "font_class": "upload-filled", + "unicode": "\ue68e" + }, + { + "font_class": "videocam", + "unicode": "\ue68c" + }, + { + "font_class": "videocam-filled", + "unicode": "\ue689" + }, + { + "font_class": "vip", + "unicode": "\ue6a8" + }, + { + "font_class": "vip-filled", + "unicode": "\ue6c6" + }, + { + "font_class": "wallet", + "unicode": "\ue6b1" + }, + { + "font_class": "wallet-filled", + "unicode": "\ue6c2" + }, + { + "font_class": "weibo", + "unicode": "\ue68b" + }, + { + "font_class": "weixin", + "unicode": "\ue691" + } +] + +// export const fontData = JSON.parse(fontDataJson) diff --git a/uni_modules/uni-icons/package.json b/uni_modules/uni-icons/package.json new file mode 100644 index 0000000..60e45f0 --- /dev/null +++ b/uni_modules/uni-icons/package.json @@ -0,0 +1,111 @@ +{ + "id": "uni-icons", + "displayName": "uni-icons 图标", + "version": "2.0.12", + "description": "图标组件,用于展示移动端常见的图标,可自定义颜色、大小。", + "keywords": [ + "uni-ui", + "uniui", + "icon", + "图标" +], + "repository": "https://github.com/dcloudio/uni-ui", + "engines": { + "HBuilderX": "^3.2.14", + "uni-app": "^4.08", + "uni-app-x": "^4.61" + }, + "directories": { + "example": "../../temps/example_temps" + }, + "dcloudext": { + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui", + "type": "component-vue", + "darkmode": "x", + "i18n": "x", + "widescreen": "x" + }, + "uni_modules": { + "dependencies": [ + "uni-scss" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "x", + "aliyun": "x", + "alipay": "x" + }, + "client": { + "uni-app": { + "vue": { + "vue2": "√", + "vue3": "√" + }, + "web": { + "safari": "√", + "chrome": "√" + }, + "app": { + "vue": "√", + "nvue": "-", + "android": { + "extVersion": "", + "minVersion": "29" + }, + "ios": "√", + "harmony": "√" + }, + "mp": { + "weixin": "√", + "alipay": "√", + "toutiao": "√", + "baidu": "√", + "kuaishou": "-", + "jd": "-", + "harmony": "-", + "qq": "√", + "lark": "-" + }, + "quickapp": { + "huawei": "√", + "union": "√" + } + }, + "uni-app-x": { + "web": { + "safari": "√", + "chrome": "√" + }, + "app": { + "android": { + "extVersion": "", + "minVersion": "29" + }, + "ios": "√", + "harmony": "√" + }, + "mp": { + "weixin": "√" + } + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uni-icons/readme.md b/uni_modules/uni-icons/readme.md new file mode 100644 index 0000000..86234ba --- /dev/null +++ b/uni_modules/uni-icons/readme.md @@ -0,0 +1,8 @@ +## Icons 图标 +> **组件名:uni-icons** +> 代码块: `uIcons` + +用于展示 icons 图标 。 + +### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-icons) +#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 diff --git a/uni_modules/uni-scss/changelog.md b/uni_modules/uni-scss/changelog.md new file mode 100644 index 0000000..b863bb0 --- /dev/null +++ b/uni_modules/uni-scss/changelog.md @@ -0,0 +1,8 @@ +## 1.0.3(2022-01-21) +- 优化 组件示例 +## 1.0.2(2021-11-22) +- 修复 / 符号在 vue 不同版本兼容问题引起的报错问题 +## 1.0.1(2021-11-22) +- 修复 vue3中scss语法兼容问题 +## 1.0.0(2021-11-18) +- init diff --git a/uni_modules/uni-scss/index.scss b/uni_modules/uni-scss/index.scss new file mode 100644 index 0000000..1744a5f --- /dev/null +++ b/uni_modules/uni-scss/index.scss @@ -0,0 +1 @@ +@import './styles/index.scss'; diff --git a/uni_modules/uni-scss/package.json b/uni_modules/uni-scss/package.json new file mode 100644 index 0000000..7cc0ccb --- /dev/null +++ b/uni_modules/uni-scss/package.json @@ -0,0 +1,82 @@ +{ + "id": "uni-scss", + "displayName": "uni-scss 辅助样式", + "version": "1.0.3", + "description": "uni-sass是uni-ui提供的一套全局样式 ,通过一些简单的类名和sass变量,实现简单的页面布局操作,比如颜色、边距、圆角等。", + "keywords": [ + "uni-scss", + "uni-ui", + "辅助样式" +], + "repository": "https://github.com/dcloudio/uni-ui", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "category": [ + "JS SDK", + "通用 SDK" + ], + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui" + }, + "uni_modules": { + "dependencies": [], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "y", + "app-nvue": "u" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y" + }, + "快应用": { + "华为": "n", + "联盟": "n" + }, + "Vue": { + "vue2": "y", + "vue3": "y" + } + } + } + } +} diff --git a/uni_modules/uni-scss/readme.md b/uni_modules/uni-scss/readme.md new file mode 100644 index 0000000..b7d1c25 --- /dev/null +++ b/uni_modules/uni-scss/readme.md @@ -0,0 +1,4 @@ +`uni-sass` 是 `uni-ui`提供的一套全局样式 ,通过一些简单的类名和`sass`变量,实现简单的页面布局操作,比如颜色、边距、圆角等。 + +### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-sass) +#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 \ No newline at end of file diff --git a/uni_modules/uni-scss/styles/index.scss b/uni_modules/uni-scss/styles/index.scss new file mode 100644 index 0000000..ffac4fe --- /dev/null +++ b/uni_modules/uni-scss/styles/index.scss @@ -0,0 +1,7 @@ +@import './setting/_variables.scss'; +@import './setting/_border.scss'; +@import './setting/_color.scss'; +@import './setting/_space.scss'; +@import './setting/_radius.scss'; +@import './setting/_text.scss'; +@import './setting/_styles.scss'; diff --git a/uni_modules/uni-scss/styles/setting/_border.scss b/uni_modules/uni-scss/styles/setting/_border.scss new file mode 100644 index 0000000..12a11c3 --- /dev/null +++ b/uni_modules/uni-scss/styles/setting/_border.scss @@ -0,0 +1,3 @@ +.uni-border { + border: 1px $uni-border-1 solid; +} \ No newline at end of file diff --git a/uni_modules/uni-scss/styles/setting/_color.scss b/uni_modules/uni-scss/styles/setting/_color.scss new file mode 100644 index 0000000..1ededd9 --- /dev/null +++ b/uni_modules/uni-scss/styles/setting/_color.scss @@ -0,0 +1,66 @@ + +// TODO 暂时不需要 class ,需要用户使用变量实现 ,如果使用类名其实并不推荐 +// @mixin get-styles($k,$c) { +// @if $k == size or $k == weight{ +// font-#{$k}:#{$c} +// }@else{ +// #{$k}:#{$c} +// } +// } +$uni-ui-color:( + // 主色 + primary: $uni-primary, + primary-disable: $uni-primary-disable, + primary-light: $uni-primary-light, + // 辅助色 + success: $uni-success, + success-disable: $uni-success-disable, + success-light: $uni-success-light, + warning: $uni-warning, + warning-disable: $uni-warning-disable, + warning-light: $uni-warning-light, + error: $uni-error, + error-disable: $uni-error-disable, + error-light: $uni-error-light, + info: $uni-info, + info-disable: $uni-info-disable, + info-light: $uni-info-light, + // 中性色 + main-color: $uni-main-color, + base-color: $uni-base-color, + secondary-color: $uni-secondary-color, + extra-color: $uni-extra-color, + // 背景色 + bg-color: $uni-bg-color, + // 边框颜色 + border-1: $uni-border-1, + border-2: $uni-border-2, + border-3: $uni-border-3, + border-4: $uni-border-4, + // 黑色 + black:$uni-black, + // 白色 + white:$uni-white, + // 透明 + transparent:$uni-transparent +) !default; +@each $key, $child in $uni-ui-color { + .uni-#{"" + $key} { + color: $child; + } + .uni-#{"" + $key}-bg { + background-color: $child; + } +} +.uni-shadow-sm { + box-shadow: $uni-shadow-sm; +} +.uni-shadow-base { + box-shadow: $uni-shadow-base; +} +.uni-shadow-lg { + box-shadow: $uni-shadow-lg; +} +.uni-mask { + background-color:$uni-mask; +} diff --git a/uni_modules/uni-scss/styles/setting/_radius.scss b/uni_modules/uni-scss/styles/setting/_radius.scss new file mode 100644 index 0000000..9a0428b --- /dev/null +++ b/uni_modules/uni-scss/styles/setting/_radius.scss @@ -0,0 +1,55 @@ +@mixin radius($r,$d:null ,$important: false){ + $radius-value:map-get($uni-radius, $r) if($important, !important, null); + // Key exists within the $uni-radius variable + @if (map-has-key($uni-radius, $r) and $d){ + @if $d == t { + border-top-left-radius:$radius-value; + border-top-right-radius:$radius-value; + }@else if $d == r { + border-top-right-radius:$radius-value; + border-bottom-right-radius:$radius-value; + }@else if $d == b { + border-bottom-left-radius:$radius-value; + border-bottom-right-radius:$radius-value; + }@else if $d == l { + border-top-left-radius:$radius-value; + border-bottom-left-radius:$radius-value; + }@else if $d == tl { + border-top-left-radius:$radius-value; + }@else if $d == tr { + border-top-right-radius:$radius-value; + }@else if $d == br { + border-bottom-right-radius:$radius-value; + }@else if $d == bl { + border-bottom-left-radius:$radius-value; + } + }@else{ + border-radius:$radius-value; + } +} + +@each $key, $child in $uni-radius { + @if($key){ + .uni-radius-#{"" + $key} { + @include radius($key) + } + }@else{ + .uni-radius { + @include radius($key) + } + } +} + +@each $direction in t, r, b, l,tl, tr, br, bl { + @each $key, $child in $uni-radius { + @if($key){ + .uni-radius-#{"" + $direction}-#{"" + $key} { + @include radius($key,$direction,false) + } + }@else{ + .uni-radius-#{$direction} { + @include radius($key,$direction,false) + } + } + } +} diff --git a/uni_modules/uni-scss/styles/setting/_space.scss b/uni_modules/uni-scss/styles/setting/_space.scss new file mode 100644 index 0000000..3c89528 --- /dev/null +++ b/uni_modules/uni-scss/styles/setting/_space.scss @@ -0,0 +1,56 @@ + +@mixin fn($space,$direction,$size,$n) { + @if $n { + #{$space}-#{$direction}: #{$size*$uni-space-root}px + } @else { + #{$space}-#{$direction}: #{-$size*$uni-space-root}px + } +} +@mixin get-styles($direction,$i,$space,$n){ + @if $direction == t { + @include fn($space, top,$i,$n); + } + @if $direction == r { + @include fn($space, right,$i,$n); + } + @if $direction == b { + @include fn($space, bottom,$i,$n); + } + @if $direction == l { + @include fn($space, left,$i,$n); + } + @if $direction == x { + @include fn($space, left,$i,$n); + @include fn($space, right,$i,$n); + } + @if $direction == y { + @include fn($space, top,$i,$n); + @include fn($space, bottom,$i,$n); + } + @if $direction == a { + @if $n { + #{$space}:#{$i*$uni-space-root}px; + } @else { + #{$space}:#{-$i*$uni-space-root}px; + } + } +} + +@each $orientation in m,p { + $space: margin; + @if $orientation == m { + $space: margin; + } @else { + $space: padding; + } + @for $i from 0 through 16 { + @each $direction in t, r, b, l, x, y, a { + .uni-#{$orientation}#{$direction}-#{$i} { + @include get-styles($direction,$i,$space,true); + } + .uni-#{$orientation}#{$direction}-n#{$i} { + @include get-styles($direction,$i,$space,false); + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uni-scss/styles/setting/_styles.scss b/uni_modules/uni-scss/styles/setting/_styles.scss new file mode 100644 index 0000000..689afec --- /dev/null +++ b/uni_modules/uni-scss/styles/setting/_styles.scss @@ -0,0 +1,167 @@ +/* #ifndef APP-NVUE */ + +$-color-white:#fff; +$-color-black:#000; +@mixin base-style($color) { + color: #fff; + background-color: $color; + border-color: mix($-color-black, $color, 8%); + &:not([hover-class]):active { + background: mix($-color-black, $color, 10%); + border-color: mix($-color-black, $color, 20%); + color: $-color-white; + outline: none; + } +} +@mixin is-color($color) { + @include base-style($color); + &[loading] { + @include base-style($color); + &::before { + margin-right:5px; + } + } + &[disabled] { + &, + &[loading], + &:not([hover-class]):active { + color: $-color-white; + border-color: mix(darken($color,10%), $-color-white); + background-color: mix($color, $-color-white); + } + } + +} +@mixin base-plain-style($color) { + color:$color; + background-color: mix($-color-white, $color, 90%); + border-color: mix($-color-white, $color, 70%); + &:not([hover-class]):active { + background: mix($-color-white, $color, 80%); + color: $color; + outline: none; + border-color: mix($-color-white, $color, 50%); + } +} +@mixin is-plain($color){ + &[plain] { + @include base-plain-style($color); + &[loading] { + @include base-plain-style($color); + &::before { + margin-right:5px; + } + } + &[disabled] { + &, + &:active { + color: mix($-color-white, $color, 40%); + background-color: mix($-color-white, $color, 90%); + border-color: mix($-color-white, $color, 80%); + } + } + } +} + + +.uni-btn { + margin: 5px; + color: #393939; + border:1px solid #ccc; + font-size: 16px; + font-weight: 200; + background-color: #F9F9F9; + // TODO 暂时处理边框隐藏一边的问题 + overflow: visible; + &::after{ + border: none; + } + + &:not([type]),&[type=default] { + color: #999; + &[loading] { + background: none; + &::before { + margin-right:5px; + } + } + + + + &[disabled]{ + color: mix($-color-white, #999, 60%); + &, + &[loading], + &:active { + color: mix($-color-white, #999, 60%); + background-color: mix($-color-white,$-color-black , 98%); + border-color: mix($-color-white, #999, 85%); + } + } + + &[plain] { + color: #999; + background: none; + border-color: $uni-border-1; + &:not([hover-class]):active { + background: none; + color: mix($-color-white, $-color-black, 80%); + border-color: mix($-color-white, $-color-black, 90%); + outline: none; + } + &[disabled]{ + &, + &[loading], + &:active { + background: none; + color: mix($-color-white, #999, 60%); + border-color: mix($-color-white, #999, 85%); + } + } + } + } + + &:not([hover-class]):active { + color: mix($-color-white, $-color-black, 50%); + } + + &[size=mini] { + font-size: 16px; + font-weight: 200; + border-radius: 8px; + } + + + + &.uni-btn-small { + font-size: 14px; + } + &.uni-btn-mini { + font-size: 12px; + } + + &.uni-btn-radius { + border-radius: 999px; + } + &[type=primary] { + @include is-color($uni-primary); + @include is-plain($uni-primary) + } + &[type=success] { + @include is-color($uni-success); + @include is-plain($uni-success) + } + &[type=error] { + @include is-color($uni-error); + @include is-plain($uni-error) + } + &[type=warning] { + @include is-color($uni-warning); + @include is-plain($uni-warning) + } + &[type=info] { + @include is-color($uni-info); + @include is-plain($uni-info) + } +} +/* #endif */ diff --git a/uni_modules/uni-scss/styles/setting/_text.scss b/uni_modules/uni-scss/styles/setting/_text.scss new file mode 100644 index 0000000..a34d08f --- /dev/null +++ b/uni_modules/uni-scss/styles/setting/_text.scss @@ -0,0 +1,24 @@ +@mixin get-styles($k,$c) { + @if $k == size or $k == weight{ + font-#{$k}:#{$c} + }@else{ + #{$k}:#{$c} + } +} + +@each $key, $child in $uni-headings { + /* #ifndef APP-NVUE */ + .uni-#{$key} { + @each $k, $c in $child { + @include get-styles($k,$c) + } + } + /* #endif */ + /* #ifdef APP-NVUE */ + .container .uni-#{$key} { + @each $k, $c in $child { + @include get-styles($k,$c) + } + } + /* #endif */ +} diff --git a/uni_modules/uni-scss/styles/setting/_variables.scss b/uni_modules/uni-scss/styles/setting/_variables.scss new file mode 100644 index 0000000..557d3d7 --- /dev/null +++ b/uni_modules/uni-scss/styles/setting/_variables.scss @@ -0,0 +1,146 @@ +// @use "sass:math"; +@import '../tools/functions.scss'; +// 间距基础倍数 +$uni-space-root: 2 !default; +// 边框半径默认值 +$uni-radius-root:5px !default; +$uni-radius: () !default; +// 边框半径断点 +$uni-radius: map-deep-merge( + ( + 0: 0, + // TODO 当前版本暂时不支持 sm 属性 + // 'sm': math.div($uni-radius-root, 2), + null: $uni-radius-root, + 'lg': $uni-radius-root * 2, + 'xl': $uni-radius-root * 6, + 'pill': 9999px, + 'circle': 50% + ), + $uni-radius +); +// 字体家族 +$body-font-family: 'Roboto', sans-serif !default; +// 文本 +$heading-font-family: $body-font-family !default; +$uni-headings: () !default; +$letterSpacing: -0.01562em; +$uni-headings: map-deep-merge( + ( + 'h1': ( + size: 32px, + weight: 300, + line-height: 50px, + // letter-spacing:-0.01562em + ), + 'h2': ( + size: 28px, + weight: 300, + line-height: 40px, + // letter-spacing: -0.00833em + ), + 'h3': ( + size: 24px, + weight: 400, + line-height: 32px, + // letter-spacing: normal + ), + 'h4': ( + size: 20px, + weight: 400, + line-height: 30px, + // letter-spacing: 0.00735em + ), + 'h5': ( + size: 16px, + weight: 400, + line-height: 24px, + // letter-spacing: normal + ), + 'h6': ( + size: 14px, + weight: 500, + line-height: 18px, + // letter-spacing: 0.0125em + ), + 'subtitle': ( + size: 12px, + weight: 400, + line-height: 20px, + // letter-spacing: 0.00937em + ), + 'body': ( + font-size: 14px, + font-weight: 400, + line-height: 22px, + // letter-spacing: 0.03125em + ), + 'caption': ( + 'size': 12px, + 'weight': 400, + 'line-height': 20px, + // 'letter-spacing': 0.03333em, + // 'text-transform': false + ) + ), + $uni-headings +); + + + +// 主色 +$uni-primary: #2979ff !default; +$uni-primary-disable:lighten($uni-primary,20%) !default; +$uni-primary-light: lighten($uni-primary,25%) !default; + +// 辅助色 +// 除了主色外的场景色,需要在不同的场景中使用(例如危险色表示危险的操作)。 +$uni-success: #18bc37 !default; +$uni-success-disable:lighten($uni-success,20%) !default; +$uni-success-light: lighten($uni-success,25%) !default; + +$uni-warning: #f3a73f !default; +$uni-warning-disable:lighten($uni-warning,20%) !default; +$uni-warning-light: lighten($uni-warning,25%) !default; + +$uni-error: #e43d33 !default; +$uni-error-disable:lighten($uni-error,20%) !default; +$uni-error-light: lighten($uni-error,25%) !default; + +$uni-info: #8f939c !default; +$uni-info-disable:lighten($uni-info,20%) !default; +$uni-info-light: lighten($uni-info,25%) !default; + +// 中性色 +// 中性色用于文本、背景和边框颜色。通过运用不同的中性色,来表现层次结构。 +$uni-main-color: #3a3a3a !default; // 主要文字 +$uni-base-color: #6a6a6a !default; // 常规文字 +$uni-secondary-color: #909399 !default; // 次要文字 +$uni-extra-color: #c7c7c7 !default; // 辅助说明 + +// 边框颜色 +$uni-border-1: #F0F0F0 !default; +$uni-border-2: #EDEDED !default; +$uni-border-3: #DCDCDC !default; +$uni-border-4: #B9B9B9 !default; + +// 常规色 +$uni-black: #000000 !default; +$uni-white: #ffffff !default; +$uni-transparent: rgba($color: #000000, $alpha: 0) !default; + +// 背景色 +$uni-bg-color: #f7f7f7 !default; + +/* 水平间距 */ +$uni-spacing-sm: 8px !default; +$uni-spacing-base: 15px !default; +$uni-spacing-lg: 30px !default; + +// 阴影 +$uni-shadow-sm:0 0 5px rgba($color: #d8d8d8, $alpha: 0.5) !default; +$uni-shadow-base:0 1px 8px 1px rgba($color: #a5a5a5, $alpha: 0.2) !default; +$uni-shadow-lg:0px 1px 10px 2px rgba($color: #a5a4a4, $alpha: 0.5) !default; + +// 蒙版 +$uni-mask: rgba($color: #000000, $alpha: 0.4) !default; diff --git a/uni_modules/uni-scss/styles/tools/functions.scss b/uni_modules/uni-scss/styles/tools/functions.scss new file mode 100644 index 0000000..ac6f63e --- /dev/null +++ b/uni_modules/uni-scss/styles/tools/functions.scss @@ -0,0 +1,19 @@ +// 合并 map +@function map-deep-merge($parent-map, $child-map){ + $result: $parent-map; + @each $key, $child in $child-map { + $parent-has-key: map-has-key($result, $key); + $parent-value: map-get($result, $key); + $parent-type: type-of($parent-value); + $child-type: type-of($child); + $parent-is-map: $parent-type == map; + $child-is-map: $child-type == map; + + @if (not $parent-has-key) or ($parent-type != $child-type) or (not ($parent-is-map and $child-is-map)){ + $result: map-merge($result, ( $key: $child )); + }@else { + $result: map-merge($result, ( $key: map-deep-merge($parent-value, $child) )); + } + } + @return $result; +}; diff --git a/uni_modules/uni-scss/theme.scss b/uni_modules/uni-scss/theme.scss new file mode 100644 index 0000000..80ee62f --- /dev/null +++ b/uni_modules/uni-scss/theme.scss @@ -0,0 +1,31 @@ +// 间距基础倍数 +$uni-space-root: 2; +// 边框半径默认值 +$uni-radius-root:5px; +// 主色 +$uni-primary: #2979ff; +// 辅助色 +$uni-success: #4cd964; +// 警告色 +$uni-warning: #f0ad4e; +// 错误色 +$uni-error: #dd524d; +// 描述色 +$uni-info: #909399; +// 中性色 +$uni-main-color: #303133; +$uni-base-color: #606266; +$uni-secondary-color: #909399; +$uni-extra-color: #C0C4CC; +// 背景色 +$uni-bg-color: #f5f5f5; +// 边框颜色 +$uni-border-1: #DCDFE6; +$uni-border-2: #E4E7ED; +$uni-border-3: #EBEEF5; +$uni-border-4: #F2F6FC; + +// 常规色 +$uni-black: #000000; +$uni-white: #ffffff; +$uni-transparent: rgba($color: #000000, $alpha: 0); diff --git a/uni_modules/uni-scss/variables.scss b/uni_modules/uni-scss/variables.scss new file mode 100644 index 0000000..1c062d4 --- /dev/null +++ b/uni_modules/uni-scss/variables.scss @@ -0,0 +1,62 @@ +@import './styles/setting/_variables.scss'; +// 间距基础倍数 +$uni-space-root: 2; +// 边框半径默认值 +$uni-radius-root:5px; + +// 主色 +$uni-primary: #2979ff; +$uni-primary-disable:mix(#fff,$uni-primary,50%); +$uni-primary-light: mix(#fff,$uni-primary,80%); + +// 辅助色 +// 除了主色外的场景色,需要在不同的场景中使用(例如危险色表示危险的操作)。 +$uni-success: #18bc37; +$uni-success-disable:mix(#fff,$uni-success,50%); +$uni-success-light: mix(#fff,$uni-success,80%); + +$uni-warning: #f3a73f; +$uni-warning-disable:mix(#fff,$uni-warning,50%); +$uni-warning-light: mix(#fff,$uni-warning,80%); + +$uni-error: #e43d33; +$uni-error-disable:mix(#fff,$uni-error,50%); +$uni-error-light: mix(#fff,$uni-error,80%); + +$uni-info: #8f939c; +$uni-info-disable:mix(#fff,$uni-info,50%); +$uni-info-light: mix(#fff,$uni-info,80%); + +// 中性色 +// 中性色用于文本、背景和边框颜色。通过运用不同的中性色,来表现层次结构。 +$uni-main-color: #3a3a3a; // 主要文字 +$uni-base-color: #6a6a6a; // 常规文字 +$uni-secondary-color: #909399; // 次要文字 +$uni-extra-color: #c7c7c7; // 辅助说明 + +// 边框颜色 +$uni-border-1: #F0F0F0; +$uni-border-2: #EDEDED; +$uni-border-3: #DCDCDC; +$uni-border-4: #B9B9B9; + +// 常规色 +$uni-black: #000000; +$uni-white: #ffffff; +$uni-transparent: rgba($color: #000000, $alpha: 0); + +// 背景色 +$uni-bg-color: #f7f7f7; + +/* 水平间距 */ +$uni-spacing-sm: 8px; +$uni-spacing-base: 15px; +$uni-spacing-lg: 30px; + +// 阴影 +$uni-shadow-sm:0 0 5px rgba($color: #d8d8d8, $alpha: 0.5); +$uni-shadow-base:0 1px 8px 1px rgba($color: #a5a5a5, $alpha: 0.2); +$uni-shadow-lg:0px 1px 10px 2px rgba($color: #a5a4a4, $alpha: 0.5); + +// 蒙版 +$uni-mask: rgba($color: #000000, $alpha: 0.4); diff --git a/uni_modules/uni-swipe-action/changelog.md b/uni_modules/uni-swipe-action/changelog.md new file mode 100644 index 0000000..998e476 --- /dev/null +++ b/uni_modules/uni-swipe-action/changelog.md @@ -0,0 +1,58 @@ +## 1.3.16(2025-06-11) +- 修复 鸿蒙 next 浏览器上无法滑动的问题 +## 1.3.14(2025-06-09) +- 优化 更新示例项目 +## 1.3.13(2025-04-15) +- 修复 app 端 缺少leftOptions 或 rightOptions 时无法滑动的问题 +## 1.3.12(2025-04-14) +- 修复 由上一个兼容版本引发的 安卓运行报错且无法回弹的问题 +## 1.3.11(2025-04-08) +- 优化 兼容鸿蒙平台 +- 修复 WEB 平台控制台报错 +## 1.3.10(2024-01-17) +- 修复 点击按钮时,按钮会被点击穿透导致自动收缩的 bug(兼容阿里/百度/抖音小程序) +## 1.3.9(2024-01-17) +- 修复 点击按钮时,按钮会被点击穿透导致自动收缩的 bug +## 1.3.8(2023-04-13) +- 修复`uni-swipe-action`和`uni-swipe-action-item`不同时使用导致 closeOther 方法报错的 bug +## 1.3.7(2022-06-06) +- 修复 vue3 下使用组件不能正常运行的Bug +## 1.3.6(2022-05-31) +- 修复 h5端点击click触发两次的Bug +## 1.3.5(2022-05-23) +- 修复 isPC 找不到的Bug +## 1.3.4(2022-05-19) +- 修复 在 nvue 下 disabled 失效的bug +## 1.3.3(2022-03-31) +- 修复 按钮字体大小不能设置的bug +## 1.3.2(2022-03-16) +- 修复 h5和app端下报el错误的bug +## 1.3.1(2022-03-07) +- 修复 HBuilderX 1.4.X 版本中,h5和app端下报错的bug +## 1.3.0(2021-11-19) +- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource) +- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-swipe-action](https://uniapp.dcloud.io/component/uniui/uni-swipe-action) +## 1.2.4(2021-08-20) +- 优化 close-all 方法 +## 1.2.3(2021-08-20) +- 新增 close-all 方法,关闭所有已打开的组件 +## 1.2.2(2021-08-17) +- 新增 resize() 方法,在非微信小程序、h5、app-vue端出现不能滑动的问题的时候,重置组件 +- 修复 app 端偶尔出现类似 Page[x][-x,xx;-x,xx,x,x-x] 的问题 +- 优化 微信小程序、h5、app-vue 滑动逻辑,避免出现动态新增组件后不能滑动的问题 +## 1.2.1(2021-07-30) +- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834) +- 修复 跨页面修改组件数据 ,导致不能滑动的问题 +## 1.1.10(2021-06-17) +- 修复 按钮点击执行两次的bug +## 1.1.9(2021-05-12) +- 新增 项目示例地址 +## 1.1.8(2021-03-26) +- 修复 微信小程序 nv_navigator is not defined 报错的bug +## 1.1.7(2021-02-05) +- 调整为uni_modules目录规范 +- 新增 左侧滑动 +- 新增 插槽使用方式 +- 新增 threshold 属性,可以控制滑动缺省值 +- 优化 长列表滚动性能 +- 修复 滚动页面时触发组件滑动的Bug diff --git a/uni_modules/uni-swipe-action/components/uni-swipe-action-item/bindingx.js b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/bindingx.js new file mode 100644 index 0000000..707e432 --- /dev/null +++ b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/bindingx.js @@ -0,0 +1,302 @@ +let bindIngXMixins = {} + +// #ifdef APP-NVUE +const BindingX = uni.requireNativePlugin('bindingx'); +const dom = uni.requireNativePlugin('dom'); +const animation = uni.requireNativePlugin('animation'); + +bindIngXMixins = { + data() { + return {} + }, + + watch: { + show(newVal) { + if (this.autoClose) return + if (this.stop) return + this.stop = true + if (newVal) { + this.open(newVal) + } else { + this.close() + } + }, + leftOptions() { + this.getSelectorQuery() + this.init() + }, + rightOptions(newVal) { + this.init() + } + }, + created() { + this.swipeaction = this.getSwipeAction() + if (this.swipeaction && Array.isArray(this.swipeaction.children)) { + this.swipeaction.children.push(this) + } + }, + mounted() { + this.box = this.getEl(this.$refs['selector-box--hock']) + this.selector = this.getEl(this.$refs['selector-content--hock']); + this.leftButton = this.getEl(this.$refs['selector-left-button--hock']); + this.rightButton = this.getEl(this.$refs['selector-right-button--hock']); + this.init() + }, + // beforeDestroy() { + // this.swipeaction.children.forEach((item, index) => { + // if (item === this) { + // this.swipeaction.children.splice(index, 1) + // } + // }) + // }, + methods: { + init() { + this.$nextTick(() => { + this.x = 0 + this.button = { + show: false + } + setTimeout(() => { + this.getSelectorQuery() + }, 200) + }) + }, + onClick(index, item, position) { + this.$emit('click', { + content: item, + index, + position + }) + }, + touchstart(e) { + // fix by mehaotian 禁止滑动 + if (this.disabled) return + // 每次只触发一次,避免多次监听造成闪烁 + if (this.stop) return + this.stop = true + if (this.autoClose && this.swipeaction) { + this.swipeaction.closeOther(this) + } + + const leftWidth = this.button.left.width + const rightWidth = this.button.right.width + let expression = this.range(this.x, -rightWidth, leftWidth) + let leftExpression = this.range(this.x - leftWidth, -leftWidth, 0) + let rightExpression = this.range(this.x + rightWidth, 0, rightWidth) + + this.eventpan = BindingX.bind({ + anchor: this.box, + eventType: 'pan', + props: [{ + element: this.selector, + property: 'transform.translateX', + expression + }, { + element: this.leftButton, + property: 'transform.translateX', + expression: leftExpression + }, { + element: this.rightButton, + property: 'transform.translateX', + expression: rightExpression + }, ] + }, (e) => { + // nope + if (e.state === 'end') { + this.x = e.deltaX + this.x; + this.isclick = true + this.bindTiming(e.deltaX) + } + }); + }, + touchend(e) { + if (this.isopen !== 'none' && !this.isclick) { + this.open('none') + } + }, + bindTiming(x) { + const left = this.x + const leftWidth = this.button.left.width + const rightWidth = this.button.right.width + const threshold = this.threshold + if (!this.isopen || this.isopen === 'none') { + if (left > threshold) { + this.open('left') + } else if (left < -threshold) { + this.open('right') + } else { + this.open('none') + } + } else { + if ((x > -leftWidth && x < 0) || x > rightWidth) { + if ((x > -threshold && x < 0) || (x - rightWidth > threshold)) { + this.open('left') + } else { + this.open('none') + } + } else { + if ((x < threshold && x > 0) || (x + leftWidth < -threshold)) { + this.open('right') + } else { + this.open('none') + } + } + } + }, + + /** + * 移动范围 + * @param {Object} num + * @param {Object} mix + * @param {Object} max + */ + range(num, mix, max) { + return `min(max(x+${num}, ${mix}), ${max})` + }, + + /** + * 开启swipe + */ + open(type) { + this.animation(type) + }, + + /** + * 关闭swipe + */ + close() { + this.animation('none') + }, + + /** + * 开启关闭动画 + * @param {Object} type + */ + animation(type) { + const time = 300 + const leftWidth = this.button.left.width + const rightWidth = this.button.right.width + if (this.eventpan && this.eventpan.token) { + BindingX.unbind({ + token: this.eventpan.token, + eventType: 'pan' + }) + } + + switch (type) { + case 'left': + Promise.all([ + this.move(this.selector, leftWidth), + this.move(this.leftButton, 0), + this.move(this.rightButton, rightWidth * 2) + ]).then(() => { + this.setEmit(leftWidth, type) + }) + break + case 'right': + Promise.all([ + this.move(this.selector, -rightWidth), + this.move(this.leftButton, -leftWidth * 2), + this.move(this.rightButton, 0) + ]).then(() => { + this.setEmit(-rightWidth, type) + }) + break + default: + Promise.all([ + this.move(this.selector, 0), + this.move(this.leftButton, -leftWidth), + this.move(this.rightButton, rightWidth) + ]).then(() => { + this.setEmit(0, type) + }) + + } + }, + setEmit(x, type) { + const leftWidth = this.button.left.width + const rightWidth = this.button.right.width + this.isopen = this.isopen || 'none' + this.stop = false + this.isclick = false + // 只有状态不一致才会返回结果 + if (this.isopen !== type && this.x !== x) { + if (type === 'left' && leftWidth > 0) { + this.$emit('change', 'left') + } + if (type === 'right' && rightWidth > 0) { + this.$emit('change', 'right') + } + if (type === 'none') { + this.$emit('change', 'none') + } + } + this.x = x + this.isopen = type + }, + move(ref, value) { + return new Promise((resolve, reject) => { + animation.transition(ref, { + styles: { + transform: `translateX(${value})`, + }, + duration: 150, //ms + timingFunction: 'linear', + needLayout: false, + delay: 0 //ms + }, function(res) { + resolve(res) + }) + }) + + }, + + /** + * 获取ref + * @param {Object} el + */ + getEl(el) { + return el.ref + }, + /** + * 获取节点信息 + */ + getSelectorQuery() { + Promise.all([ + this.getDom('left'), + this.getDom('right'), + ]).then((data) => { + let show = 'none' + if (this.autoClose) { + show = 'none' + } else { + show = this.show + } + + if (show === 'none') { + // this.close() + } else { + this.open(show) + } + + }) + + }, + getDom(str) { + return new Promise((resolve, reject) => { + dom.getComponentRect(this.$refs[`selector-${str}-button--hock`], (data) => { + if (data) { + this.button[str] = data.size + resolve(data) + } else { + reject() + } + }) + }) + } + } +} + +// #endif + +export default bindIngXMixins diff --git a/uni_modules/uni-swipe-action/components/uni-swipe-action-item/isPC.js b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/isPC.js new file mode 100644 index 0000000..917cb48 --- /dev/null +++ b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/isPC.js @@ -0,0 +1,12 @@ +export function isPC() { + var userAgentInfo = navigator.userAgent; + var Agents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"]; + var flag = true; + for (let v = 0; v < Agents.length - 1; v++) { + if (userAgentInfo.indexOf(Agents[v]) > 0) { + flag = false; + break; + } + } + return flag; +} diff --git a/uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpalipay.js b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpalipay.js new file mode 100644 index 0000000..35c796b --- /dev/null +++ b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpalipay.js @@ -0,0 +1,195 @@ +export default { + data() { + return { + x: 0, + transition: false, + width: 0, + viewWidth: 0, + swipeShow: 0 + } + }, + watch: { + show(newVal) { + if (this.autoClose) return + if (newVal && newVal !== 'none') { + this.transition = true + this.open(newVal) + } else { + this.close() + } + } + }, + created() { + this.swipeaction = this.getSwipeAction() + if (this.swipeaction && Array.isArray(this.swipeaction.children)) { + this.swipeaction.children.push(this) + } + }, + mounted() { + this.isopen = false + setTimeout(() => { + this.getQuerySelect() + }, 50) + }, + methods: { + appTouchStart(e) { + const { + clientX + } = e.changedTouches[0] + this.clientX = clientX + this.timestamp = new Date().getTime() + }, + appTouchEnd(e, index, item, position) { + const { + clientX + } = e.changedTouches[0] + // fixed by xxxx 模拟点击事件,解决 ios 13 点击区域错位的问题 + let diff = Math.abs(this.clientX - clientX) + let time = (new Date().getTime()) - this.timestamp + if (diff < 40 && time < 300) { + this.$emit('click', { + content: item, + index, + position + }) + } + }, + /** + * 移动触发 + * @param {Object} e + */ + onChange(e) { + this.moveX = e.detail.x + this.isclose = false + }, + touchstart(e) { + this.transition = false + this.isclose = true + if (this.autoClose && this.swipeaction) { + this.swipeaction.closeOther(this) + } + }, + touchmove(e) {}, + touchend(e) { + // 0的位置什么都不执行 + if (this.isclose && this.isopen === 'none') return + if (this.isclose && this.isopen !== 'none') { + this.transition = true + this.close() + } else { + this.move(this.moveX + this.leftWidth) + } + }, + + /** + * 移动 + * @param {Object} moveX + */ + move(moveX) { + // 打开关闭的处理逻辑不太一样 + this.transition = true + // 未打开状态 + if (!this.isopen || this.isopen === 'none') { + if (moveX > this.threshold) { + this.open('left') + } else if (moveX < -this.threshold) { + this.open('right') + } else { + this.close() + } + } else { + if (moveX < 0 && moveX < this.rightWidth) { + const rightX = this.rightWidth + moveX + if (rightX < this.threshold) { + this.open('right') + } else { + this.close() + } + } else if (moveX > 0 && moveX < this.leftWidth) { + const leftX = this.leftWidth - moveX + if (leftX < this.threshold) { + this.open('left') + } else { + this.close() + } + } + + } + + }, + + /** + * 打开 + */ + open(type) { + this.x = this.moveX + this.animation(type) + }, + + /** + * 关闭 + */ + close() { + this.x = this.moveX + // TODO 解决 x 值不更新的问题,所以会多触发一次 nextTick ,待优化 + this.$nextTick(() => { + this.x = -this.leftWidth + if (this.isopen !== 'none') { + this.$emit('change', 'none') + } + this.isopen = 'none' + }) + }, + + /** + * 执行结束动画 + * @param {Object} type + */ + animation(type) { + this.$nextTick(() => { + if (type === 'left') { + this.x = 0 + } else { + this.x = -this.rightWidth - this.leftWidth + } + + if (this.isopen !== type) { + this.$emit('change', type) + } + this.isopen = type + }) + + }, + getSlide(x) {}, + getQuerySelect() { + const query = uni.createSelectorQuery().in(this); + query.selectAll('.movable-view--hock').boundingClientRect(data => { + this.leftWidth = data[1].width + this.rightWidth = data[2].width + this.width = data[0].width + this.viewWidth = this.width + this.rightWidth + this.leftWidth + if (this.leftWidth === 0) { + // TODO 疑似bug ,初始化的时候如果x 是0,会导致移动位置错误,所以让元素超出一点 + this.x = -0.1 + } else { + this.x = -this.leftWidth + } + this.moveX = this.x + this.$nextTick(() => { + this.swipeShow = 1 + }) + + if (!this.buttonWidth) { + this.disabledView = true + } + + if (this.autoClose) return + if (this.show !== 'none') { + this.transition = true + this.open(this.shows) + } + }).exec(); + + } + } +} diff --git a/uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpother.js b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpother.js new file mode 100644 index 0000000..d389bce --- /dev/null +++ b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpother.js @@ -0,0 +1,260 @@ +let otherMixins = {} + +// #ifndef APP-PLUS|| MP-WEIXIN || H5 +const MIN_DISTANCE = 10; +otherMixins = { + data() { + // TODO 随机生生元素ID,解决百度小程序获取同一个元素位置信息的bug + const elClass = `Uni_${Math.ceil(Math.random() * 10e5).toString(36)}` + return { + uniShow: false, + left: 0, + buttonShow: 'none', + ani: false, + moveLeft: '', + elClass + } + }, + watch: { + show(newVal) { + if (this.autoClose) return + this.openState(newVal) + }, + left() { + this.moveLeft = `translateX(${this.left}px)` + }, + buttonShow(newVal) { + if (this.autoClose) return + this.openState(newVal) + }, + leftOptions() { + this.init() + }, + rightOptions() { + this.init() + } + }, + mounted() { + this.swipeaction = this.getSwipeAction() + if (this.swipeaction && Array.isArray(this.swipeaction.children)) { + this.swipeaction.children.push(this) + } + this.init() + }, + methods: { + init() { + clearTimeout(this.timer) + this.timer = setTimeout(() => { + this.getSelectorQuery() + }, 100) + // 移动距离 + this.left = 0 + this.x = 0 + }, + + closeSwipe(e) { + if (this.autoClose && this.swipeaction) { + this.swipeaction.closeOther(this) + } + }, + appTouchStart(e) { + const { + clientX + } = e.changedTouches[0] + this.clientX = clientX + this.timestamp = new Date().getTime() + }, + appTouchEnd(e, index, item, position) { + const { + clientX + } = e.changedTouches[0] + // fixed by xxxx 模拟点击事件,解决 ios 13 点击区域错位的问题 + let diff = Math.abs(this.clientX - clientX) + let time = (new Date().getTime()) - this.timestamp + if (diff < 40 && time < 300) { + this.$emit('click', { + content: item, + index, + position + }) + } + }, + touchstart(e) { + if (this.disabled) return + this.ani = false + this.x = this.left || 0 + this.stopTouchStart(e) + this.autoClose && this.closeSwipe() + }, + touchmove(e) { + if (this.disabled) return + // 是否可以滑动页面 + this.stopTouchMove(e); + if (this.direction !== 'horizontal') { + return; + } + this.move(this.x + this.deltaX) + return false + }, + touchend() { + if (this.disabled) return + this.moveDirection(this.left) + }, + /** + * 设置移动距离 + * @param {Object} value + */ + move(value) { + value = value || 0 + const leftWidth = this.leftWidth + const rightWidth = this.rightWidth + // 获取可滑动范围 + this.left = this.range(value, -rightWidth, leftWidth); + }, + + /** + * 获取范围 + * @param {Object} num + * @param {Object} min + * @param {Object} max + */ + range(num, min, max) { + return Math.min(Math.max(num, min), max); + }, + /** + * 移动方向判断 + * @param {Object} left + * @param {Object} value + */ + moveDirection(left) { + const threshold = this.threshold + const isopen = this.isopen || 'none' + const leftWidth = this.leftWidth + const rightWidth = this.rightWidth + if (this.deltaX === 0) { + this.openState('none') + return + } + if ((isopen === 'none' && rightWidth > 0 && -left > threshold) || (isopen !== 'none' && rightWidth > + 0 && rightWidth + + left < threshold)) { + // right + this.openState('right') + } else if ((isopen === 'none' && leftWidth > 0 && left > threshold) || (isopen !== 'none' && leftWidth > + 0 && + leftWidth - left < threshold)) { + // left + this.openState('left') + } else { + // default + this.openState('none') + } + }, + + /** + * 开启状态 + * @param {Boolean} type + */ + openState(type) { + const leftWidth = this.leftWidth + const rightWidth = this.rightWidth + let left = '' + this.isopen = this.isopen ? this.isopen : 'none' + switch (type) { + case "left": + left = leftWidth + break + case "right": + left = -rightWidth + break + default: + left = 0 + } + + + if (this.isopen !== type) { + this.throttle = true + this.$emit('change', type) + } + + this.isopen = type + // 添加动画类 + this.ani = true + this.$nextTick(() => { + this.move(left) + }) + // 设置最终移动位置,理论上只要进入到这个函数,肯定是要打开的 + }, + close() { + this.openState('none') + }, + getDirection(x, y) { + if (x > y && x > MIN_DISTANCE) { + return 'horizontal'; + } + if (y > x && y > MIN_DISTANCE) { + return 'vertical'; + } + return ''; + }, + + /** + * 重置滑动状态 + * @param {Object} event + */ + resetTouchStatus() { + this.direction = ''; + this.deltaX = 0; + this.deltaY = 0; + this.offsetX = 0; + this.offsetY = 0; + }, + + /** + * 设置滑动开始位置 + * @param {Object} event + */ + stopTouchStart(event) { + this.resetTouchStatus(); + const touch = event.touches[0]; + this.startX = touch.clientX; + this.startY = touch.clientY; + }, + + /** + * 滑动中,是否禁止打开 + * @param {Object} event + */ + stopTouchMove(event) { + const touch = event.touches[0]; + this.deltaX = touch.clientX - this.startX; + this.deltaY = touch.clientY - this.startY; + this.offsetX = Math.abs(this.deltaX); + this.offsetY = Math.abs(this.deltaY); + this.direction = this.direction || this.getDirection(this.offsetX, this.offsetY); + }, + + getSelectorQuery() { + const views = uni.createSelectorQuery().in(this) + views + .selectAll('.' + this.elClass) + .boundingClientRect(data => { + if (data.length === 0) return + let show = 'none' + if (this.autoClose) { + show = 'none' + } else { + show = this.show + } + this.leftWidth = data[0].width || 0 + this.rightWidth = data[1].width || 0 + this.buttonShow = show + }) + .exec() + } + } +} + +// #endif + +export default otherMixins diff --git a/uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpwxs.js b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpwxs.js new file mode 100644 index 0000000..0b5de88 --- /dev/null +++ b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpwxs.js @@ -0,0 +1,84 @@ +let mpMixins = {} +let is_pc = null +// #ifdef H5 +import { + isPC +} from "./isPC" +is_pc = isPC() +// #endif +// #ifdef APP-VUE || APP-HARMONY || MP-WEIXIN || H5 + +mpMixins = { + data() { + return { + is_show: 'none' + } + }, + watch: { + show(newVal) { + this.is_show = this.show + } + }, + created() { + this.swipeaction = this.getSwipeAction() + if (this.swipeaction && Array.isArray(this.swipeaction.children)) { + this.swipeaction.children.push(this) + } + }, + mounted() { + this.is_show = this.show + }, + methods: { + // wxs 中调用 + closeSwipe(e) { + if (this.autoClose && this.swipeaction) { + this.swipeaction.closeOther(this) + } + }, + + change(e) { + this.$emit('change', e.open) + if (this.is_show !== e.open) { + this.is_show = e.open + } + }, + + appTouchStart(e) { + if (is_pc) return + const { + clientX + } = e.changedTouches[0] + this.clientX = clientX + this.timestamp = new Date().getTime() + }, + appTouchEnd(e, index, item, position) { + if (is_pc) return + const { + clientX + } = e.changedTouches[0] + // fixed by xxxx 模拟点击事件,解决 ios 13 点击区域错位的问题 + let diff = Math.abs(this.clientX - clientX) + let time = (new Date().getTime()) - this.timestamp + if (diff < 40 && time < 300) { + this.$emit('click', { + content: item, + index, + position + }) + } + }, + onClickForPC(index, item, position) { + if (!is_pc) return + // #ifdef H5 + this.$emit('click', { + content: item, + index, + position + }) + // #endif + } + } +} + +// #endif +export default mpMixins diff --git a/uni_modules/uni-swipe-action/components/uni-swipe-action-item/render.js b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/render.js new file mode 100644 index 0000000..218cb41 --- /dev/null +++ b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/render.js @@ -0,0 +1,277 @@ +const MIN_DISTANCE = 10; +export default { + showWatch(newVal, oldVal, ownerInstance, instance, self) { + var state = self.state || {} + var $el = ownerInstance.$el || ownerInstance.$vm && ownerInstance.$vm.$el + if (!$el) return + this.getDom(instance, ownerInstance, self) + if (newVal && newVal !== 'none') { + this.openState(newVal, instance, ownerInstance, self) + return + } + + if (state.left) { + this.openState('none', instance, ownerInstance, self) + } + this.resetTouchStatus(instance, self) + }, + + /** + * 开始触摸操作 + * @param {Object} e + * @param {Object} ins + */ + touchstart(e, ownerInstance, self) { + let instance = e.instance; + let disabled = instance.getDataset().disabled + let state = self.state || {}; + this.getDom(instance, ownerInstance, self) + // fix by mehaotian, TODO 兼容 app-vue 获取dataset为字符串 , h5 获取 为 undefined 的问题,待框架修复 + disabled = this.getDisabledType(disabled) + if (disabled) return + // 开始触摸时移除动画类 + instance.requestAnimationFrame(function() { + instance.removeClass('ani'); + ownerInstance.callMethod('closeSwipe'); + }) + + // 记录上次的位置 + state.x = state.left || 0 + // 计算滑动开始位置 + this.stopTouchStart(e, ownerInstance, self) + }, + + /** + * 开始滑动操作 + * @param {Object} e + * @param {Object} ownerInstance + */ + touchmove(e, ownerInstance, self) { + let instance = e.instance; + // 删除之后已经那不到实例了 + if (!instance) return; + let disabled = instance.getDataset().disabled + let state = self.state || {} + // fix by mehaotian, TODO 兼容 app-vue 获取dataset为字符串 , h5 获取 为 undefined 的问题,待框架修复 + disabled = this.getDisabledType(disabled) + if (disabled) return + // 是否可以滑动页面 + this.stopTouchMove(e, self); + if (state.direction !== 'horizontal') { + return; + } + if (e.preventDefault) { + // 阻止页面滚动 + e.preventDefault() + } + let x = state.x + state.deltaX + this.move(x, instance, ownerInstance, self) + }, + + /** + * 结束触摸操作 + * @param {Object} e + * @param {Object} ownerInstance + */ + touchend(e, ownerInstance, self) { + let instance = e.instance; + let disabled = instance.getDataset().disabled + let state = self.state || {} + // fix by mehaotian, TODO 兼容 app-vue 获取dataset为字符串 , h5 获取 为 undefined 的问题,待框架修复 + disabled = this.getDisabledType(disabled) + + if (disabled) return + // 滑动过程中触摸结束,通过阙值判断是开启还是关闭 + // fixed by mehaotian 定时器解决点击按钮,touchend 触发比 click 事件时机早的问题 ,主要是 ios13 + this.moveDirection(state.left, instance, ownerInstance, self) + + }, + + /** + * 设置移动距离 + * @param {Object} value + * @param {Object} instance + * @param {Object} ownerInstance + */ + move(value, instance, ownerInstance, self) { + value = value || 0 + let state = self.state || {} + let leftWidth = state.leftWidth + let rightWidth = state.rightWidth + // 获取可滑动范围 + state.left = this.range(value, -rightWidth, leftWidth); + instance.requestAnimationFrame(function() { + instance.setStyle({ + transform: 'translateX(' + state.left + 'px)', + '-webkit-transform': 'translateX(' + state.left + 'px)' + }) + }) + + }, + + /** + * 获取元素信息 + * @param {Object} instance + * @param {Object} ownerInstance + */ + getDom(instance, ownerInstance, self) { + var state = self.state || {} + var $el = ownerInstance.$el || ownerInstance.$vm && ownerInstance.$vm.$el + var leftDom = $el.querySelector('.button-group--left') + var rightDom = $el.querySelector('.button-group--right') + if (leftDom && leftDom.offsetWidth) { + state.leftWidth = leftDom.offsetWidth || 0 + } else { + state.leftWidth = 0 + } + if (rightDom && rightDom.offsetWidth) { + state.rightWidth = rightDom.offsetWidth || 0 + } else { + state.rightWidth = 0 + } + state.threshold = instance.getDataset().threshold + }, + + getDisabledType(value) { + return (typeof(value) === 'string' ? JSON.parse(value) : value) || false; + }, + + /** + * 获取范围 + * @param {Object} num + * @param {Object} min + * @param {Object} max + */ + range(num, min, max) { + return Math.min(Math.max(num, min), max); + }, + + + /** + * 移动方向判断 + * @param {Object} left + * @param {Object} value + * @param {Object} ownerInstance + * @param {Object} ins + */ + moveDirection(left, ins, ownerInstance, self) { + var state = self.state || {} + var threshold = state.threshold + var position = state.position + var isopen = state.isopen || 'none' + var leftWidth = state.leftWidth + var rightWidth = state.rightWidth + if (state.deltaX === 0) { + this.openState('none', ins, ownerInstance, self) + return + } + if ((isopen === 'none' && rightWidth > 0 && -left > threshold) || (isopen !== 'none' && rightWidth > 0 && + rightWidth + + left < threshold)) { + // right + this.openState('right', ins, ownerInstance, self) + } else if ((isopen === 'none' && leftWidth > 0 && left > threshold) || (isopen !== 'none' && leftWidth > 0 && + leftWidth - left < threshold)) { + // left + this.openState('left', ins, ownerInstance, self) + } else { + // default + this.openState('none', ins, ownerInstance, self) + } + }, + + + /** + * 开启状态 + * @param {Boolean} type + * @param {Object} ins + * @param {Object} ownerInstance + */ + openState(type, ins, ownerInstance, self) { + let state = self.state || {} + let leftWidth = state.leftWidth + let rightWidth = state.rightWidth + let left = '' + state.isopen = state.isopen ? state.isopen : 'none' + switch (type) { + case "left": + left = leftWidth + break + case "right": + left = -rightWidth + break + default: + left = 0 + } + + // && !state.throttle + + if (state.isopen !== type) { + state.throttle = true + ownerInstance.callMethod('change', { + open: type + }) + + } + + state.isopen = type + // 添加动画类 + ins.requestAnimationFrame(() => { + ins.addClass('ani'); + this.move(left, ins, ownerInstance, self) + }) + }, + + + getDirection(x, y) { + if (x > y && x > MIN_DISTANCE) { + return 'horizontal'; + } + if (y > x && y > MIN_DISTANCE) { + return 'vertical'; + } + return ''; + }, + + /** + * 重置滑动状态 + * @param {Object} event + */ + resetTouchStatus(instance, self) { + let state = self.state || {}; + state.direction = ''; + state.deltaX = 0; + state.deltaY = 0; + state.offsetX = 0; + state.offsetY = 0; + }, + + /** + * 设置滑动开始位置 + * @param {Object} event + */ + stopTouchStart(event, ownerInstance, self) { + let instance = event.instance; + let state = self.state || {} + this.resetTouchStatus(instance, self); + var touch = event.touches[0]; + state.startX = touch.clientX; + state.startY = touch.clientY; + }, + + /** + * 滑动中,是否禁止打开 + * @param {Object} event + */ + stopTouchMove(event, self) { + let instance = event.instance; + let state = self.state || {}; + let touch = event.touches[0]; + + state.deltaX = touch.clientX - state.startX; + state.deltaY = touch.clientY - state.startY; + state.offsetY = Math.abs(state.deltaY); + state.offsetX = Math.abs(state.deltaX); + state.direction = state.direction || this.getDirection(state.offsetX, state.offsetY); + } +} diff --git a/uni_modules/uni-swipe-action/components/uni-swipe-action-item/uni-swipe-action-item.vue b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/uni-swipe-action-item.vue new file mode 100644 index 0000000..921159b --- /dev/null +++ b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/uni-swipe-action-item.vue @@ -0,0 +1,347 @@ + + + + + + diff --git a/uni_modules/uni-swipe-action/components/uni-swipe-action-item/wx.wxs b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/wx.wxs new file mode 100644 index 0000000..5e5e1ee --- /dev/null +++ b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/wx.wxs @@ -0,0 +1,349 @@ +var MIN_DISTANCE = 10; + +/** + * 判断当前是否为H5、app-vue + */ +var IS_HTML5 = false +if (typeof window === 'object') IS_HTML5 = true + +/** + * 监听页面内值的变化,主要用于动态开关swipe-action + * @param {Object} newValue + * @param {Object} oldValue + * @param {Object} ownerInstance + * @param {Object} instance + */ +function showWatch(newVal, oldVal, ownerInstance, instance) { + var state = instance.getState() + getDom(instance, ownerInstance) + if (newVal && newVal !== 'none') { + openState(newVal, instance, ownerInstance) + return + } + + if (state.left) { + openState('none', instance, ownerInstance) + } + resetTouchStatus(instance) +} + +/** + * 开始触摸操作 + * @param {Object} e + * @param {Object} ins + */ +function touchstart(e, ownerInstance) { + var instance = e.instance; + var disabled = instance.getDataset().disabled + var state = instance.getState(); + getDom(instance, ownerInstance) + // fix by mehaotian, TODO 兼容 app-vue 获取dataset为字符串 , h5 获取 为 undefined 的问题,待框架修复 + disabled = (typeof(disabled) === 'string' ? JSON.parse(disabled) : disabled) || false; + if (disabled) return + // 开始触摸时移除动画类 + instance.requestAnimationFrame(function() { + instance.removeClass('ani'); + ownerInstance.callMethod('closeSwipe'); + }) + + // 记录上次的位置 + state.x = state.left || 0 + // 计算滑动开始位置 + stopTouchStart(e, ownerInstance) +} + +/** + * 开始滑动操作 + * @param {Object} e + * @param {Object} ownerInstance + */ +function touchmove(e, ownerInstance) { + var instance = e.instance; + var disabled = instance.getDataset().disabled + var state = instance.getState() + // fix by mehaotian, TODO 兼容 app-vue 获取dataset为字符串 , h5 获取 为 undefined 的问题,待框架修复 + disabled = (typeof(disabled) === 'string' ? JSON.parse(disabled) : disabled) || false; + if (disabled) return + // 是否可以滑动页面 + stopTouchMove(e); + if (state.direction !== 'horizontal') { + return; + } + + if (e.preventDefault) { + // 阻止页面滚动 + e.preventDefault() + } + + move(state.x + state.deltaX, instance, ownerInstance) +} + +/** + * 结束触摸操作 + * @param {Object} e + * @param {Object} ownerInstance + */ +function touchend(e, ownerInstance) { + var instance = e.instance; + var disabled = instance.getDataset().disabled + var state = instance.getState() + // fix by mehaotian, TODO 兼容 app-vue 获取dataset为字符串 , h5 获取 为 undefined 的问题,待框架修复 + disabled = (typeof(disabled) === 'string' ? JSON.parse(disabled) : disabled) || false; + + if (disabled) return + // 滑动过程中触摸结束,通过阙值判断是开启还是关闭 + // fixed by mehaotian 定时器解决点击按钮,touchend 触发比 click 事件时机早的问题 ,主要是 ios13 + moveDirection(state.left, instance, ownerInstance) + +} + +/** + * 设置移动距离 + * @param {Object} value + * @param {Object} instance + * @param {Object} ownerInstance + */ +function move(value, instance, ownerInstance) { + value = value || 0 + var state = instance.getState() + var leftWidth = state.leftWidth + var rightWidth = state.rightWidth + // 获取可滑动范围 + state.left = range(value, -rightWidth, leftWidth); + instance.requestAnimationFrame(function() { + instance.setStyle({ + transform: 'translateX(' + state.left + 'px)', + '-webkit-transform': 'translateX(' + state.left + 'px)' + }) + }) + +} + +/** + * 获取元素信息 + * @param {Object} instance + * @param {Object} ownerInstance + */ +function getDom(instance, ownerInstance) { + var state = instance.getState() + var leftDom = ownerInstance.selectComponent('.button-group--left') + var rightDom = ownerInstance.selectComponent('.button-group--right') + var leftStyles = { + width: 0 + } + var rightStyles = { + width: 0 + } + + if (leftDom) { + leftStyles = leftDom.getBoundingClientRect() + } + + if (rightDom) { + rightStyles = rightDom.getBoundingClientRect() + } + state.leftWidth = leftStyles.width || 0 + state.rightWidth = rightStyles.width || 0 + state.threshold = instance.getDataset().threshold +} + +/** + * 获取范围 + * @param {Object} num + * @param {Object} min + * @param {Object} max + */ +function range(num, min, max) { + return Math.min(Math.max(num, min), max); +} + + +/** + * 移动方向判断 + * @param {Object} left + * @param {Object} value + * @param {Object} ownerInstance + * @param {Object} ins + */ +function moveDirection(left, ins, ownerInstance) { + var state = ins.getState() + var threshold = state.threshold + var position = state.position + var isopen = state.isopen || 'none' + var leftWidth = state.leftWidth + var rightWidth = state.rightWidth + if (state.deltaX === 0) { + openState('none', ins, ownerInstance) + return + } + if ((isopen === 'none' && rightWidth > 0 && -left > threshold) || (isopen !== 'none' && rightWidth > 0 && + rightWidth + + left < threshold)) { + // right + openState('right', ins, ownerInstance) + } else if ((isopen === 'none' && leftWidth > 0 && left > threshold) || (isopen !== 'none' && leftWidth > 0 && + leftWidth - left < threshold)) { + // left + openState('left', ins, ownerInstance) + } else { + // default + openState('none', ins, ownerInstance) + } +} + + +/** + * 开启状态 + * @param {Boolean} type + * @param {Object} ins + * @param {Object} ownerInstance + */ +function openState(type, ins, ownerInstance) { + var state = ins.getState() + var leftWidth = state.leftWidth + var rightWidth = state.rightWidth + var left = '' + state.isopen = state.isopen ? state.isopen : 'none' + switch (type) { + case "left": + left = leftWidth + break + case "right": + left = -rightWidth + break + default: + left = 0 + } + + // && !state.throttle + + if (state.isopen !== type) { + state.throttle = true + ownerInstance.callMethod('change', { + open: type + }) + + } + + state.isopen = type + // 添加动画类 + ins.requestAnimationFrame(function() { + ins.addClass('ani'); + move(left, ins, ownerInstance) + }) + // 设置最终移动位置,理论上只要进入到这个函数,肯定是要打开的 +} + + +function getDirection(x, y) { + if (x > y && x > MIN_DISTANCE) { + return 'horizontal'; + } + if (y > x && y > MIN_DISTANCE) { + return 'vertical'; + } + return ''; +} + +/** + * 重置滑动状态 + * @param {Object} event + */ +function resetTouchStatus(instance) { + var state = instance.getState(); + state.direction = ''; + state.deltaX = 0; + state.deltaY = 0; + state.offsetX = 0; + state.offsetY = 0; +} + +/** + * 设置滑动开始位置 + * @param {Object} event + */ +function stopTouchStart(event) { + var instance = event.instance; + var state = instance.getState(); + resetTouchStatus(instance); + var touch = event.touches[0]; + if (IS_HTML5 && isPC()) { + touch = event; + } + state.startX = touch.clientX; + state.startY = touch.clientY; +} + +/** + * 滑动中,是否禁止打开 + * @param {Object} event + */ +function stopTouchMove(event) { + var instance = event.instance; + var state = instance.getState(); + var touch = event.touches[0]; + if (IS_HTML5 && isPC()) { + touch = event; + } + state.deltaX = touch.clientX - state.startX; + state.deltaY = touch.clientY - state.startY; + state.offsetY = Math.abs(state.deltaY); + state.offsetX = Math.abs(state.deltaX); + state.direction = state.direction || getDirection(state.offsetX, state.offsetY); +} + +function isPC() { + var userAgentInfo = navigator.userAgent; + var Agents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"]; + var flag = true; + for (var v = 0; v < Agents.length - 1; v++) { + if (userAgentInfo.indexOf(Agents[v]) > 0) { + flag = false; + break; + } + } + if(userAgentInfo.indexOf('Phone') > 0 && userAgentInfo.indexOf('Harmony') > 0){ + flag = false; + } + return flag; +} + +var movable = false + +function mousedown(e, ins) { + if (!IS_HTML5) return + if (!isPC()) return + touchstart(e, ins) + movable = true +} + +function mousemove(e, ins) { + if (!IS_HTML5) return + if (!isPC()) return + if (!movable) return + touchmove(e, ins) +} + +function mouseup(e, ins) { + if (!IS_HTML5) return + if (!isPC()) return + touchend(e, ins) + movable = false +} + +function mouseleave(e, ins) { + if (!IS_HTML5) return + if (!isPC()) return + movable = false +} + +module.exports = { + showWatch: showWatch, + touchstart: touchstart, + touchmove: touchmove, + touchend: touchend, + mousedown: mousedown, + mousemove: mousemove, + mouseup: mouseup, + mouseleave: mouseleave +} diff --git a/uni_modules/uni-swipe-action/components/uni-swipe-action/uni-swipe-action.vue b/uni_modules/uni-swipe-action/components/uni-swipe-action/uni-swipe-action.vue new file mode 100644 index 0000000..9b32b3d --- /dev/null +++ b/uni_modules/uni-swipe-action/components/uni-swipe-action/uni-swipe-action.vue @@ -0,0 +1,60 @@ + + + + + diff --git a/uni_modules/uni-swipe-action/package.json b/uni_modules/uni-swipe-action/package.json new file mode 100644 index 0000000..fb1df50 --- /dev/null +++ b/uni_modules/uni-swipe-action/package.json @@ -0,0 +1,112 @@ +{ + "id": "uni-swipe-action", + "displayName": "uni-swipe-action 滑动操作", + "version": "1.3.16", + "description": "SwipeAction 滑动操作操作组件", + "keywords": [ + "", + "uni-ui", + "uniui", + "滑动删除", + "侧滑删除" +], + "repository": "https://github.com/dcloudio/uni-ui", + "engines": { + "HBuilderX": "", + "uni-app": "^4.27", + "uni-app-x": "" + }, + "directories": { + "example": "../../temps/example_temps" + }, + "dcloudext": { + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui", + "type": "component-vue", + "darkmode": "x", + "i18n": "x", + "widescreen": "x" + }, + "uni_modules": { + "dependencies": [ + "uni-scss" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "x", + "aliyun": "x", + "alipay": "x" + }, + "client": { + "uni-app": { + "vue": { + "vue2": { + "extVersion": "1.3.14", + "minVersion": "" + }, + "vue3": { + "extVersion": "1.3.14", + "minVersion": "" + } + }, + "web": { + "safari": "-", + "chrome": "-" + }, + "app": { + "vue": "-", + "nvue": "-", + "android": "-", + "ios": "-", + "harmony": "-" + }, + "mp": { + "weixin": "-", + "alipay": "-", + "toutiao": "-", + "baidu": "-", + "kuaishou": "-", + "jd": "-", + "harmony": "-", + "qq": "-", + "lark": "-" + }, + "quickapp": { + "huawei": "-", + "union": "-" + } + }, + "uni-app-x": { + "web": { + "safari": "-", + "chrome": "-" + }, + "app": { + "android": "-", + "ios": "-", + "harmony": "-" + }, + "mp": { + "weixin": "-" + } + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uni-swipe-action/readme.md b/uni_modules/uni-swipe-action/readme.md new file mode 100644 index 0000000..93a5cac --- /dev/null +++ b/uni_modules/uni-swipe-action/readme.md @@ -0,0 +1,11 @@ + + +## SwipeAction 滑动操作 +> **组件名:uni-swipe-action** +> 代码块: `uSwipeAction`、`uSwipeActionItem` + + +通过滑动触发选项的容器 + +### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-swipe-action) +#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 \ No newline at end of file diff --git a/uni_modules/uview-ui/LICENSE b/uni_modules/uview-ui/LICENSE new file mode 100644 index 0000000..4db40ef --- /dev/null +++ b/uni_modules/uview-ui/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 www.uviewui.com + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/uni_modules/uview-ui/README.md b/uni_modules/uview-ui/README.md new file mode 100644 index 0000000..c78ff47 --- /dev/null +++ b/uni_modules/uview-ui/README.md @@ -0,0 +1,66 @@ +

+ logo +

+

uView 2.0

+

多平台快速开发的UI框架

+ +[![stars](https://img.shields.io/github/stars/umicro/uView2.0?style=flat-square&logo=GitHub)](https://github.com/umicro/uView2.0) +[![forks](https://img.shields.io/github/forks/umicro/uView2.0?style=flat-square&logo=GitHub)](https://github.com/umicro/uView2.0) +[![issues](https://img.shields.io/github/issues/umicro/uView2.0?style=flat-square&logo=GitHub)](https://github.com/umicro/uView2.0/issues) +[![Website](https://img.shields.io/badge/uView-up-blue?style=flat-square)](https://uviewui.com) +[![release](https://img.shields.io/github/v/release/umicro/uView2.0?style=flat-square)](https://gitee.com/umicro/uView2.0/releases) +[![license](https://img.shields.io/github/license/umicro/uView2.0?style=flat-square)](https://en.wikipedia.org/wiki/MIT_License) + +## 说明 + +uView UI,是[uni-app](https://uniapp.dcloud.io/)全面兼容nvue的uni-app生态框架,全面的组件和便捷的工具会让您信手拈来,如鱼得水 + +## [官方文档:https://uviewui.com](https://uviewui.com) + + +## 预览 + +您可以通过**微信**扫码,查看最佳的演示效果。 +
+
+ + + +## 链接 + +- [官方文档](https://www.uviewui.com/) +- [更新日志](https://www.uviewui.com/components/changelog.html) +- [升级指南](https://www.uviewui.com/components/changeGuide.html) +- [关于我们](https://www.uviewui.com/cooperation/about.html) + +## 交流反馈 + +欢迎加入我们的QQ群交流反馈:[点此跳转](https://www.uviewui.com/components/addQQGroup.html) + +## 关于PR + +> 我们非常乐意接受各位的优质PR,但在此之前我希望您了解uView2.0是一个需要兼容多个平台的(小程序、h5、ios app、android app)包括nvue页面、vue页面。 +> 所以希望在您修复bug并提交之前尽可能的去这些平台测试一下兼容性。最好能携带测试截图以方便审核。非常感谢! + +## 安装 + +#### **uni-app插件市场链接** —— [https://ext.dcloud.net.cn/plugin?id=1593](https://ext.dcloud.net.cn/plugin?id=1593) + +请通过[官网安装文档](https://www.uviewui.com/components/install.html)了解更详细的内容 + +## 快速上手 + +请通过[快速上手](https://uviewui.com/components/quickstart.html)了解更详细的内容 + +## 使用方法 +配置easycom规则后,自动按需引入,无需`import`组件,直接引用即可。 + +```html + +``` + +## 版权信息 +uView遵循[MIT](https://en.wikipedia.org/wiki/MIT_License)开源协议,意味着您无需支付任何费用,也无需授权,即可将uView应用到您的产品中。 + diff --git a/uni_modules/uview-ui/changelog.md b/uni_modules/uview-ui/changelog.md new file mode 100644 index 0000000..16fb337 --- /dev/null +++ b/uni_modules/uview-ui/changelog.md @@ -0,0 +1,374 @@ +## 2.0.37(2024-03-17) +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. 修复表单校验`trigger`触发器参数无效问题 +2. 修复`u-input`组件的`password`属性在动态切换为`false`时失效的问题 +3. 添加微信小程序用户同意隐私协议事件回调 +4. 修复支付宝小程序picker样式问题 +5. `u-modal`添加`duration`字段控制动画过度时间 +6. 修复`picker` `lastIndex`异常导致的`column`异常问题 +7. `tabs`增加长按事件支持 +8. 修复`u-avatar` `square`属性在小程序`open-data`下无效问题 +9. 其他一些修复 +## 2.0.36(2023-03-27) +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. 重构`deepClone` & `deepMerge`方法 +2. 其他优化 +## 2.0.34(2022-09-24) +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. `u-input`、`u-textarea`增加`ignoreCompositionEvent`属性 +2. 修复`route`方法调用可能报错的问题 +3. 修复`u-no-network`组件`z-index`无效的问题 +4. 修复`textarea`组件在h5上confirmType=""报错的问题 +5. `u-rate`适配`nvue` +6. 优化验证手机号码的正则表达式(根据工信部发布的《电信网编号计划(2017年版)》进行修改。) +7. `form-item`添加`labelPosition`属性 +8. `u-calendar`修复`maxDate`设置为当前日期,并且当前时间大于08:00时无法显示日期列表的问题 (#724) +9. `u-radio`增加一个默认插槽用于自定义修改label内容 (#680) +10. 修复`timeFormat`函数在safari重的兼容性问题 (#664) +## 2.0.33(2022-06-17) +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. 修复`loadmore`组件`lineColor`类型错误问题 +2. 修复`u-parse`组件`imgtap`、`linktap`不生效问题 +## 2.0.32(2022-06-16) +# uView2.0重磅发布,利剑出鞘,一统江湖 +1. `u-loadmore`新增自定义颜色、虚/实线 +2. 修复`u-swiper-action`组件部分平台不能上下滑动的问题 +3. 修复`u-list`回弹问题 +4. 修复`notice-bar`组件动画在低端安卓机可能会抖动的问题 +5. `u-loading-page`添加控制图标大小的属性`iconSize` +6. 修复`u-tooltip`组件`color`参数不生效的问题 +7. 修复`u--input`组件使用`blur`事件输出为`undefined`的bug +8. `u-code-input`组件新增键盘弹起时,是否自动上推页面参数`adjustPosition` +9. 修复`image`组件`load`事件无回调对象问题 +10. 修复`button`组件`loadingSize`设置无效问题 +10. 其他修复 +## 2.0.31(2022-04-19) +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. 修复`upload`在`vue`页面上传成功后没有成功标志的问题 +2. 解决演示项目中微信小程序模拟上传图片一直出于上传中问题 +3. 修复`u-code-input`组件在`nvue`页面编译到`app`平台上光标异常问题(`app`去除此功能) +4. 修复`actionSheet`组件标题关闭按钮点击事件名称错误的问题 +5. 其他修复 +## 2.0.30(2022-04-04) +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. `u-rate`增加`readonly`属性 +2. `tabs`滑块支持设置背景图片 +3. 修复`u-subsection` `mode`为`subsection`时,滑块样式不正确的问题 +4. `u-code-input`添加光标效果动画 +5. 修复`popup`的`open`事件不触发 +6. 修复`u-flex-column`无效的问题 +7. 修复`u-datetime-picker`索引在特定场合异常问题 +8. 修复`u-datetime-picker`最小时间字符串模板错误问题 +9. `u-swiper`添加`m3u8`验证 +10. `u-swiper`修改判断image和video逻辑 +11. 修复`swiper`无法使用本地图片问题,增加`type`参数 +12. 修复`u-row-notice`格式错误问题 +13. 修复`u-switch`组件当`unit`为`rpx`时,`nodeStyle`消失的问题 +14. 修复`datetime-picker`组件`showToolbar`与`visibleItemCount`属性无效的问题 +15. 修复`upload`组件条件编译位置判断错误,导致`previewImage`属性设置为`false`时,整个组件都会被隐藏的问题 +16. 修复`u-checkbox-group`设置`shape`属性无效的问题 +17. 修复`u-upload`的`capture`传入字符串的时候不生效的问题 +18. 修复`u-action-sheet`组件,关闭事件逻辑错误的问题 +19. 修复`u-list`触顶事件的触发错误的问题 +20. 修复`u-text`只有手机号可拨打的问题 +21. 修复`u-textarea`不能换行的问题 +22. 其他修复 +## 2.0.29(2022-03-13) +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. 修复`u--text`组件设置`decoration`属性未生效的问题 +2. 修复`u-datetime-picker`使用`formatter`后返回值不正确 +3. 修复`u-datetime-picker` `intercept` 可能为undefined +4. 修复已设置单位 uni..config.unit = 'rpx'时,线型指示器 `transform` 的位置翻倍,导致指示器超出宽度 +5. 修复mixin中bem方法生成的类名在支付宝和字节小程序中失效 +6. 修复默认值传值为空的时候,打开`u-datetime-picker`报错,不能选中第一列时间的bug +7. 修复`u-datetime-picker`使用`formatter`后返回值不正确 +8. 修复`u-image`组件`loading`无效果的问题 +9. 修复`config.unit`属性设为`rpx`时,导航栏占用高度不足导致塌陷的问题 +10. 修复`u-datetime-picker`组件`itemHeight`无效问题 +11. 其他修复 +## 2.0.28(2022-02-22) +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. search组件新增searchIconSize属性 +2. 兼容Safari/Webkit中传入时间格式如2022-02-17 12:00:56 +3. 修复text value.js 判断日期出format错误问题 +4. priceFormat格式化金额出现精度错误 +5. priceFormat在部分情况下出现精度损失问题 +6. 优化表单rules提示 +7. 修复avatar组件src为空时,展示状态不对 +8. 其他修复 +## 2.0.27(2022-01-28) +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1.样式修复 +## 2.0.26(2022-01-28) +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1.样式修复 +## 2.0.25(2022-01-27) +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. 修复text组件mode=price时,可能会导致精度错误的问题 +2. 添加$u.setConfig()方法,可设置uView内置的config, props, zIndex, color属性,详见:[修改uView内置配置方案](https://uviewui.com/components/setting.html#%E9%BB%98%E8%AE%A4%E5%8D%95%E4%BD%8D%E9%85%8D%E7%BD%AE) +3. 优化form组件在errorType=toast时,如果输入错误页面会有抖动的问题 +4. 修复$u.addUnit()对配置默认单位可能无效的问题 +## 2.0.24(2022-01-25) +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. 修复swiper在current指定非0时缩放有误 +2. 修复u-icon添加stop属性的时候报错 +3. 优化遗留的通过正则判断rpx单位的问题 +4. 优化Layout布局 vue使用gutter时,会超出固定区域 +5. 优化search组件高度单位问题(rpx -> px) +6. 修复u-image slot 加载和错误的图片失去了高度 +7. 修复u-index-list中footer插槽与header插槽存在性判断错误 +8. 修复部分机型下u-popup关闭时会闪烁 +9. 修复u-image在nvue-app下失去宽高 +10. 修复u-popup运行报错 +11. 修复u-tooltip报错 +12. 修复box-sizing在app下的警告 +13. 修复u-navbar在小程序中报运行时错误 +14. 其他修复 +## 2.0.23(2022-01-24) +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. 修复image组件在hx3.3.9的nvue下可能会显示异常的问题 +2. 修复col组件gutter参数带rpx单位处理不正确的问题 +3. 修复text组件单行时无法显示省略号的问题 +4. navbar添加titleStyle参数 +5. 升级到hx3.3.9可消除nvue下控制台样式警告的问题 +## 2.0.22(2022-01-19) +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. $u.page()方法优化,避免在特殊场景可能报错的问题 +2. picker组件添加immediateChange参数 +3. 新增$u.pages()方法 +## 2.0.21(2022-01-19) +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. 优化:form组件在用户设置rules的时候提示用户model必传 +2. 优化遗留的通过正则判断rpx单位的问题 +3. 修复微信小程序环境中tabbar组件开启safeAreaInsetBottom属性后,placeholder高度填充不正确 +4. 修复swiper在current指定非0时缩放有误 +5. 修复u-icon添加stop属性的时候报错 +6. 修复upload组件在accept=all的时候没有作用 +7. 修复在text组件mode为phone时call属性无效的问题 +8. 处理u-form clearValidate方法 +9. 其他修复 +## 2.0.20(2022-01-14) +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. 修复calendar默认会选择一个日期,如果直接点确定的话,无法取到值的问题 +2. 修复Slider缺少disabled props 还有注释 +3. 修复u-notice-bar点击事件无法拿到index索引值的问题 +4. 修复u-collapse-item在vue文件下,app端自定义插槽不生效的问题 +5. 优化头像为空时显示默认头像 +6. 修复图片地址赋值后判断加载状态为完成问题 +7. 修复日历滚动到默认日期月份区域 +8. search组件暴露点击左边icon事件 +9. 修复u-form clearValidate方法不生效 +10. upload h5端增加返回文件参数(文件的name参数) +11. 处理upload选择文件后url为blob类型无法预览的问题 +12. u-code-input 修复输入框没有往左移出一半屏幕 +13. 修复Upload上传 disabled为true时,控制台报hoverClass类型错误 +14. 临时处理ios app下grid点击坍塌问题 +15. 其他修复 +## 2.0.19(2021-12-29) +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. 优化微信小程序包体积可在微信中预览,请升级HbuilderX3.3.4,同时在“运行->运行到小程序模拟器”中勾选“运行时是否压缩代码” +2. 优化微信小程序setData性能,处理某些方法如$u.route()无法在模板中使用的问题 +3. navbar添加autoBack参数 +4. 允许avatar组件的事件冒泡 +5. 修复cell组件报错问题 +6. 其他修复 +## 2.0.18(2021-12-28) +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. 修复app端编译报错问题 +2. 重新处理微信小程序端setData过大的性能问题 +3. 修复边框问题 +4. 修复最大最小月份不大于0则没有数据出现的问题 +5. 修复SwipeAction微信小程序端无法上下滑动问题 +6. 修复input的placeholder在小程序端默认显示为true问题 +7. 修复divider组件click事件无效问题 +8. 修复u-code-input maxlength 属性值为 String 类型时显示异常 +9. 修复当 grid只有 1到2时 在小程序端algin设置无效的问题 +10. 处理form-item的label为top时,取消错误提示的左边距 +11. 其他修复 +## 2.0.17(2021-12-26) +## uView正在参与开源中国的“年度最佳项目”评选,之前投过票的现在也可以投票,恳请同学们投一票,[点此帮助uView](https://www.oschina.net/project/top_cn_2021/?id=583) + +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. 解决HBuilderX3.3.3.20211225版本导致的样式问题 +2. calendar日历添加monthNum参数 +3. navbar添加center slot +## 2.0.16(2021-12-25) +## uView正在参与开源中国的“年度最佳项目”评选,之前投过票的现在也可以投票,恳请同学们投一票,[点此帮助uView](https://www.oschina.net/project/top_cn_2021/?id=583) + +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. 解决微信小程序setData性能问题 +2. 修复count-down组件change事件不触发问题 +## 2.0.15(2021-12-21) +## uView正在参与开源中国的“年度最佳项目”评选,之前投过票的现在也可以投票,恳请同学们投一票,[点此帮助uView](https://www.oschina.net/project/top_cn_2021/?id=583) + +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. 修复Cell单元格titleWidth无效 +2. 修复cheakbox组件ischecked不更新 +3. 修复keyboard是否显示"."按键默认值问题 +4. 修复number-keyboard是否显示键盘的"."符号问题 +5. 修复Input输入框 readonly无效 +6. 修复u-avatar 导致打包app、H5时候报错问题 +7. 修复Upload上传deletable无效 +8. 修复upload当设置maxSize时无效的问题 +9. 修复tabs lineWidth传入带单位的字符串的时候偏移量计算错误问题 +10. 修复rate组件在有padding的view内,显示的星星位置和可触摸区域不匹配,无法正常选中星星 +## 2.0.13(2021-12-14) +## [点击加群交流反馈:364463526](https://jq.qq.com/?_chanwv=1027&k=mCxS3TGY) + +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. 修复配置默认单位为rpx可能会导致自定义导航栏高度异常的问题 +## 2.0.12(2021-12-14) +## [点击加群交流反馈:364463526](https://jq.qq.com/?_chanwv=1027&k=mCxS3TGY) + +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. 修复tabs组件在vue环境下划线消失的问题 +2. 修复upload组件在安卓小程序无法选择视频的问题 +3. 添加uni.$u.config.unit配置,用于配置参数默认单位,详见:[默认单位配置](https://www.uviewui.com/components/setting.html#%E9%BB%98%E8%AE%A4%E5%8D%95%E4%BD%8D%E9%85%8D%E7%BD%AE) +4. 修复textarea组件在没绑定v-model时,字符统计不生效问题 +5. 修复nvue下控制是否出现滚动条失效问题 +## 2.0.11(2021-12-13) +## [点击加群交流反馈:364463526](https://jq.qq.com/?_chanwv=1027&k=mCxS3TGY) + +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. text组件align参数无效的问题 +2. subsection组件添加keyName参数 +3. upload组件无法判断[Object file]类型的问题 +4. 处理notify层级过低问题 +5. codeInput组件添加disabledDot参数 +6. 处理actionSheet组件round参数无效的问题 +7. calendar组件添加round参数用于控制圆角值 +8. 处理swipeAction组件在vue环境下默认被打开的问题 +9. button组件的throttleTime节流参数无效的问题 +10. 解决u-notify手动关闭方法close()无效的问题 +11. input组件readonly不生效问题 +12. tag组件type参数为info不生效问题 +## 2.0.10(2021-12-08) +## [点击加群交流反馈:364463526](https://jq.qq.com/?_chanwv=1027&k=mCxS3TGY) + +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. 修复button sendMessagePath属性不生效 +2. 修复DatetimePicker选择器title无效 +3. 修复u-toast设置loading=true不生效 +4. 修复u-text金额模式传0报错 +5. 修复u-toast组件的icon属性配置不生效 +6. button的icon在特殊场景下的颜色优化 +7. IndexList优化,增加# +## 2.0.9(2021-12-01) +## [点击加群交流反馈:232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU) + +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. 优化swiper的height支持100%值(仅vue有效),修复嵌入视频时click事件无法触发的问题 +2. 优化tabs组件对list值为空的判断,或者动态变化list时重新计算相关尺寸的问题 +3. 优化datetime-picker组件逻辑,让其后续打开的默认值为上一次的选中值,需要通过v-model绑定值才有效 +4. 修复upload内嵌在其他组件中,选择图片可能不会换行的问题 +## 2.0.8(2021-12-01) +## [点击加群交流反馈:232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU) + +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. 修复toast的position参数无效问题 +2. 处理input在ios nvue上无法获得焦点的问题 +3. avatar-group组件添加extraValue参数,让剩余展示数量可手动控制 +4. tabs组件添加keyName参数用于配置从对象中读取的键名 +5. 处理text组件名字脱敏默认配置无效的问题 +6. 处理picker组件item文本太长换行问题 +## 2.0.7(2021-11-30) +## [点击加群交流反馈:232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU) + +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. 修复radio和checkbox动态改变v-model无效的问题。 +2. 优化form规则validator在微信小程序用法 +3. 修复backtop组件mode参数在微信小程序无效的问题 +4. 处理Album的previewFullImage属性无效的问题 +5. 处理u-datetime-picker组件mode='time'在选择改变时间时,控制台报错的问题 +## 2.0.6(2021-11-27) +## [点击加群交流反馈:232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU) + +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. 处理tag组件在vue下边框无效的问题。 +2. 处理popup组件圆角参数可能无效的问题。 +3. 处理tabs组件lineColor参数可能无效的问题。 +4. propgress组件在值很小时,显示异常的问题。 +## 2.0.5(2021-11-25) +## [点击加群交流反馈:232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU) + +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. calendar在vue下显示异常问题。 +2. form组件labelPosition和errorType参数无效的问题 +3. input组件inputAlign无效的问题 +4. 其他一些修复 +## 2.0.4(2021-11-23) +## [点击加群交流反馈:232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU) + +# uView2.0重磅发布,利剑出鞘,一统江湖 + +0. input组件缺失@confirm事件,以及subfix和prefix无效问题 +1. component.scss文件样式在vue下干扰全局布局问题 +2. 修复subsection在vue环境下表现异常的问题 +3. tag组件的bgColor等参数无效的问题 +4. upload组件不换行的问题 +5. 其他的一些修复处理 +## 2.0.3(2021-11-16) +## [点击加群交流反馈:1129077272](https://jq.qq.com/?_wv=1027&k=KnbeceDU) + +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. uView2.0已实现全面兼容nvue +2. uView2.0对1.x进行了架构重构,细节和性能都有极大提升 +3. 目前uView2.0为公测阶段,相关细节可能会有变动 +4. 我们写了一份与1.x的对比指南,详见[对比1.x](https://www.uviewui.com/components/diff1.x.html) +5. 处理modal的confirm回调事件拼写错误问题 +6. 处理input组件@input事件参数错误问题 +7. 其他一些修复 +## 2.0.2(2021-11-16) +## [点击加群交流反馈:1129077272](https://jq.qq.com/?_wv=1027&k=KnbeceDU) + +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. uView2.0已实现全面兼容nvue +2. uView2.0对1.x进行了架构重构,细节和性能都有极大提升 +3. 目前uView2.0为公测阶段,相关细节可能会有变动 +4. 我们写了一份与1.x的对比指南,详见[对比1.x](https://www.uviewui.com/components/diff1.x.html) +5. 修复input组件formatter参数缺失问题 +6. 优化loading-icon组件的scss写法问题,防止不兼容新版本scss +## 2.0.0(2020-11-15) +## [点击加群交流反馈:1129077272](https://jq.qq.com/?_wv=1027&k=KnbeceDU) + +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. uView2.0已实现全面兼容nvue +2. uView2.0对1.x进行了架构重构,细节和性能都有极大提升 +3. 目前uView2.0为公测阶段,相关细节可能会有变动 +4. 我们写了一份与1.x的对比指南,详见[对比1.x](https://www.uviewui.com/components/diff1.x.html) +5. 修复input组件formatter参数缺失问题 + + diff --git a/uni_modules/uview-ui/components/u--form/u--form.vue b/uni_modules/uview-ui/components/u--form/u--form.vue new file mode 100644 index 0000000..d534ece --- /dev/null +++ b/uni_modules/uview-ui/components/u--form/u--form.vue @@ -0,0 +1,78 @@ + + + diff --git a/uni_modules/uview-ui/components/u--image/u--image.vue b/uni_modules/uview-ui/components/u--image/u--image.vue new file mode 100644 index 0000000..21b7ab1 --- /dev/null +++ b/uni_modules/uview-ui/components/u--image/u--image.vue @@ -0,0 +1,47 @@ + + + \ No newline at end of file diff --git a/uni_modules/uview-ui/components/u--input/u--input.vue b/uni_modules/uview-ui/components/u--input/u--input.vue new file mode 100644 index 0000000..1e58b01 --- /dev/null +++ b/uni_modules/uview-ui/components/u--input/u--input.vue @@ -0,0 +1,73 @@ + + + \ No newline at end of file diff --git a/uni_modules/uview-ui/components/u--text/u--text.vue b/uni_modules/uview-ui/components/u--text/u--text.vue new file mode 100644 index 0000000..44ee52a --- /dev/null +++ b/uni_modules/uview-ui/components/u--text/u--text.vue @@ -0,0 +1,44 @@ + + + diff --git a/uni_modules/uview-ui/components/u--textarea/u--textarea.vue b/uni_modules/uview-ui/components/u--textarea/u--textarea.vue new file mode 100644 index 0000000..f4df0b9 --- /dev/null +++ b/uni_modules/uview-ui/components/u--textarea/u--textarea.vue @@ -0,0 +1,48 @@ + + + diff --git a/uni_modules/uview-ui/components/u-action-sheet/props.js b/uni_modules/uview-ui/components/u-action-sheet/props.js new file mode 100644 index 0000000..e96e04f --- /dev/null +++ b/uni_modules/uview-ui/components/u-action-sheet/props.js @@ -0,0 +1,54 @@ +export default { + props: { + // 操作菜单是否展示 (默认false) + show: { + type: Boolean, + default: uni.$u.props.actionSheet.show + }, + // 标题 + title: { + type: String, + default: uni.$u.props.actionSheet.title + }, + // 选项上方的描述信息 + description: { + type: String, + default: uni.$u.props.actionSheet.description + }, + // 数据 + actions: { + type: Array, + default: uni.$u.props.actionSheet.actions + }, + // 取消按钮的文字,不为空时显示按钮 + cancelText: { + type: String, + default: uni.$u.props.actionSheet.cancelText + }, + // 点击某个菜单项时是否关闭弹窗 + closeOnClickAction: { + type: Boolean, + default: uni.$u.props.actionSheet.closeOnClickAction + }, + // 处理底部安全区(默认true) + safeAreaInsetBottom: { + type: Boolean, + default: uni.$u.props.actionSheet.safeAreaInsetBottom + }, + // 小程序的打开方式 + openType: { + type: String, + default: uni.$u.props.actionSheet.openType + }, + // 点击遮罩是否允许关闭 (默认true) + closeOnClickOverlay: { + type: Boolean, + default: uni.$u.props.actionSheet.closeOnClickOverlay + }, + // 圆角值 + round: { + type: [Boolean, String, Number], + default: uni.$u.props.actionSheet.round + } + } +} diff --git a/uni_modules/uview-ui/components/u-action-sheet/u-action-sheet.vue b/uni_modules/uview-ui/components/u-action-sheet/u-action-sheet.vue new file mode 100644 index 0000000..26d5d8d --- /dev/null +++ b/uni_modules/uview-ui/components/u-action-sheet/u-action-sheet.vue @@ -0,0 +1,278 @@ + + + + + + diff --git a/uni_modules/uview-ui/components/u-album/props.js b/uni_modules/uview-ui/components/u-album/props.js new file mode 100644 index 0000000..75cdb37 --- /dev/null +++ b/uni_modules/uview-ui/components/u-album/props.js @@ -0,0 +1,59 @@ +export default { + props: { + // 图片地址,Array|Array形式 + urls: { + type: Array, + default: uni.$u.props.album.urls + }, + // 指定从数组的对象元素中读取哪个属性作为图片地址 + keyName: { + type: String, + default: uni.$u.props.album.keyName + }, + // 单图时,图片长边的长度 + singleSize: { + type: [String, Number], + default: uni.$u.props.album.singleSize + }, + // 多图时,图片边长 + multipleSize: { + type: [String, Number], + default: uni.$u.props.album.multipleSize + }, + // 多图时,图片水平和垂直之间的间隔 + space: { + type: [String, Number], + default: uni.$u.props.album.space + }, + // 单图时,图片缩放裁剪的模式 + singleMode: { + type: String, + default: uni.$u.props.album.singleMode + }, + // 多图时,图片缩放裁剪的模式 + multipleMode: { + type: String, + default: uni.$u.props.album.multipleMode + }, + // 最多展示的图片数量,超出时最后一个位置将会显示剩余图片数量 + maxCount: { + type: [String, Number], + default: uni.$u.props.album.maxCount + }, + // 是否可以预览图片 + previewFullImage: { + type: Boolean, + default: uni.$u.props.album.previewFullImage + }, + // 每行展示图片数量,如设置,singleSize和multipleSize将会无效 + rowCount: { + type: [String, Number], + default: uni.$u.props.album.rowCount + }, + // 超出maxCount时是否显示查看更多的提示 + showMore: { + type: Boolean, + default: uni.$u.props.album.showMore + } + } +} diff --git a/uni_modules/uview-ui/components/u-album/u-album.vue b/uni_modules/uview-ui/components/u-album/u-album.vue new file mode 100644 index 0000000..687e2d5 --- /dev/null +++ b/uni_modules/uview-ui/components/u-album/u-album.vue @@ -0,0 +1,259 @@ + + + + + \ No newline at end of file diff --git a/uni_modules/uview-ui/components/u-alert/props.js b/uni_modules/uview-ui/components/u-alert/props.js new file mode 100644 index 0000000..4297e2c --- /dev/null +++ b/uni_modules/uview-ui/components/u-alert/props.js @@ -0,0 +1,44 @@ +export default { + props: { + // 显示文字 + title: { + type: String, + default: uni.$u.props.alert.title + }, + // 主题,success/warning/info/error + type: { + type: String, + default: uni.$u.props.alert.type + }, + // 辅助性文字 + description: { + type: String, + default: uni.$u.props.alert.description + }, + // 是否可关闭 + closable: { + type: Boolean, + default: uni.$u.props.alert.closable + }, + // 是否显示图标 + showIcon: { + type: Boolean, + default: uni.$u.props.alert.showIcon + }, + // 浅或深色调,light-浅色,dark-深色 + effect: { + type: String, + default: uni.$u.props.alert.effect + }, + // 文字是否居中 + center: { + type: Boolean, + default: uni.$u.props.alert.center + }, + // 字体大小 + fontSize: { + type: [String, Number], + default: uni.$u.props.alert.fontSize + } + } +} diff --git a/uni_modules/uview-ui/components/u-alert/u-alert.vue b/uni_modules/uview-ui/components/u-alert/u-alert.vue new file mode 100644 index 0000000..81f7d43 --- /dev/null +++ b/uni_modules/uview-ui/components/u-alert/u-alert.vue @@ -0,0 +1,243 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-avatar-group/props.js b/uni_modules/uview-ui/components/u-avatar-group/props.js new file mode 100644 index 0000000..58b42ac --- /dev/null +++ b/uni_modules/uview-ui/components/u-avatar-group/props.js @@ -0,0 +1,52 @@ +export default { + props: { + // 头像图片组 + urls: { + type: Array, + default: uni.$u.props.avatarGroup.urls + }, + // 最多展示的头像数量 + maxCount: { + type: [String, Number], + default: uni.$u.props.avatarGroup.maxCount + }, + // 头像形状 + shape: { + type: String, + default: uni.$u.props.avatarGroup.shape + }, + // 图片裁剪模式 + mode: { + type: String, + default: uni.$u.props.avatarGroup.mode + }, + // 超出maxCount时是否显示查看更多的提示 + showMore: { + type: Boolean, + default: uni.$u.props.avatarGroup.showMore + }, + // 头像大小 + size: { + type: [String, Number], + default: uni.$u.props.avatarGroup.size + }, + // 指定从数组的对象元素中读取哪个属性作为图片地址 + keyName: { + type: String, + default: uni.$u.props.avatarGroup.keyName + }, + // 头像之间的遮挡比例 + gap: { + type: [String, Number], + validator(value) { + return value >= 0 && value <= 1 + }, + default: uni.$u.props.avatarGroup.gap + }, + // 需额外显示的值 + extraValue: { + type: [Number, String], + default: uni.$u.props.avatarGroup.extraValue + } + } +} diff --git a/uni_modules/uview-ui/components/u-avatar-group/u-avatar-group.vue b/uni_modules/uview-ui/components/u-avatar-group/u-avatar-group.vue new file mode 100644 index 0000000..7e996d7 --- /dev/null +++ b/uni_modules/uview-ui/components/u-avatar-group/u-avatar-group.vue @@ -0,0 +1,103 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-avatar/props.js b/uni_modules/uview-ui/components/u-avatar/props.js new file mode 100644 index 0000000..34ca0f2 --- /dev/null +++ b/uni_modules/uview-ui/components/u-avatar/props.js @@ -0,0 +1,78 @@ +export default { + props: { + // 头像图片路径(不能为相对路径) + src: { + type: String, + default: uni.$u.props.avatar.src + }, + // 头像形状,circle-圆形,square-方形 + shape: { + type: String, + default: uni.$u.props.avatar.shape + }, + // 头像尺寸 + size: { + type: [String, Number], + default: uni.$u.props.avatar.size + }, + // 裁剪模式 + mode: { + type: String, + default: uni.$u.props.avatar.mode + }, + // 显示的文字 + text: { + type: String, + default: uni.$u.props.avatar.text + }, + // 背景色 + bgColor: { + type: String, + default: uni.$u.props.avatar.bgColor + }, + // 文字颜色 + color: { + type: String, + default: uni.$u.props.avatar.color + }, + // 文字大小 + fontSize: { + type: [String, Number], + default: uni.$u.props.avatar.fontSize + }, + // 显示的图标 + icon: { + type: String, + default: uni.$u.props.avatar.icon + }, + // 显示小程序头像,只对百度,微信,QQ小程序有效 + mpAvatar: { + type: Boolean, + default: uni.$u.props.avatar.mpAvatar + }, + // 是否使用随机背景色 + randomBgColor: { + type: Boolean, + default: uni.$u.props.avatar.randomBgColor + }, + // 加载失败的默认头像(组件有内置默认图片) + defaultUrl: { + type: String, + default: uni.$u.props.avatar.defaultUrl + }, + // 如果配置了randomBgColor为true,且配置了此值,则从默认的背景色数组中取出对应索引的颜色值,取值0-19之间 + colorIndex: { + type: [String, Number], + // 校验参数规则,索引在0-19之间 + validator(n) { + return uni.$u.test.range(n, [0, 19]) || n === '' + }, + default: uni.$u.props.avatar.colorIndex + }, + // 组件标识符 + name: { + type: String, + default: uni.$u.props.avatar.name + } + } +} diff --git a/uni_modules/uview-ui/components/u-avatar/u-avatar.vue b/uni_modules/uview-ui/components/u-avatar/u-avatar.vue new file mode 100644 index 0000000..d38d8a6 --- /dev/null +++ b/uni_modules/uview-ui/components/u-avatar/u-avatar.vue @@ -0,0 +1,173 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-back-top/props.js b/uni_modules/uview-ui/components/u-back-top/props.js new file mode 100644 index 0000000..6c702c2 --- /dev/null +++ b/uni_modules/uview-ui/components/u-back-top/props.js @@ -0,0 +1,54 @@ +export default { + props: { + // 返回顶部的形状,circle-圆形,square-方形 + mode: { + type: String, + default: uni.$u.props.backtop.mode + }, + // 自定义图标 + icon: { + type: String, + default: uni.$u.props.backtop.icon + }, + // 提示文字 + text: { + type: String, + default: uni.$u.props.backtop.text + }, + // 返回顶部滚动时间 + duration: { + type: [String, Number], + default: uni.$u.props.backtop.duration + }, + // 滚动距离 + scrollTop: { + type: [String, Number], + default: uni.$u.props.backtop.scrollTop + }, + // 距离顶部多少距离显示,单位px + top: { + type: [String, Number], + default: uni.$u.props.backtop.top + }, + // 返回顶部按钮到底部的距离,单位px + bottom: { + type: [String, Number], + default: uni.$u.props.backtop.bottom + }, + // 返回顶部按钮到右边的距离,单位px + right: { + type: [String, Number], + default: uni.$u.props.backtop.right + }, + // 层级 + zIndex: { + type: [String, Number], + default: uni.$u.props.backtop.zIndex + }, + // 图标的样式,对象形式 + iconStyle: { + type: Object, + default: uni.$u.props.backtop.iconStyle + } + } +} diff --git a/uni_modules/uview-ui/components/u-back-top/u-back-top.vue b/uni_modules/uview-ui/components/u-back-top/u-back-top.vue new file mode 100644 index 0000000..2d07566 --- /dev/null +++ b/uni_modules/uview-ui/components/u-back-top/u-back-top.vue @@ -0,0 +1,129 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-badge/props.js b/uni_modules/uview-ui/components/u-badge/props.js new file mode 100644 index 0000000..74c032c --- /dev/null +++ b/uni_modules/uview-ui/components/u-badge/props.js @@ -0,0 +1,72 @@ +export default { + props: { + // 是否显示圆点 + isDot: { + type: Boolean, + default: uni.$u.props.badge.isDot + }, + // 显示的内容 + value: { + type: [Number, String], + default: uni.$u.props.badge.value + }, + // 是否显示 + show: { + type: Boolean, + default: uni.$u.props.badge.show + }, + // 最大值,超过最大值会显示 '{max}+' + max: { + type: [Number, String], + default: uni.$u.props.badge.max + }, + // 主题类型,error|warning|success|primary + type: { + type: String, + default: uni.$u.props.badge.type + }, + // 当数值为 0 时,是否展示 Badge + showZero: { + type: Boolean, + default: uni.$u.props.badge.showZero + }, + // 背景颜色,优先级比type高,如设置,type参数会失效 + bgColor: { + type: [String, null], + default: uni.$u.props.badge.bgColor + }, + // 字体颜色 + color: { + type: [String, null], + default: uni.$u.props.badge.color + }, + // 徽标形状,circle-四角均为圆角,horn-左下角为直角 + shape: { + type: String, + default: uni.$u.props.badge.shape + }, + // 设置数字的显示方式,overflow|ellipsis|limit + // overflow会根据max字段判断,超出显示`${max}+` + // ellipsis会根据max判断,超出显示`${max}...` + // limit会依据1000作为判断条件,超出1000,显示`${value/1000}K`,比如2.2k、3.34w,最多保留2位小数 + numberType: { + type: String, + default: uni.$u.props.badge.numberType + }, + // 设置badge的位置偏移,格式为 [x, y],也即设置的为top和right的值,absolute为true时有效 + offset: { + type: Array, + default: uni.$u.props.badge.offset + }, + // 是否反转背景和字体颜色 + inverted: { + type: Boolean, + default: uni.$u.props.badge.inverted + }, + // 是否绝对定位 + absolute: { + type: Boolean, + default: uni.$u.props.badge.absolute + } + } +} diff --git a/uni_modules/uview-ui/components/u-badge/u-badge.vue b/uni_modules/uview-ui/components/u-badge/u-badge.vue new file mode 100644 index 0000000..53cfc81 --- /dev/null +++ b/uni_modules/uview-ui/components/u-badge/u-badge.vue @@ -0,0 +1,171 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-button/nvue.scss b/uni_modules/uview-ui/components/u-button/nvue.scss new file mode 100644 index 0000000..490db7d --- /dev/null +++ b/uni_modules/uview-ui/components/u-button/nvue.scss @@ -0,0 +1,46 @@ +$u-button-active-opacity:0.75 !default; +$u-button-loading-text-margin-left:4px !default; +$u-button-text-color: #FFFFFF !default; +$u-button-text-plain-error-color:$u-error !default; +$u-button-text-plain-warning-color:$u-warning !default; +$u-button-text-plain-success-color:$u-success !default; +$u-button-text-plain-info-color:$u-info !default; +$u-button-text-plain-primary-color:$u-primary !default; +.u-button { + &--active { + opacity: $u-button-active-opacity; + } + + &--active--plain { + background-color: rgb(217, 217, 217); + } + + &__loading-text { + margin-left:$u-button-loading-text-margin-left; + } + + &__text, + &__loading-text { + color:$u-button-text-color; + } + + &__text--plain--error { + color:$u-button-text-plain-error-color; + } + + &__text--plain--warning { + color:$u-button-text-plain-warning-color; + } + + &__text--plain--success{ + color:$u-button-text-plain-success-color; + } + + &__text--plain--info { + color:$u-button-text-plain-info-color; + } + + &__text--plain--primary { + color:$u-button-text-plain-primary-color; + } +} \ No newline at end of file diff --git a/uni_modules/uview-ui/components/u-button/props.js b/uni_modules/uview-ui/components/u-button/props.js new file mode 100644 index 0000000..07fd844 --- /dev/null +++ b/uni_modules/uview-ui/components/u-button/props.js @@ -0,0 +1,161 @@ +/* + * @Author : LQ + * @Description : + * @version : 1.0 + * @Date : 2021-08-16 10:04:04 + * @LastAuthor : LQ + * @lastTime : 2021-08-16 10:04:24 + * @FilePath : /u-view2.0/uview-ui/components/u-button/props.js + */ +export default { + props: { + // 是否细边框 + hairline: { + type: Boolean, + default: uni.$u.props.button.hairline + }, + // 按钮的预置样式,info,primary,error,warning,success + type: { + type: String, + default: uni.$u.props.button.type + }, + // 按钮尺寸,large,normal,small,mini + size: { + type: String, + default: uni.$u.props.button.size + }, + // 按钮形状,circle(两边为半圆),square(带圆角) + shape: { + type: String, + default: uni.$u.props.button.shape + }, + // 按钮是否镂空 + plain: { + type: Boolean, + default: uni.$u.props.button.plain + }, + // 是否禁止状态 + disabled: { + type: Boolean, + default: uni.$u.props.button.disabled + }, + // 是否加载中 + loading: { + type: Boolean, + default: uni.$u.props.button.loading + }, + // 加载中提示文字 + loadingText: { + type: [String, Number], + default: uni.$u.props.button.loadingText + }, + // 加载状态图标类型 + loadingMode: { + type: String, + default: uni.$u.props.button.loadingMode + }, + // 加载图标大小 + loadingSize: { + type: [String, Number], + default: uni.$u.props.button.loadingSize + }, + // 开放能力,具体请看uniapp稳定关于button组件部分说明 + // https://uniapp.dcloud.io/component/button + openType: { + type: String, + default: uni.$u.props.button.openType + }, + // 用于
组件,点击分别会触发 组件的 submit/reset 事件 + // 取值为submit(提交表单),reset(重置表单) + formType: { + type: String, + default: uni.$u.props.button.formType + }, + // 打开 APP 时,向 APP 传递的参数,open-type=launchApp时有效 + // 只微信小程序、QQ小程序有效 + appParameter: { + type: String, + default: uni.$u.props.button.appParameter + }, + // 指定是否阻止本节点的祖先节点出现点击态,微信小程序有效 + hoverStopPropagation: { + type: Boolean, + default: uni.$u.props.button.hoverStopPropagation + }, + // 指定返回用户信息的语言,zh_CN 简体中文,zh_TW 繁体中文,en 英文。只微信小程序有效 + lang: { + type: String, + default: uni.$u.props.button.lang + }, + // 会话来源,open-type="contact"时有效。只微信小程序有效 + sessionFrom: { + type: String, + default: uni.$u.props.button.sessionFrom + }, + // 会话内消息卡片标题,open-type="contact"时有效 + // 默认当前标题,只微信小程序有效 + sendMessageTitle: { + type: String, + default: uni.$u.props.button.sendMessageTitle + }, + // 会话内消息卡片点击跳转小程序路径,open-type="contact"时有效 + // 默认当前分享路径,只微信小程序有效 + sendMessagePath: { + type: String, + default: uni.$u.props.button.sendMessagePath + }, + // 会话内消息卡片图片,open-type="contact"时有效 + // 默认当前页面截图,只微信小程序有效 + sendMessageImg: { + type: String, + default: uni.$u.props.button.sendMessageImg + }, + // 是否显示会话内消息卡片,设置此参数为 true,用户进入客服会话会在右下角显示"可能要发送的小程序"提示, + // 用户点击后可以快速发送小程序消息,open-type="contact"时有效 + showMessageCard: { + type: Boolean, + default: uni.$u.props.button.showMessageCard + }, + // 额外传参参数,用于小程序的data-xxx属性,通过target.dataset.name获取 + dataName: { + type: String, + default: uni.$u.props.button.dataName + }, + // 节流,一定时间内只能触发一次 + throttleTime: { + type: [String, Number], + default: uni.$u.props.button.throttleTime + }, + // 按住后多久出现点击态,单位毫秒 + hoverStartTime: { + type: [String, Number], + default: uni.$u.props.button.hoverStartTime + }, + // 手指松开后点击态保留时间,单位毫秒 + hoverStayTime: { + type: [String, Number], + default: uni.$u.props.button.hoverStayTime + }, + // 按钮文字,之所以通过props传入,是因为slot传入的话 + // nvue中无法控制文字的样式 + text: { + type: [String, Number], + default: uni.$u.props.button.text + }, + // 按钮图标 + icon: { + type: String, + default: uni.$u.props.button.icon + }, + // 按钮图标 + iconColor: { + type: String, + default: uni.$u.props.button.icon + }, + // 按钮颜色,支持传入linear-gradient渐变色 + color: { + type: String, + default: uni.$u.props.button.color + } + } +} diff --git a/uni_modules/uview-ui/components/u-button/u-button.vue b/uni_modules/uview-ui/components/u-button/u-button.vue new file mode 100644 index 0000000..d60f73e --- /dev/null +++ b/uni_modules/uview-ui/components/u-button/u-button.vue @@ -0,0 +1,495 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-button/vue.scss b/uni_modules/uview-ui/components/u-button/vue.scss new file mode 100644 index 0000000..32019b2 --- /dev/null +++ b/uni_modules/uview-ui/components/u-button/vue.scss @@ -0,0 +1,80 @@ +// nvue下hover-class无效 +$u-button-before-top:50% !default; +$u-button-before-left:50% !default; +$u-button-before-width:100% !default; +$u-button-before-height:100% !default; +$u-button-before-transform:translate(-50%, -50%) !default; +$u-button-before-opacity:0 !default; +$u-button-before-background-color:#000 !default; +$u-button-before-border-color:#000 !default; +$u-button-active-before-opacity:.15 !default; +$u-button-icon-margin-left:4px !default; +$u-button-plain-u-button-info-color:$u-info; +$u-button-plain-u-button-success-color:$u-success; +$u-button-plain-u-button-error-color:$u-error; +$u-button-plain-u-button-warning-color:$u-error; + +.u-button { + width: 100%; + + &__text { + white-space: nowrap; + line-height: 1; + } + + &:before { + position: absolute; + top:$u-button-before-top; + left:$u-button-before-left; + width:$u-button-before-width; + height:$u-button-before-height; + border: inherit; + border-radius: inherit; + transform:$u-button-before-transform; + opacity:$u-button-before-opacity; + content: " "; + background-color:$u-button-before-background-color; + border-color:$u-button-before-border-color; + } + + &--active { + &:before { + opacity: .15 + } + } + + &__icon+&__text:not(:empty), + &__loading-text { + margin-left:$u-button-icon-margin-left; + } + + &--plain { + &.u-button--primary { + color: $u-primary; + } + } + + &--plain { + &.u-button--info { + color:$u-button-plain-u-button-info-color; + } + } + + &--plain { + &.u-button--success { + color:$u-button-plain-u-button-success-color; + } + } + + &--plain { + &.u-button--error { + color:$u-button-plain-u-button-error-color; + } + } + + &--plain { + &.u-button--warning { + color:$u-button-plain-u-button-warning-color; + } + } +} diff --git a/uni_modules/uview-ui/components/u-calendar/header.vue b/uni_modules/uview-ui/components/u-calendar/header.vue new file mode 100644 index 0000000..bb71fc5 --- /dev/null +++ b/uni_modules/uview-ui/components/u-calendar/header.vue @@ -0,0 +1,105 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-calendar/month.vue b/uni_modules/uview-ui/components/u-calendar/month.vue new file mode 100644 index 0000000..baefb6c --- /dev/null +++ b/uni_modules/uview-ui/components/u-calendar/month.vue @@ -0,0 +1,722 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-calendar/props.js b/uni_modules/uview-ui/components/u-calendar/props.js new file mode 100644 index 0000000..14a9ff4 --- /dev/null +++ b/uni_modules/uview-ui/components/u-calendar/props.js @@ -0,0 +1,154 @@ +export default { + props: { + // 日历顶部标题 + title: { + type: String, + default: uni.$u.props.calendar.title + }, + // 是否显示标题 + showTitle: { + type: Boolean, + default: uni.$u.props.calendar.showTitle + }, + // 是否显示副标题 + showSubtitle: { + type: Boolean, + default: uni.$u.props.calendar.showSubtitle + }, + // 日期类型选择,single-选择单个日期,multiple-可以选择多个日期,range-选择日期范围 + mode: { + type: String, + default: uni.$u.props.calendar.mode + }, + // mode=range时,第一个日期底部的提示文字 + startText: { + type: String, + default: uni.$u.props.calendar.startText + }, + // mode=range时,最后一个日期底部的提示文字 + endText: { + type: String, + default: uni.$u.props.calendar.endText + }, + // 自定义列表 + customList: { + type: Array, + default: uni.$u.props.calendar.customList + }, + // 主题色,对底部按钮和选中日期有效 + color: { + type: String, + default: uni.$u.props.calendar.color + }, + // 最小的可选日期 + minDate: { + type: [String, Number], + default: uni.$u.props.calendar.minDate + }, + // 最大可选日期 + maxDate: { + type: [String, Number], + default: uni.$u.props.calendar.maxDate + }, + // 默认选中的日期,mode为multiple或range是必须为数组格式 + defaultDate: { + type: [Array, String, Date, null], + default: uni.$u.props.calendar.defaultDate + }, + // mode=multiple时,最多可选多少个日期 + maxCount: { + type: [String, Number], + default: uni.$u.props.calendar.maxCount + }, + // 日期行高 + rowHeight: { + type: [String, Number], + default: uni.$u.props.calendar.rowHeight + }, + // 日期格式化函数 + formatter: { + type: [Function, null], + default: uni.$u.props.calendar.formatter + }, + // 是否显示农历 + showLunar: { + type: Boolean, + default: uni.$u.props.calendar.showLunar + }, + // 是否显示月份背景色 + showMark: { + type: Boolean, + default: uni.$u.props.calendar.showMark + }, + // 确定按钮的文字 + confirmText: { + type: String, + default: uni.$u.props.calendar.confirmText + }, + // 确认按钮处于禁用状态时的文字 + confirmDisabledText: { + type: String, + default: uni.$u.props.calendar.confirmDisabledText + }, + // 是否显示日历弹窗 + show: { + type: Boolean, + default: uni.$u.props.calendar.show + }, + // 是否允许点击遮罩关闭日历 + closeOnClickOverlay: { + type: Boolean, + default: uni.$u.props.calendar.closeOnClickOverlay + }, + // 是否为只读状态,只读状态下禁止选择日期 + readonly: { + type: Boolean, + default: uni.$u.props.calendar.readonly + }, + // 是否展示确认按钮 + showConfirm: { + type: Boolean, + default: uni.$u.props.calendar.showConfirm + }, + // 日期区间最多可选天数,默认无限制,mode = range时有效 + maxRange: { + type: [Number, String], + default: uni.$u.props.calendar.maxRange + }, + // 范围选择超过最多可选天数时的提示文案,mode = range时有效 + rangePrompt: { + type: String, + default: uni.$u.props.calendar.rangePrompt + }, + // 范围选择超过最多可选天数时,是否展示提示文案,mode = range时有效 + showRangePrompt: { + type: Boolean, + default: uni.$u.props.calendar.showRangePrompt + }, + // 是否允许日期范围的起止时间为同一天,mode = range时有效 + allowSameDay: { + type: Boolean, + default: uni.$u.props.calendar.allowSameDay + }, + // 圆角值 + round: { + type: [Boolean, String, Number], + default: uni.$u.props.calendar.round + }, + // 最多展示月份数量 + monthNum: { + type: [Number, String], + default: 3 + }, + // 固定start date,只能选end date,mode = range时有效 + fixStartDate: { + type: Boolean, + default: false + }, + // 底部文字 + footerInfo: { + type: String, + default: uni.$u.props.calendar.footerInfo + }, + } +} diff --git a/uni_modules/uview-ui/components/u-calendar/u-calendar.vue b/uni_modules/uview-ui/components/u-calendar/u-calendar.vue new file mode 100644 index 0000000..a974011 --- /dev/null +++ b/uni_modules/uview-ui/components/u-calendar/u-calendar.vue @@ -0,0 +1,443 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-calendar/util.js b/uni_modules/uview-ui/components/u-calendar/util.js new file mode 100644 index 0000000..ca4736b --- /dev/null +++ b/uni_modules/uview-ui/components/u-calendar/util.js @@ -0,0 +1,85 @@ +export default { + methods: { + // 设置月份数据 + setMonth() { + // 月初是周几 + const day = dayjs(this.date).date(1).day() + const start = day == 0 ? 6 : day - 1 + + // 本月天数 + const days = dayjs(this.date).endOf('month').format('D') + + // 上个月天数 + const prevDays = dayjs(this.date).endOf('month').subtract(1, 'month').format('D') + + // 日期数据 + const arr = [] + // 清空表格 + this.month = [] + + // 添加上月数据 + arr.push( + ...new Array(start).fill(1).map((e, i) => { + const day = prevDays - start + i + 1 + + return { + value: day, + disabled: true, + date: dayjs(this.date).subtract(1, 'month').date(day).format('YYYY-MM-DD') + } + }) + ) + + // 添加本月数据 + arr.push( + ...new Array(days - 0).fill(1).map((e, i) => { + const day = i + 1 + + return { + value: day, + date: dayjs(this.date).date(day).format('YYYY-MM-DD') + } + }) + ) + + // 添加下个月 + arr.push( + ...new Array(42 - days - start).fill(1).map((e, i) => { + const day = i + 1 + + return { + value: day, + disabled: true, + date: dayjs(this.date).add(1, 'month').date(day).format('YYYY-MM-DD') + } + }) + ) + + // 分割数组 + for (let n = 0; n < arr.length; n += 7) { + this.month.push( + arr.slice(n, n + 7).map((e, i) => { + e.index = i + n + + // 自定义信息 + const custom = this.customList.find((c) => c.date == e.date) + + // 农历 + if (this.lunar) { + const { + IDayCn, + IMonthCn + } = this.getLunar(e.date) + e.lunar = IDayCn == '初一' ? IMonthCn : IDayCn + } + + return { + ...e, + ...custom + } + }) + ) + } + } + } +} diff --git a/uni_modules/uview-ui/components/u-car-keyboard/props.js b/uni_modules/uview-ui/components/u-car-keyboard/props.js new file mode 100644 index 0000000..3553647 --- /dev/null +++ b/uni_modules/uview-ui/components/u-car-keyboard/props.js @@ -0,0 +1,14 @@ +export default { + props: { + // 是否打乱键盘按键的顺序 + random: { + type: Boolean, + default: false + }, + // 输入一个中文后,是否自动切换到英文 + autoChange: { + type: Boolean, + default: false + } + } +} diff --git a/uni_modules/uview-ui/components/u-car-keyboard/u-car-keyboard.vue b/uni_modules/uview-ui/components/u-car-keyboard/u-car-keyboard.vue new file mode 100644 index 0000000..51175b5 --- /dev/null +++ b/uni_modules/uview-ui/components/u-car-keyboard/u-car-keyboard.vue @@ -0,0 +1,311 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-cell-group/props.js b/uni_modules/uview-ui/components/u-cell-group/props.js new file mode 100644 index 0000000..350ef40 --- /dev/null +++ b/uni_modules/uview-ui/components/u-cell-group/props.js @@ -0,0 +1,14 @@ +export default { + props: { + // 分组标题 + title: { + type: String, + default: uni.$u.props.cellGroup.title + }, + // 是否显示外边框 + border: { + type: Boolean, + default: uni.$u.props.cellGroup.border + } + } +} diff --git a/uni_modules/uview-ui/components/u-cell-group/u-cell-group.vue b/uni_modules/uview-ui/components/u-cell-group/u-cell-group.vue new file mode 100644 index 0000000..a9508c0 --- /dev/null +++ b/uni_modules/uview-ui/components/u-cell-group/u-cell-group.vue @@ -0,0 +1,61 @@ + + + + + + diff --git a/uni_modules/uview-ui/components/u-cell/props.js b/uni_modules/uview-ui/components/u-cell/props.js new file mode 100644 index 0000000..da03330 --- /dev/null +++ b/uni_modules/uview-ui/components/u-cell/props.js @@ -0,0 +1,110 @@ +export default { + props: { + // 标题 + title: { + type: [String, Number], + default: uni.$u.props.cell.title + }, + // 标题下方的描述信息 + label: { + type: [String, Number], + default: uni.$u.props.cell.label + }, + // 右侧的内容 + value: { + type: [String, Number], + default: uni.$u.props.cell.value + }, + // 左侧图标名称,或者图片链接(本地文件建议使用绝对地址) + icon: { + type: String, + default: uni.$u.props.cell.icon + }, + // 是否禁用cell + disabled: { + type: Boolean, + default: uni.$u.props.cell.disabled + }, + // 是否显示下边框 + border: { + type: Boolean, + default: uni.$u.props.cell.border + }, + // 内容是否垂直居中(主要是针对右侧的value部分) + center: { + type: Boolean, + default: uni.$u.props.cell.center + }, + // 点击后跳转的URL地址 + url: { + type: String, + default: uni.$u.props.cell.url + }, + // 链接跳转的方式,内部使用的是uView封装的route方法,可能会进行拦截操作 + linkType: { + type: String, + default: uni.$u.props.cell.linkType + }, + // 是否开启点击反馈(表现为点击时加上灰色背景) + clickable: { + type: Boolean, + default: uni.$u.props.cell.clickable + }, + // 是否展示右侧箭头并开启点击反馈 + isLink: { + type: Boolean, + default: uni.$u.props.cell.isLink + }, + // 是否显示表单状态下的必填星号(此组件可能会内嵌入input组件) + required: { + type: Boolean, + default: uni.$u.props.cell.required + }, + // 右侧的图标箭头 + rightIcon: { + type: String, + default: uni.$u.props.cell.rightIcon + }, + // 右侧箭头的方向,可选值为:left,up,down + arrowDirection: { + type: String, + default: uni.$u.props.cell.arrowDirection + }, + // 左侧图标样式 + iconStyle: { + type: [Object, String], + default: () => { + return uni.$u.props.cell.iconStyle + } + }, + // 右侧箭头图标的样式 + rightIconStyle: { + type: [Object, String], + default: () => { + return uni.$u.props.cell.rightIconStyle + } + }, + // 标题的样式 + titleStyle: { + type: [Object, String], + default: () => { + return uni.$u.props.cell.titleStyle + } + }, + // 单位元的大小,可选值为large + size: { + type: String, + default: uni.$u.props.cell.size + }, + // 点击cell是否阻止事件传播 + stop: { + type: Boolean, + default: uni.$u.props.cell.stop + }, + // 标识符,cell被点击时返回 + name: { + type: [Number, String], + default: uni.$u.props.cell.name + } + } +} diff --git a/uni_modules/uview-ui/components/u-cell/u-cell.vue b/uni_modules/uview-ui/components/u-cell/u-cell.vue new file mode 100644 index 0000000..b099c90 --- /dev/null +++ b/uni_modules/uview-ui/components/u-cell/u-cell.vue @@ -0,0 +1,229 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-checkbox-group/props.js b/uni_modules/uview-ui/components/u-checkbox-group/props.js new file mode 100644 index 0000000..2f818a1 --- /dev/null +++ b/uni_modules/uview-ui/components/u-checkbox-group/props.js @@ -0,0 +1,82 @@ +export default { + props: { + // 标识符 + name: { + type: String, + default: uni.$u.props.checkboxGroup.name + }, + // 绑定的值 + value: { + type: Array, + default: uni.$u.props.checkboxGroup.value + }, + // 形状,circle-圆形,square-方形 + shape: { + type: String, + default: uni.$u.props.checkboxGroup.shape + }, + // 是否禁用全部checkbox + disabled: { + type: Boolean, + default: uni.$u.props.checkboxGroup.disabled + }, + + // 选中状态下的颜色,如设置此值,将会覆盖parent的activeColor值 + activeColor: { + type: String, + default: uni.$u.props.checkboxGroup.activeColor + }, + // 未选中的颜色 + inactiveColor: { + type: String, + default: uni.$u.props.checkboxGroup.inactiveColor + }, + + // 整个组件的尺寸,默认px + size: { + type: [String, Number], + default: uni.$u.props.checkboxGroup.size + }, + // 布局方式,row-横向,column-纵向 + placement: { + type: String, + default: uni.$u.props.checkboxGroup.placement + }, + // label的字体大小,px单位 + labelSize: { + type: [String, Number], + default: uni.$u.props.checkboxGroup.labelSize + }, + // label的字体颜色 + labelColor: { + type: [String], + default: uni.$u.props.checkboxGroup.labelColor + }, + // 是否禁止点击文本操作 + labelDisabled: { + type: Boolean, + default: uni.$u.props.checkboxGroup.labelDisabled + }, + // 图标颜色 + iconColor: { + type: String, + default: uni.$u.props.checkboxGroup.iconColor + }, + // 图标的大小,单位px + iconSize: { + type: [String, Number], + default: uni.$u.props.checkboxGroup.iconSize + }, + // 勾选图标的对齐方式,left-左边,right-右边 + iconPlacement: { + type: String, + default: uni.$u.props.checkboxGroup.iconPlacement + }, + // 竖向配列时,是否显示下划线 + borderBottom: { + type: Boolean, + default: uni.$u.props.checkboxGroup.borderBottom + } + + } +} diff --git a/uni_modules/uview-ui/components/u-checkbox-group/u-checkbox-group.vue b/uni_modules/uview-ui/components/u-checkbox-group/u-checkbox-group.vue new file mode 100644 index 0000000..7a6b4fa --- /dev/null +++ b/uni_modules/uview-ui/components/u-checkbox-group/u-checkbox-group.vue @@ -0,0 +1,103 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-checkbox/props.js b/uni_modules/uview-ui/components/u-checkbox/props.js new file mode 100644 index 0000000..93f4fd9 --- /dev/null +++ b/uni_modules/uview-ui/components/u-checkbox/props.js @@ -0,0 +1,69 @@ +export default { + props: { + // checkbox的名称 + name: { + type: [String, Number, Boolean], + default: uni.$u.props.checkbox.name + }, + // 形状,square为方形,circle为圆型 + shape: { + type: String, + default: uni.$u.props.checkbox.shape + }, + // 整体的大小 + size: { + type: [String, Number], + default: uni.$u.props.checkbox.size + }, + // 是否默认选中 + checked: { + type: Boolean, + default: uni.$u.props.checkbox.checked + }, + // 是否禁用 + disabled: { + type: [String, Boolean], + default: uni.$u.props.checkbox.disabled + }, + // 选中状态下的颜色,如设置此值,将会覆盖parent的activeColor值 + activeColor: { + type: String, + default: uni.$u.props.checkbox.activeColor + }, + // 未选中的颜色 + inactiveColor: { + type: String, + default: uni.$u.props.checkbox.inactiveColor + }, + // 图标的大小,单位px + iconSize: { + type: [String, Number], + default: uni.$u.props.checkbox.iconSize + }, + // 图标颜色 + iconColor: { + type: String, + default: uni.$u.props.checkbox.iconColor + }, + // label提示文字,因为nvue下,直接slot进来的文字,由于特殊的结构,无法修改样式 + label: { + type: [String, Number], + default: uni.$u.props.checkbox.label + }, + // label的字体大小,px单位 + labelSize: { + type: [String, Number], + default: uni.$u.props.checkbox.labelSize + }, + // label的颜色 + labelColor: { + type: String, + default: uni.$u.props.checkbox.labelColor + }, + // 是否禁止点击提示语选中复选框 + labelDisabled: { + type: [String, Boolean], + default: uni.$u.props.checkbox.labelDisabled + } + } +} diff --git a/uni_modules/uview-ui/components/u-checkbox/u-checkbox.vue b/uni_modules/uview-ui/components/u-checkbox/u-checkbox.vue new file mode 100644 index 0000000..6429cca --- /dev/null +++ b/uni_modules/uview-ui/components/u-checkbox/u-checkbox.vue @@ -0,0 +1,344 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-circle-progress/props.js b/uni_modules/uview-ui/components/u-circle-progress/props.js new file mode 100644 index 0000000..d776cfb --- /dev/null +++ b/uni_modules/uview-ui/components/u-circle-progress/props.js @@ -0,0 +1,8 @@ +export default { + props: { + percentage: { + type: [String, Number], + default: uni.$u.props.circleProgress.percentage + } + } +} diff --git a/uni_modules/uview-ui/components/u-circle-progress/u-circle-progress.vue b/uni_modules/uview-ui/components/u-circle-progress/u-circle-progress.vue new file mode 100644 index 0000000..d1ee286 --- /dev/null +++ b/uni_modules/uview-ui/components/u-circle-progress/u-circle-progress.vue @@ -0,0 +1,198 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-code-input/props.js b/uni_modules/uview-ui/components/u-code-input/props.js new file mode 100644 index 0000000..8aa555a --- /dev/null +++ b/uni_modules/uview-ui/components/u-code-input/props.js @@ -0,0 +1,84 @@ +export default { + props: { + // 键盘弹起时,是否自动上推页面 + adjustPosition: { + type: Boolean, + default: uni.$u.props.codeInput.adjustPosition + }, + // 最大输入长度 + maxlength: { + type: [String, Number], + default: uni.$u.props.codeInput.maxlength + }, + // 是否用圆点填充 + dot: { + type: Boolean, + default: uni.$u.props.codeInput.dot + }, + // 显示模式,box-盒子模式,line-底部横线模式 + mode: { + type: String, + default: uni.$u.props.codeInput.mode + }, + // 是否细边框 + hairline: { + type: Boolean, + default: uni.$u.props.codeInput.hairline + }, + // 字符间的距离 + space: { + type: [String, Number], + default: uni.$u.props.codeInput.space + }, + // 预置值 + value: { + type: [String, Number], + default: uni.$u.props.codeInput.value + }, + // 是否自动获取焦点 + focus: { + type: Boolean, + default: uni.$u.props.codeInput.focus + }, + // 字体是否加粗 + bold: { + type: Boolean, + default: uni.$u.props.codeInput.bold + }, + // 字体颜色 + color: { + type: String, + default: uni.$u.props.codeInput.color + }, + // 字体大小 + fontSize: { + type: [String, Number], + default: uni.$u.props.codeInput.fontSize + }, + // 输入框的大小,宽等于高 + size: { + type: [String, Number], + default: uni.$u.props.codeInput.size + }, + // 是否隐藏原生键盘,如果想用自定义键盘的话,需设置此参数为true + disabledKeyboard: { + type: Boolean, + default: uni.$u.props.codeInput.disabledKeyboard + }, + // 边框和线条颜色 + borderColor: { + type: String, + default: uni.$u.props.codeInput.borderColor + }, + // 是否禁止输入"."符号 + disabledDot: { + type: Boolean, + default: uni.$u.props.codeInput.disabledDot + }, + // 是否显示冒号 + isColon: { + type: Boolean, + default: uni.$u.props.codeInput.isColon + } + } +} diff --git a/uni_modules/uview-ui/components/u-code-input/u-code-input.vue b/uni_modules/uview-ui/components/u-code-input/u-code-input.vue new file mode 100644 index 0000000..60ecf44 --- /dev/null +++ b/uni_modules/uview-ui/components/u-code-input/u-code-input.vue @@ -0,0 +1,258 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-code/props.js b/uni_modules/uview-ui/components/u-code/props.js new file mode 100644 index 0000000..eaf80d0 --- /dev/null +++ b/uni_modules/uview-ui/components/u-code/props.js @@ -0,0 +1,34 @@ +export default { + props: { + // 倒计时总秒数 + seconds: { + type: [String, Number], + default: uni.$u.props.code.seconds + }, + // 尚未开始时提示 + startText: { + type: String, + default: uni.$u.props.code.startText + }, + // 正在倒计时中的提示 + changeText: { + type: String, + default: uni.$u.props.code.changeText + }, + // 倒计时结束时的提示 + endText: { + type: String, + default: uni.$u.props.code.endText + }, + // 是否在H5刷新或各端返回再进入时继续倒计时 + keepRunning: { + type: Boolean, + default: uni.$u.props.code.keepRunning + }, + // 为了区分多个页面,或者一个页面多个倒计时组件本地存储的继续倒计时变了 + uniqueKey: { + type: String, + default: uni.$u.props.code.uniqueKey + } + } +} diff --git a/uni_modules/uview-ui/components/u-code/u-code.vue b/uni_modules/uview-ui/components/u-code/u-code.vue new file mode 100644 index 0000000..f79a09a --- /dev/null +++ b/uni_modules/uview-ui/components/u-code/u-code.vue @@ -0,0 +1,129 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-col/props.js b/uni_modules/uview-ui/components/u-col/props.js new file mode 100644 index 0000000..0622251 --- /dev/null +++ b/uni_modules/uview-ui/components/u-col/props.js @@ -0,0 +1,29 @@ +export default { + props: { + // 占父容器宽度的多少等分,总分为12份 + span: { + type: [String, Number], + default: uni.$u.props.col.span + }, + // 指定栅格左侧的间隔数(总12栏) + offset: { + type: [String, Number], + default: uni.$u.props.col.offset + }, + // 水平排列方式,可选值为`start`(或`flex-start`)、`end`(或`flex-end`)、`center`、`around`(或`space-around`)、`between`(或`space-between`) + justify: { + type: String, + default: uni.$u.props.col.justify + }, + // 垂直对齐方式,可选值为top、center、bottom、stretch + align: { + type: String, + default: uni.$u.props.col.align + }, + // 文字对齐方式 + textAlign: { + type: String, + default: uni.$u.props.col.textAlign + } + } +} diff --git a/uni_modules/uview-ui/components/u-col/u-col.vue b/uni_modules/uview-ui/components/u-col/u-col.vue new file mode 100644 index 0000000..8be1517 --- /dev/null +++ b/uni_modules/uview-ui/components/u-col/u-col.vue @@ -0,0 +1,162 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-collapse-item/props.js b/uni_modules/uview-ui/components/u-collapse-item/props.js new file mode 100644 index 0000000..bd5749b --- /dev/null +++ b/uni_modules/uview-ui/components/u-collapse-item/props.js @@ -0,0 +1,59 @@ +export default { + props: { + // 标题 + title: { + type: String, + default: uni.$u.props.collapseItem.title + }, + // 标题右侧内容 + value: { + type: String, + default: uni.$u.props.collapseItem.value + }, + // 标题下方的描述信息 + label: { + type: String, + default: uni.$u.props.collapseItem.label + }, + // 是否禁用折叠面板 + disabled: { + type: Boolean, + default: uni.$u.props.collapseItem.disabled + }, + // 是否展示右侧箭头并开启点击反馈 + isLink: { + type: Boolean, + default: uni.$u.props.collapseItem.isLink + }, + // 是否开启点击反馈 + clickable: { + type: Boolean, + default: uni.$u.props.collapseItem.clickable + }, + // 是否显示内边框 + border: { + type: Boolean, + default: uni.$u.props.collapseItem.border + }, + // 标题的对齐方式 + align: { + type: String, + default: uni.$u.props.collapseItem.align + }, + // 唯一标识符 + name: { + type: [String, Number], + default: uni.$u.props.collapseItem.name + }, + // 标题左侧图片,可为绝对路径的图片或内置图标 + icon: { + type: String, + default: uni.$u.props.collapseItem.icon + }, + // 面板展开收起的过渡时间,单位ms + duration: { + type: Number, + default: uni.$u.props.collapseItem.duration + } + } +} diff --git a/uni_modules/uview-ui/components/u-collapse-item/u-collapse-item.vue b/uni_modules/uview-ui/components/u-collapse-item/u-collapse-item.vue new file mode 100644 index 0000000..0e1b703 --- /dev/null +++ b/uni_modules/uview-ui/components/u-collapse-item/u-collapse-item.vue @@ -0,0 +1,225 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-collapse/props.js b/uni_modules/uview-ui/components/u-collapse/props.js new file mode 100644 index 0000000..7ee6d31 --- /dev/null +++ b/uni_modules/uview-ui/components/u-collapse/props.js @@ -0,0 +1,19 @@ +export default { + props: { + // 当前展开面板的name,非手风琴模式:[],手风琴模式:string | number + value: { + type: [String, Number, Array, null], + default: uni.$u.props.collapse.value + }, + // 是否手风琴模式 + accordion: { + type: Boolean, + default: uni.$u.props.collapse.accordion + }, + // 是否显示外边框 + border: { + type: Boolean, + default: uni.$u.props.collapse.border + } + } +} diff --git a/uni_modules/uview-ui/components/u-collapse/u-collapse.vue b/uni_modules/uview-ui/components/u-collapse/u-collapse.vue new file mode 100644 index 0000000..fc188a2 --- /dev/null +++ b/uni_modules/uview-ui/components/u-collapse/u-collapse.vue @@ -0,0 +1,90 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-column-notice/props.js b/uni_modules/uview-ui/components/u-column-notice/props.js new file mode 100644 index 0000000..4809154 --- /dev/null +++ b/uni_modules/uview-ui/components/u-column-notice/props.js @@ -0,0 +1,55 @@ +export default { + props: { + // 显示的内容,字符串 + text: { + type: [Array], + default: uni.$u.props.columnNotice.text + }, + // 是否显示左侧的音量图标 + icon: { + type: String, + default: uni.$u.props.columnNotice.icon + }, + // 通告模式,link-显示右箭头,closable-显示右侧关闭图标 + mode: { + type: String, + default: uni.$u.props.columnNotice.mode + }, + // 文字颜色,各图标也会使用文字颜色 + color: { + type: String, + default: uni.$u.props.columnNotice.color + }, + // 背景颜色 + bgColor: { + type: String, + default: uni.$u.props.columnNotice.bgColor + }, + // 字体大小,单位px + fontSize: { + type: [String, Number], + default: uni.$u.props.columnNotice.fontSize + }, + // 水平滚动时的滚动速度,即每秒滚动多少px(px),这有利于控制文字无论多少时,都能有一个恒定的速度 + speed: { + type: [String, Number], + default: uni.$u.props.columnNotice.speed + }, + // direction = row时,是否使用步进形式滚动 + step: { + type: Boolean, + default: uni.$u.props.columnNotice.step + }, + // 滚动一个周期的时间长,单位ms + duration: { + type: [String, Number], + default: uni.$u.props.columnNotice.duration + }, + // 是否禁止用手滑动切换 + // 目前HX2.6.11,只支持App 2.5.5+、H5 2.5.5+、支付宝小程序、字节跳动小程序 + disableTouch: { + type: Boolean, + default: uni.$u.props.columnNotice.disableTouch + } + } +} diff --git a/uni_modules/uview-ui/components/u-column-notice/u-column-notice.vue b/uni_modules/uview-ui/components/u-column-notice/u-column-notice.vue new file mode 100644 index 0000000..fc39532 --- /dev/null +++ b/uni_modules/uview-ui/components/u-column-notice/u-column-notice.vue @@ -0,0 +1,160 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-count-down/props.js b/uni_modules/uview-ui/components/u-count-down/props.js new file mode 100644 index 0000000..d62f025 --- /dev/null +++ b/uni_modules/uview-ui/components/u-count-down/props.js @@ -0,0 +1,24 @@ +export default { + props: { + // 倒计时时长,单位ms + time: { + type: [String, Number], + default: uni.$u.props.countDown.time + }, + // 时间格式,DD-日,HH-时,mm-分,ss-秒,SSS-毫秒 + format: { + type: String, + default: uni.$u.props.countDown.format + }, + // 是否自动开始倒计时 + autoStart: { + type: Boolean, + default: uni.$u.props.countDown.autoStart + }, + // 是否展示毫秒倒计时 + millisecond: { + type: Boolean, + default: uni.$u.props.countDown.millisecond + } + } +} diff --git a/uni_modules/uview-ui/components/u-count-down/u-count-down.vue b/uni_modules/uview-ui/components/u-count-down/u-count-down.vue new file mode 100644 index 0000000..b5e85a6 --- /dev/null +++ b/uni_modules/uview-ui/components/u-count-down/u-count-down.vue @@ -0,0 +1,163 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-count-down/utils.js b/uni_modules/uview-ui/components/u-count-down/utils.js new file mode 100644 index 0000000..8c75005 --- /dev/null +++ b/uni_modules/uview-ui/components/u-count-down/utils.js @@ -0,0 +1,62 @@ +// 补0,如1 -> 01 +function padZero(num, targetLength = 2) { + let str = `${num}` + while (str.length < targetLength) { + str = `0${str}` + } + return str +} +const SECOND = 1000 +const MINUTE = 60 * SECOND +const HOUR = 60 * MINUTE +const DAY = 24 * HOUR +export function parseTimeData(time) { + const days = Math.floor(time / DAY) + const hours = Math.floor((time % DAY) / HOUR) + const minutes = Math.floor((time % HOUR) / MINUTE) + const seconds = Math.floor((time % MINUTE) / SECOND) + const milliseconds = Math.floor(time % SECOND) + return { + days, + hours, + minutes, + seconds, + milliseconds + } +} +export function parseFormat(format, timeData) { + let { + days, + hours, + minutes, + seconds, + milliseconds + } = timeData + // 如果格式化字符串中不存在DD(天),则将天的时间转为小时中去 + if (format.indexOf('DD') === -1) { + hours += days * 24 + } else { + // 对天补0 + format = format.replace('DD', padZero(days)) + } + // 其他同理于DD的格式化处理方式 + if (format.indexOf('HH') === -1) { + minutes += hours * 60 + } else { + format = format.replace('HH', padZero(hours)) + } + if (format.indexOf('mm') === -1) { + seconds += minutes * 60 + } else { + format = format.replace('mm', padZero(minutes)) + } + if (format.indexOf('ss') === -1) { + milliseconds += seconds * 1000 + } else { + format = format.replace('ss', padZero(seconds)) + } + return format.replace('SSS', padZero(milliseconds, 3)) +} +export function isSameSecond(time1, time2) { + return Math.floor(time1 / 1000) === Math.floor(time2 / 1000) +} diff --git a/uni_modules/uview-ui/components/u-count-to/props.js b/uni_modules/uview-ui/components/u-count-to/props.js new file mode 100644 index 0000000..86873c1 --- /dev/null +++ b/uni_modules/uview-ui/components/u-count-to/props.js @@ -0,0 +1,59 @@ +export default { + props: { + // 开始的数值,默认从0增长到某一个数 + startVal: { + type: [String, Number], + default: uni.$u.props.countTo.startVal + }, + // 要滚动的目标数值,必须 + endVal: { + type: [String, Number], + default: uni.$u.props.countTo.endVal + }, + // 滚动到目标数值的动画持续时间,单位为毫秒(ms) + duration: { + type: [String, Number], + default: uni.$u.props.countTo.duration + }, + // 设置数值后是否自动开始滚动 + autoplay: { + type: Boolean, + default: uni.$u.props.countTo.autoplay + }, + // 要显示的小数位数 + decimals: { + type: [String, Number], + default: uni.$u.props.countTo.decimals + }, + // 是否在即将到达目标数值的时候,使用缓慢滚动的效果 + useEasing: { + type: Boolean, + default: uni.$u.props.countTo.useEasing + }, + // 十进制分割 + decimal: { + type: [String, Number], + default: uni.$u.props.countTo.decimal + }, + // 字体颜色 + color: { + type: String, + default: uni.$u.props.countTo.color + }, + // 字体大小 + fontSize: { + type: [String, Number], + default: uni.$u.props.countTo.fontSize + }, + // 是否加粗字体 + bold: { + type: Boolean, + default: uni.$u.props.countTo.bold + }, + // 千位分隔符,类似金额的分割(¥23,321.05中的",") + separator: { + type: String, + default: uni.$u.props.countTo.separator + } + } +} diff --git a/uni_modules/uview-ui/components/u-count-to/u-count-to.vue b/uni_modules/uview-ui/components/u-count-to/u-count-to.vue new file mode 100644 index 0000000..417b732 --- /dev/null +++ b/uni_modules/uview-ui/components/u-count-to/u-count-to.vue @@ -0,0 +1,184 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-datetime-picker/props.js b/uni_modules/uview-ui/components/u-datetime-picker/props.js new file mode 100644 index 0000000..f44c0f9 --- /dev/null +++ b/uni_modules/uview-ui/components/u-datetime-picker/props.js @@ -0,0 +1,116 @@ +export default { + props: { + // 是否打开组件 + show: { + type: Boolean, + default: uni.$u.props.datetimePicker.show + }, + // 是否展示顶部的操作栏 + showToolbar: { + type: Boolean, + default: uni.$u.props.datetimePicker.showToolbar + }, + // 绑定值 + value: { + type: [String, Number], + default: uni.$u.props.datetimePicker.value + }, + // 顶部标题 + title: { + type: String, + default: uni.$u.props.datetimePicker.title + }, + // 展示格式,mode=date为日期选择,mode=time为时间选择,mode=year-month为年月选择,mode=datetime为日期时间选择 + mode: { + type: String, + default: uni.$u.props.datetimePicker.mode + }, + // 可选的最大时间 + maxDate: { + type: Number, + // 最大默认值为后10年 + default: uni.$u.props.datetimePicker.maxDate + }, + // 可选的最小时间 + minDate: { + type: Number, + // 最小默认值为前10年 + default: uni.$u.props.datetimePicker.minDate + }, + // 可选的最小小时,仅mode=time有效 + minHour: { + type: Number, + default: uni.$u.props.datetimePicker.minHour + }, + // 可选的最大小时,仅mode=time有效 + maxHour: { + type: Number, + default: uni.$u.props.datetimePicker.maxHour + }, + // 可选的最小分钟,仅mode=time有效 + minMinute: { + type: Number, + default: uni.$u.props.datetimePicker.minMinute + }, + // 可选的最大分钟,仅mode=time有效 + maxMinute: { + type: Number, + default: uni.$u.props.datetimePicker.maxMinute + }, + // 选项过滤函数 + filter: { + type: [Function, null], + default: uni.$u.props.datetimePicker.filter + }, + // 选项格式化函数 + formatter: { + type: [Function, null], + default: uni.$u.props.datetimePicker.formatter + }, + // 是否显示加载中状态 + loading: { + type: Boolean, + default: uni.$u.props.datetimePicker.loading + }, + // 各列中,单个选项的高度 + itemHeight: { + type: [String, Number], + default: uni.$u.props.datetimePicker.itemHeight + }, + // 取消按钮的文字 + cancelText: { + type: String, + default: uni.$u.props.datetimePicker.cancelText + }, + // 确认按钮的文字 + confirmText: { + type: String, + default: uni.$u.props.datetimePicker.confirmText + }, + // 取消按钮的颜色 + cancelColor: { + type: String, + default: uni.$u.props.datetimePicker.cancelColor + }, + // 确认按钮的颜色 + confirmColor: { + type: String, + default: uni.$u.props.datetimePicker.confirmColor + }, + // 每列中可见选项的数量 + visibleItemCount: { + type: [String, Number], + default: uni.$u.props.datetimePicker.visibleItemCount + }, + // 是否允许点击遮罩关闭选择器 + closeOnClickOverlay: { + type: Boolean, + default: uni.$u.props.datetimePicker.closeOnClickOverlay + }, + // 各列的默认索引 + defaultIndex: { + type: Array, + default: uni.$u.props.datetimePicker.defaultIndex + } + } +} diff --git a/uni_modules/uview-ui/components/u-datetime-picker/u-datetime-picker.vue b/uni_modules/uview-ui/components/u-datetime-picker/u-datetime-picker.vue new file mode 100644 index 0000000..18d8dcc --- /dev/null +++ b/uni_modules/uview-ui/components/u-datetime-picker/u-datetime-picker.vue @@ -0,0 +1,360 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-divider/props.js b/uni_modules/uview-ui/components/u-divider/props.js new file mode 100644 index 0000000..1fa8359 --- /dev/null +++ b/uni_modules/uview-ui/components/u-divider/props.js @@ -0,0 +1,44 @@ +export default { + props: { + // 是否虚线 + dashed: { + type: Boolean, + default: uni.$u.props.divider.dashed + }, + // 是否细线 + hairline: { + type: Boolean, + default: uni.$u.props.divider.hairline + }, + // 是否以点替代文字,优先于text字段起作用 + dot: { + type: Boolean, + default: uni.$u.props.divider.dot + }, + // 内容文本的位置,left-左边,center-中间,right-右边 + textPosition: { + type: String, + default: uni.$u.props.divider.textPosition + }, + // 文本内容 + text: { + type: [String, Number], + default: uni.$u.props.divider.text + }, + // 文本大小 + textSize: { + type: [String, Number], + default: uni.$u.props.divider.textSize + }, + // 文本颜色 + textColor: { + type: String, + default: uni.$u.props.divider.textColor + }, + // 线条颜色 + lineColor: { + type: String, + default: uni.$u.props.divider.lineColor + } + } +} diff --git a/uni_modules/uview-ui/components/u-divider/u-divider.vue b/uni_modules/uview-ui/components/u-divider/u-divider.vue new file mode 100644 index 0000000..b629da6 --- /dev/null +++ b/uni_modules/uview-ui/components/u-divider/u-divider.vue @@ -0,0 +1,116 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-dropdown-item/props.js b/uni_modules/uview-ui/components/u-dropdown-item/props.js new file mode 100644 index 0000000..501a1f0 --- /dev/null +++ b/uni_modules/uview-ui/components/u-dropdown-item/props.js @@ -0,0 +1,36 @@ +export default { + props: { + // 当前选中项的value值 + value: { + type: [Number, String, Array], + default: '' + }, + // 菜单项标题 + title: { + type: [String, Number], + default: '' + }, + // 选项数据,如果传入了默认slot,此参数无效 + options: { + type: Array, + default() { + return [] + } + }, + // 是否禁用此菜单项 + disabled: { + type: Boolean, + default: false + }, + // 下拉弹窗的高度 + height: { + type: [Number, String], + default: 'auto' + }, + // 点击遮罩是否可以收起弹窗 + closeOnClickOverlay: { + type: Boolean, + default: true + } + } +} diff --git a/uni_modules/uview-ui/components/u-dropdown-item/u-dropdown-item.vue b/uni_modules/uview-ui/components/u-dropdown-item/u-dropdown-item.vue new file mode 100644 index 0000000..f830291 --- /dev/null +++ b/uni_modules/uview-ui/components/u-dropdown-item/u-dropdown-item.vue @@ -0,0 +1,127 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-dropdown/props.js b/uni_modules/uview-ui/components/u-dropdown/props.js new file mode 100644 index 0000000..5f8465e --- /dev/null +++ b/uni_modules/uview-ui/components/u-dropdown/props.js @@ -0,0 +1,65 @@ +export default { + props: { + // 标题选中时的样式 + activeStyle: { + type: [String, Object], + default: () => ({ + color: '#2979ff', + fontSize: '14px' + }) + }, + // 标题未选中时的样式 + inactiveStyle: { + type: [String, Object], + default: () => ({ + color: '#606266', + fontSize: '14px' + }) + }, + // 点击遮罩是否关闭菜单 + closeOnClickMask: { + type: Boolean, + default: true + }, + // 点击当前激活项标题是否关闭菜单 + closeOnClickSelf: { + type: Boolean, + default: true + }, + // 过渡时间 + duration: { + type: [Number, String], + default: 300 + }, + // 标题菜单的高度 + height: { + type: [Number, String], + default: 40 + }, + // 是否显示下边框 + borderBottom: { + type: Boolean, + default: false + }, + // 标题的字体大小 + titleSize: { + type: [Number, String], + default: 14 + }, + // 下拉出来的内容部分的圆角值 + borderRadius: { + type: [Number, String], + default: 0 + }, + // 菜单右侧的icon图标 + menuIcon: { + type: String, + default: 'arrow-down' + }, + // 菜单右侧图标的大小 + menuIconSize: { + type: [Number, String], + default: 14 + } + } +} diff --git a/uni_modules/uview-ui/components/u-dropdown/u-dropdown.vue b/uni_modules/uview-ui/components/u-dropdown/u-dropdown.vue new file mode 100644 index 0000000..f830291 --- /dev/null +++ b/uni_modules/uview-ui/components/u-dropdown/u-dropdown.vue @@ -0,0 +1,127 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-empty/props.js b/uni_modules/uview-ui/components/u-empty/props.js new file mode 100644 index 0000000..78662f8 --- /dev/null +++ b/uni_modules/uview-ui/components/u-empty/props.js @@ -0,0 +1,59 @@ +export default { + props: { + // 内置图标名称,或图片路径,建议绝对路径 + icon: { + type: String, + default: uni.$u.props.empty.icon + }, + // 提示文字 + text: { + type: String, + default: uni.$u.props.empty.text + }, + // 文字颜色 + textColor: { + type: String, + default: uni.$u.props.empty.textColor + }, + // 文字大小 + textSize: { + type: [String, Number], + default: uni.$u.props.empty.textSize + }, + // 图标的颜色 + iconColor: { + type: String, + default: uni.$u.props.empty.iconColor + }, + // 图标的大小 + iconSize: { + type: [String, Number], + default: uni.$u.props.empty.iconSize + }, + // 选择预置的图标类型 + mode: { + type: String, + default: uni.$u.props.empty.mode + }, + // 图标宽度,单位px + width: { + type: [String, Number], + default: uni.$u.props.empty.width + }, + // 图标高度,单位px + height: { + type: [String, Number], + default: uni.$u.props.empty.height + }, + // 是否显示组件 + show: { + type: Boolean, + default: uni.$u.props.empty.show + }, + // 组件距离上一个元素之间的距离,默认px单位 + marginTop: { + type: [String, Number], + default: uni.$u.props.empty.marginTop + } + } +} diff --git a/uni_modules/uview-ui/components/u-empty/u-empty.vue b/uni_modules/uview-ui/components/u-empty/u-empty.vue new file mode 100644 index 0000000..03d6a27 --- /dev/null +++ b/uni_modules/uview-ui/components/u-empty/u-empty.vue @@ -0,0 +1,128 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-form-item/props.js b/uni_modules/uview-ui/components/u-form-item/props.js new file mode 100644 index 0000000..7b16655 --- /dev/null +++ b/uni_modules/uview-ui/components/u-form-item/props.js @@ -0,0 +1,48 @@ +export default { + props: { + // input的label提示语 + label: { + type: String, + default: uni.$u.props.formItem.label + }, + // 绑定的值 + prop: { + type: String, + default: uni.$u.props.formItem.prop + }, + // 是否显示表单域的下划线边框 + borderBottom: { + type: [String, Boolean], + default: uni.$u.props.formItem.borderBottom + }, + // label的位置,left-左边,top-上边 + labelPosition: { + type: String, + default: uni.$u.props.formItem.labelPosition + }, + // label的宽度,单位px + labelWidth: { + type: [String, Number], + default: uni.$u.props.formItem.labelWidth + }, + // 右侧图标 + rightIcon: { + type: String, + default: uni.$u.props.formItem.rightIcon + }, + // 左侧图标 + leftIcon: { + type: String, + default: uni.$u.props.formItem.leftIcon + }, + // 是否显示左边的必填星号,只作显示用,具体校验必填的逻辑,请在rules中配置 + required: { + type: Boolean, + default: uni.$u.props.formItem.required + }, + leftIconStyle: { + type: [String, Object], + default: uni.$u.props.formItem.leftIconStyle, + } + } +} diff --git a/uni_modules/uview-ui/components/u-form-item/u-form-item.vue b/uni_modules/uview-ui/components/u-form-item/u-form-item.vue new file mode 100644 index 0000000..6aa8d69 --- /dev/null +++ b/uni_modules/uview-ui/components/u-form-item/u-form-item.vue @@ -0,0 +1,235 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-form/props.js b/uni_modules/uview-ui/components/u-form/props.js new file mode 100644 index 0000000..f2a629c --- /dev/null +++ b/uni_modules/uview-ui/components/u-form/props.js @@ -0,0 +1,45 @@ +export default { + props: { + // 当前form的需要验证字段的集合 + model: { + type: Object, + default: uni.$u.props.form.model + }, + // 验证规则 + rules: { + type: [Object, Function, Array], + default: uni.$u.props.form.rules + }, + // 有错误时的提示方式,message-提示信息,toast-进行toast提示 + // border-bottom-下边框呈现红色,none-无提示 + errorType: { + type: String, + default: uni.$u.props.form.errorType + }, + // 是否显示表单域的下划线边框 + borderBottom: { + type: Boolean, + default: uni.$u.props.form.borderBottom + }, + // label的位置,left-左边,top-上边 + labelPosition: { + type: String, + default: uni.$u.props.form.labelPosition + }, + // label的宽度,单位px + labelWidth: { + type: [String, Number], + default: uni.$u.props.form.labelWidth + }, + // lable字体的对齐方式 + labelAlign: { + type: String, + default: uni.$u.props.form.labelAlign + }, + // lable的样式,对象形式 + labelStyle: { + type: Object, + default: uni.$u.props.form.labelStyle + } + } +} diff --git a/uni_modules/uview-ui/components/u-form/u-form.vue b/uni_modules/uview-ui/components/u-form/u-form.vue new file mode 100644 index 0000000..fe2dde2 --- /dev/null +++ b/uni_modules/uview-ui/components/u-form/u-form.vue @@ -0,0 +1,214 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-gap/props.js b/uni_modules/uview-ui/components/u-gap/props.js new file mode 100644 index 0000000..89953e3 --- /dev/null +++ b/uni_modules/uview-ui/components/u-gap/props.js @@ -0,0 +1,24 @@ +export default { + props: { + // 背景颜色(默认transparent) + bgColor: { + type: String, + default: uni.$u.props.gap.bgColor + }, + // 分割槽高度,单位px(默认30) + height: { + type: [String, Number], + default: uni.$u.props.gap.height + }, + // 与上一个组件的距离 + marginTop: { + type: [String, Number], + default: uni.$u.props.gap.marginTop + }, + // 与下一个组件的距离 + marginBottom: { + type: [String, Number], + default: uni.$u.props.gap.marginBottom + } + } +} diff --git a/uni_modules/uview-ui/components/u-gap/u-gap.vue b/uni_modules/uview-ui/components/u-gap/u-gap.vue new file mode 100644 index 0000000..e4429f0 --- /dev/null +++ b/uni_modules/uview-ui/components/u-gap/u-gap.vue @@ -0,0 +1,38 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-grid-item/props.js b/uni_modules/uview-ui/components/u-grid-item/props.js new file mode 100644 index 0000000..06c3c66 --- /dev/null +++ b/uni_modules/uview-ui/components/u-grid-item/props.js @@ -0,0 +1,14 @@ +export default { + props: { + // 宫格的name + name: { + type: [String, Number, null], + default: uni.$u.props.gridItem.name + }, + // 背景颜色 + bgColor: { + type: String, + default: uni.$u.props.gridItem.bgColor + } + } +} diff --git a/uni_modules/uview-ui/components/u-grid-item/u-grid-item.vue b/uni_modules/uview-ui/components/u-grid-item/u-grid-item.vue new file mode 100644 index 0000000..fc0c7cf --- /dev/null +++ b/uni_modules/uview-ui/components/u-grid-item/u-grid-item.vue @@ -0,0 +1,209 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-grid/props.js b/uni_modules/uview-ui/components/u-grid/props.js new file mode 100644 index 0000000..87b0f6a --- /dev/null +++ b/uni_modules/uview-ui/components/u-grid/props.js @@ -0,0 +1,19 @@ +export default { + props: { + // 分成几列 + col: { + type: [String, Number], + default: uni.$u.props.grid.col + }, + // 是否显示边框 + border: { + type: Boolean, + default: uni.$u.props.grid.border + }, + // 宫格对齐方式,表现为数量少的时候,靠左,居中,还是靠右 + align: { + type: String, + default: uni.$u.props.grid.align + } + } +} diff --git a/uni_modules/uview-ui/components/u-grid/u-grid.vue b/uni_modules/uview-ui/components/u-grid/u-grid.vue new file mode 100644 index 0000000..b43cc27 --- /dev/null +++ b/uni_modules/uview-ui/components/u-grid/u-grid.vue @@ -0,0 +1,97 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-icon/font_2225171_8kdcwk4po24.ttf b/uni_modules/uview-ui/components/u-icon/font_2225171_8kdcwk4po24.ttf new file mode 100644 index 0000000000000000000000000000000000000000..befa24aa2bbbbec7d99e86cdb1428fc53938b6b7 GIT binary patch literal 55940 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 Og$uR{Ss + + + {{icon}} + + {{ label }} + + + + + + diff --git a/uni_modules/uview-ui/components/u-image/props.js b/uni_modules/uview-ui/components/u-image/props.js new file mode 100644 index 0000000..2eabb74 --- /dev/null +++ b/uni_modules/uview-ui/components/u-image/props.js @@ -0,0 +1,84 @@ +export default { + props: { + // 图片地址 + src: { + type: String, + default: uni.$u.props.image.src + }, + // 裁剪模式 + mode: { + type: String, + default: uni.$u.props.image.mode + }, + // 宽度,单位任意 + width: { + type: [String, Number], + default: uni.$u.props.image.width + }, + // 高度,单位任意 + height: { + type: [String, Number], + default: uni.$u.props.image.height + }, + // 图片形状,circle-圆形,square-方形 + shape: { + type: String, + default: uni.$u.props.image.shape + }, + // 圆角,单位任意 + radius: { + type: [String, Number], + default: uni.$u.props.image.radius + }, + // 是否懒加载,微信小程序、App、百度小程序、字节跳动小程序 + lazyLoad: { + type: Boolean, + default: uni.$u.props.image.lazyLoad + }, + // 开启长按图片显示识别微信小程序码菜单 + showMenuByLongpress: { + type: Boolean, + default: uni.$u.props.image.showMenuByLongpress + }, + // 加载中的图标,或者小图片 + loadingIcon: { + type: String, + default: uni.$u.props.image.loadingIcon + }, + // 加载失败的图标,或者小图片 + errorIcon: { + type: String, + default: uni.$u.props.image.errorIcon + }, + // 是否显示加载中的图标或者自定义的slot + showLoading: { + type: Boolean, + default: uni.$u.props.image.showLoading + }, + // 是否显示加载错误的图标或者自定义的slot + showError: { + type: Boolean, + default: uni.$u.props.image.showError + }, + // 是否需要淡入效果 + fade: { + type: Boolean, + default: uni.$u.props.image.fade + }, + // 只支持网络资源,只对微信小程序有效 + webp: { + type: Boolean, + default: uni.$u.props.image.webp + }, + // 过渡时间,单位ms + duration: { + type: [String, Number], + default: uni.$u.props.image.duration + }, + // 背景颜色,用于深色页面加载图片时,为了和背景色融合 + bgColor: { + type: String, + default: uni.$u.props.image.bgColor + } + } +} diff --git a/uni_modules/uview-ui/components/u-image/u-image.vue b/uni_modules/uview-ui/components/u-image/u-image.vue new file mode 100644 index 0000000..473e35b --- /dev/null +++ b/uni_modules/uview-ui/components/u-image/u-image.vue @@ -0,0 +1,232 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-index-anchor/props.js b/uni_modules/uview-ui/components/u-index-anchor/props.js new file mode 100644 index 0000000..6d8b59a --- /dev/null +++ b/uni_modules/uview-ui/components/u-index-anchor/props.js @@ -0,0 +1,29 @@ +export default { + props: { + // 列表锚点文本内容 + text: { + type: [String, Number], + default: uni.$u.props.indexAnchor.text + }, + // 列表锚点文字颜色 + color: { + type: String, + default: uni.$u.props.indexAnchor.color + }, + // 列表锚点文字大小,单位默认px + size: { + type: [String, Number], + default: uni.$u.props.indexAnchor.size + }, + // 列表锚点背景颜色 + bgColor: { + type: String, + default: uni.$u.props.indexAnchor.bgColor + }, + // 列表锚点高度,单位默认px + height: { + type: [String, Number], + default: uni.$u.props.indexAnchor.height + } + } +} diff --git a/uni_modules/uview-ui/components/u-index-anchor/u-index-anchor.vue b/uni_modules/uview-ui/components/u-index-anchor/u-index-anchor.vue new file mode 100644 index 0000000..b95ddef --- /dev/null +++ b/uni_modules/uview-ui/components/u-index-anchor/u-index-anchor.vue @@ -0,0 +1,91 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-index-item/props.js b/uni_modules/uview-ui/components/u-index-item/props.js new file mode 100644 index 0000000..7c11331 --- /dev/null +++ b/uni_modules/uview-ui/components/u-index-item/props.js @@ -0,0 +1,5 @@ +export default { + props: { + + } +} diff --git a/uni_modules/uview-ui/components/u-index-item/u-index-item.vue b/uni_modules/uview-ui/components/u-index-item/u-index-item.vue new file mode 100644 index 0000000..0bc7fb3 --- /dev/null +++ b/uni_modules/uview-ui/components/u-index-item/u-index-item.vue @@ -0,0 +1,87 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-index-list/props.js b/uni_modules/uview-ui/components/u-index-list/props.js new file mode 100644 index 0000000..354d459 --- /dev/null +++ b/uni_modules/uview-ui/components/u-index-list/props.js @@ -0,0 +1,29 @@ +export default { + props: { + // 右边锚点非激活的颜色 + inactiveColor: { + type: String, + default: uni.$u.props.indexList.inactiveColor + }, + // 右边锚点激活的颜色 + activeColor: { + type: String, + default: uni.$u.props.indexList.activeColor + }, + // 索引字符列表,数组形式 + indexList: { + type: Array, + default: uni.$u.props.indexList.indexList + }, + // 是否开启锚点自动吸顶 + sticky: { + type: Boolean, + default: uni.$u.props.indexList.sticky + }, + // 自定义导航栏的高度 + customNavHeight: { + type: [String, Number], + default: uni.$u.props.indexList.customNavHeight + } + } +} diff --git a/uni_modules/uview-ui/components/u-index-list/u-index-list.vue b/uni_modules/uview-ui/components/u-index-list/u-index-list.vue new file mode 100644 index 0000000..d712618 --- /dev/null +++ b/uni_modules/uview-ui/components/u-index-list/u-index-list.vue @@ -0,0 +1,440 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-input/props.js b/uni_modules/uview-ui/components/u-input/props.js new file mode 100644 index 0000000..2c50870 --- /dev/null +++ b/uni_modules/uview-ui/components/u-input/props.js @@ -0,0 +1,187 @@ +export default { + props: { + // 输入的值 + value: { + type: [String, Number], + default: uni.$u.props.input.value + }, + // 输入框类型 + // number-数字输入键盘,app-vue下可以输入浮点数,app-nvue和小程序平台下只能输入整数 + // idcard-身份证输入键盘,微信、支付宝、百度、QQ小程序 + // digit-带小数点的数字键盘,App的nvue页面、微信、支付宝、百度、头条、QQ小程序 + // text-文本输入键盘 + type: { + type: String, + default: uni.$u.props.input.type + }, + // 如果 textarea 是在一个 position:fixed 的区域,需要显示指定属性 fixed 为 true, + // 兼容性:微信小程序、百度小程序、字节跳动小程序、QQ小程序 + fixed: { + type: Boolean, + default: uni.$u.props.input.fixed + }, + // 是否禁用输入框 + disabled: { + type: Boolean, + default: uni.$u.props.input.disabled + }, + // 禁用状态时的背景色 + disabledColor: { + type: String, + default: uni.$u.props.input.disabledColor + }, + // 是否显示清除控件 + clearable: { + type: Boolean, + default: uni.$u.props.input.clearable + }, + // 是否密码类型 + password: { + type: Boolean, + default: uni.$u.props.input.password + }, + // 最大输入长度,设置为 -1 的时候不限制最大长度 + maxlength: { + type: [String, Number], + default: uni.$u.props.input.maxlength + }, + // 输入框为空时的占位符 + placeholder: { + type: String, + default: uni.$u.props.input.placeholder + }, + // 指定placeholder的样式类,注意页面或组件的style中写了scoped时,需要在类名前写/deep/ + placeholderClass: { + type: String, + default: uni.$u.props.input.placeholderClass + }, + // 指定placeholder的样式 + placeholderStyle: { + type: [String, Object], + default: uni.$u.props.input.placeholderStyle + }, + // 是否显示输入字数统计,只在 type ="text"或type ="textarea"时有效 + showWordLimit: { + type: Boolean, + default: uni.$u.props.input.showWordLimit + }, + // 设置右下角按钮的文字,有效值:send|search|next|go|done,兼容性详见uni-app文档 + // https://uniapp.dcloud.io/component/input + // https://uniapp.dcloud.io/component/textarea + confirmType: { + type: String, + default: uni.$u.props.input.confirmType + }, + // 点击键盘右下角按钮时是否保持键盘不收起,H5无效 + confirmHold: { + type: Boolean, + default: uni.$u.props.input.confirmHold + }, + // focus时,点击页面的时候不收起键盘,微信小程序有效 + holdKeyboard: { + type: Boolean, + default: uni.$u.props.input.holdKeyboard + }, + // 自动获取焦点 + // 在 H5 平台能否聚焦以及软键盘是否跟随弹出,取决于当前浏览器本身的实现。nvue 页面不支持,需使用组件的 focus()、blur() 方法控制焦点 + focus: { + type: Boolean, + default: uni.$u.props.input.focus + }, + // 键盘收起时,是否自动失去焦点,目前仅App3.0.0+有效 + autoBlur: { + type: Boolean, + default: uni.$u.props.input.autoBlur + }, + // 是否去掉 iOS 下的默认内边距,仅微信小程序,且type=textarea时有效 + disableDefaultPadding: { + type: Boolean, + default: uni.$u.props.input.disableDefaultPadding + }, + // 指定focus时光标的位置 + cursor: { + type: [String, Number], + default: uni.$u.props.input.cursor + }, + // 输入框聚焦时底部与键盘的距离 + cursorSpacing: { + type: [String, Number], + default: uni.$u.props.input.cursorSpacing + }, + // 光标起始位置,自动聚集时有效,需与selection-end搭配使用 + selectionStart: { + type: [String, Number], + default: uni.$u.props.input.selectionStart + }, + // 光标结束位置,自动聚集时有效,需与selection-start搭配使用 + selectionEnd: { + type: [String, Number], + default: uni.$u.props.input.selectionEnd + }, + // 键盘弹起时,是否自动上推页面 + adjustPosition: { + type: Boolean, + default: uni.$u.props.input.adjustPosition + }, + // 输入框内容对齐方式,可选值为:left|center|right + inputAlign: { + type: String, + default: uni.$u.props.input.inputAlign + }, + // 输入框字体的大小 + fontSize: { + type: [String, Number], + default: uni.$u.props.input.fontSize + }, + // 输入框字体颜色 + color: { + type: String, + default: uni.$u.props.input.color + }, + // 输入框前置图标 + prefixIcon: { + type: String, + default: uni.$u.props.input.prefixIcon + }, + // 前置图标样式,对象或字符串 + prefixIconStyle: { + type: [String, Object], + default: uni.$u.props.input.prefixIconStyle + }, + // 输入框后置图标 + suffixIcon: { + type: String, + default: uni.$u.props.input.suffixIcon + }, + // 后置图标样式,对象或字符串 + suffixIconStyle: { + type: [String, Object], + default: uni.$u.props.input.suffixIconStyle + }, + // 边框类型,surround-四周边框,bottom-底部边框,none-无边框 + border: { + type: String, + default: uni.$u.props.input.border + }, + // 是否只读,与disabled不同之处在于disabled会置灰组件,而readonly则不会 + readonly: { + type: Boolean, + default: uni.$u.props.input.readonly + }, + // 输入框形状,circle-圆形,square-方形 + shape: { + type: String, + default: uni.$u.props.input.shape + }, + // 用于处理或者过滤输入框内容的方法 + formatter: { + type: [Function, null], + default: uni.$u.props.input.formatter + }, + // 是否忽略组件内对文本合成系统事件的处理 + ignoreCompositionEvent: { + type: Boolean, + default: true + } + } +} diff --git a/uni_modules/uview-ui/components/u-input/u-input.vue b/uni_modules/uview-ui/components/u-input/u-input.vue new file mode 100644 index 0000000..4c83757 --- /dev/null +++ b/uni_modules/uview-ui/components/u-input/u-input.vue @@ -0,0 +1,354 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-keyboard/props.js b/uni_modules/uview-ui/components/u-keyboard/props.js new file mode 100644 index 0000000..cfdb00a --- /dev/null +++ b/uni_modules/uview-ui/components/u-keyboard/props.js @@ -0,0 +1,84 @@ +export default { + props: { + // 键盘的类型,number-数字键盘,card-身份证键盘,car-车牌号键盘 + mode: { + type: String, + default: uni.$u.props.keyboard.mode + }, + // 是否显示键盘的"."符号 + dotDisabled: { + type: Boolean, + default: uni.$u.props.keyboard.dotDisabled + }, + // 是否显示顶部工具条 + tooltip: { + type: Boolean, + default: uni.$u.props.keyboard.tooltip + }, + // 是否显示工具条中间的提示 + showTips: { + type: Boolean, + default: uni.$u.props.keyboard.showTips + }, + // 工具条中间的提示文字 + tips: { + type: String, + default: uni.$u.props.keyboard.tips + }, + // 是否显示工具条左边的"取消"按钮 + showCancel: { + type: Boolean, + default: uni.$u.props.keyboard.showCancel + }, + // 是否显示工具条右边的"完成"按钮 + showConfirm: { + type: Boolean, + default: uni.$u.props.keyboard.showConfirm + }, + // 是否打乱键盘按键的顺序 + random: { + type: Boolean, + default: uni.$u.props.keyboard.random + }, + // 是否开启底部安全区适配,开启的话,会在iPhoneX机型底部添加一定的内边距 + safeAreaInsetBottom: { + type: Boolean, + default: uni.$u.props.keyboard.safeAreaInsetBottom + }, + // 是否允许通过点击遮罩关闭键盘 + closeOnClickOverlay: { + type: Boolean, + default: uni.$u.props.keyboard.closeOnClickOverlay + }, + // 控制键盘的弹出与收起 + show: { + type: Boolean, + default: uni.$u.props.keyboard.show + }, + // 是否显示遮罩,某些时候数字键盘时,用户希望看到自己的数值,所以可能不想要遮罩 + overlay: { + type: Boolean, + default: uni.$u.props.keyboard.overlay + }, + // z-index值 + zIndex: { + type: [String, Number], + default: uni.$u.props.keyboard.zIndex + }, + // 取消按钮的文字 + cancelText: { + type: String, + default: uni.$u.props.keyboard.cancelText + }, + // 确认按钮的文字 + confirmText: { + type: String, + default: uni.$u.props.keyboard.confirmText + }, + // 输入一个中文后,是否自动切换到英文 + autoChange: { + type: Boolean, + default: uni.$u.props.keyboard.autoChange + } + } +} diff --git a/uni_modules/uview-ui/components/u-keyboard/u-keyboard.vue b/uni_modules/uview-ui/components/u-keyboard/u-keyboard.vue new file mode 100644 index 0000000..14228cb --- /dev/null +++ b/uni_modules/uview-ui/components/u-keyboard/u-keyboard.vue @@ -0,0 +1,164 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-line-progress/props.js b/uni_modules/uview-ui/components/u-line-progress/props.js new file mode 100644 index 0000000..5d7baee --- /dev/null +++ b/uni_modules/uview-ui/components/u-line-progress/props.js @@ -0,0 +1,32 @@ +export default { + props: { + // 激活部分的颜色 + activeColor: { + type: String, + default: uni.$u.props.lineProgress.activeColor + }, + inactiveColor: { + type: String, + default: uni.$u.props.lineProgress.color + }, + // 进度百分比,数值 + percentage: { + type: [String, Number], + default: uni.$u.props.lineProgress.inactiveColor + }, + // 是否在进度条内部显示百分比的值 + showText: { + type: Boolean, + default: uni.$u.props.lineProgress.showText + }, + // 进度条的高度,单位px + height: { + type: [String, Number], + default: uni.$u.props.lineProgress.height + }, + slotType:{ + type: String, + default: 'flex-end' + } + } +} diff --git a/uni_modules/uview-ui/components/u-line-progress/u-line-progress.vue b/uni_modules/uview-ui/components/u-line-progress/u-line-progress.vue new file mode 100644 index 0000000..252872d --- /dev/null +++ b/uni_modules/uview-ui/components/u-line-progress/u-line-progress.vue @@ -0,0 +1,164 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-line/props.js b/uni_modules/uview-ui/components/u-line/props.js new file mode 100644 index 0000000..2308cc3 --- /dev/null +++ b/uni_modules/uview-ui/components/u-line/props.js @@ -0,0 +1,33 @@ +export default { + props: { + color: { + type: String, + default: uni.$u.props.line.color + }, + // 长度,竖向时表现为高度,横向时表现为长度,可以为百分比,带px单位的值等 + length: { + type: [String, Number], + default: uni.$u.props.line.length + }, + // 线条方向,col-竖向,row-横向 + direction: { + type: String, + default: uni.$u.props.line.direction + }, + // 是否显示细边框 + hairline: { + type: Boolean, + default: uni.$u.props.line.hairline + }, + // 线条与上下左右元素的间距,字符串形式,如"30px"、"20px 30px" + margin: { + type: [String, Number], + default: uni.$u.props.line.margin + }, + // 是否虚线,true-虚线,false-实线 + dashed: { + type: Boolean, + default: uni.$u.props.line.dashed + } + } +} diff --git a/uni_modules/uview-ui/components/u-line/u-line.vue b/uni_modules/uview-ui/components/u-line/u-line.vue new file mode 100644 index 0000000..e0a6d92 --- /dev/null +++ b/uni_modules/uview-ui/components/u-line/u-line.vue @@ -0,0 +1,62 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-link/props.js b/uni_modules/uview-ui/components/u-link/props.js new file mode 100644 index 0000000..d39353f --- /dev/null +++ b/uni_modules/uview-ui/components/u-link/props.js @@ -0,0 +1,39 @@ +export default { + props: { + // 文字颜色 + color: { + type: String, + default: uni.$u.props.link.color + }, + // 字体大小,单位px + fontSize: { + type: [String, Number], + default: uni.$u.props.link.fontSize + }, + // 是否显示下划线 + underLine: { + type: Boolean, + default: uni.$u.props.link.underLine + }, + // 要跳转的链接 + href: { + type: String, + default: uni.$u.props.link.href + }, + // 小程序中复制到粘贴板的提示语 + mpTips: { + type: String, + default: uni.$u.props.link.mpTips + }, + // 下划线颜色 + lineColor: { + type: String, + default: uni.$u.props.link.lineColor + }, + // 超链接的问题,不使用slot形式传入,是因为nvue下无法修改颜色 + text: { + type: String, + default: uni.$u.props.link.text + } + } +} diff --git a/uni_modules/uview-ui/components/u-link/u-link.vue b/uni_modules/uview-ui/components/u-link/u-link.vue new file mode 100644 index 0000000..c6802a5 --- /dev/null +++ b/uni_modules/uview-ui/components/u-link/u-link.vue @@ -0,0 +1,83 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-list-item/props.js b/uni_modules/uview-ui/components/u-list-item/props.js new file mode 100644 index 0000000..58ddc49 --- /dev/null +++ b/uni_modules/uview-ui/components/u-list-item/props.js @@ -0,0 +1,9 @@ +export default { + props: { + // 用于滚动到指定item + anchor: { + type: [String, Number], + default: uni.$u.props.listItem.anchor + } + } +} diff --git a/uni_modules/uview-ui/components/u-list-item/u-list-item.vue b/uni_modules/uview-ui/components/u-list-item/u-list-item.vue new file mode 100644 index 0000000..1a25db6 --- /dev/null +++ b/uni_modules/uview-ui/components/u-list-item/u-list-item.vue @@ -0,0 +1,116 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-list/props.js b/uni_modules/uview-ui/components/u-list/props.js new file mode 100644 index 0000000..25406f4 --- /dev/null +++ b/uni_modules/uview-ui/components/u-list/props.js @@ -0,0 +1,76 @@ +export default { + props: { + // 控制是否出现滚动条,仅nvue有效 + showScrollbar: { + type: Boolean, + default: uni.$u.props.list.showScrollbar + }, + // 距底部多少时触发scrolltolower事件 + lowerThreshold: { + type: [String, Number], + default: uni.$u.props.list.lowerThreshold + }, + // 距顶部多少时触发scrolltoupper事件,非nvue有效 + upperThreshold: { + type: [String, Number], + default: uni.$u.props.list.upperThreshold + }, + // 设置竖向滚动条位置 + scrollTop: { + type: [String, Number], + default: uni.$u.props.list.scrollTop + }, + // 控制 onscroll 事件触发的频率,仅nvue有效 + offsetAccuracy: { + type: [String, Number], + default: uni.$u.props.list.offsetAccuracy + }, + // 启用 flexbox 布局。开启后,当前节点声明了display: flex就会成为flex container,并作用于其孩子节点,仅微信小程序有效 + enableFlex: { + type: Boolean, + default: uni.$u.props.list.enableFlex + }, + // 是否按分页模式显示List,默认值false + pagingEnabled: { + type: Boolean, + default: uni.$u.props.list.pagingEnabled + }, + // 是否允许List滚动 + scrollable: { + type: Boolean, + default: uni.$u.props.list.scrollable + }, + // 值应为某子元素id(id不能以数字开头) + scrollIntoView: { + type: String, + default: uni.$u.props.list.scrollIntoView + }, + // 在设置滚动条位置时使用动画过渡 + scrollWithAnimation: { + type: Boolean, + default: uni.$u.props.list.scrollWithAnimation + }, + // iOS点击顶部状态栏、安卓双击标题栏时,滚动条返回顶部,只对微信小程序有效 + enableBackToTop: { + type: Boolean, + default: uni.$u.props.list.enableBackToTop + }, + // 列表的高度 + height: { + type: [String, Number], + default: uni.$u.props.list.height + }, + // 列表宽度 + width: { + type: [String, Number], + default: uni.$u.props.list.width + }, + // 列表前后预渲染的屏数,1代表一个屏幕的高度,1.5代表1个半屏幕高度 + preLoadScreen: { + type: [String, Number], + default: uni.$u.props.list.preLoadScreen + } + // vue下,是否开启虚拟列表 + + } +} diff --git a/uni_modules/uview-ui/components/u-list/u-list.vue b/uni_modules/uview-ui/components/u-list/u-list.vue new file mode 100644 index 0000000..4447cab --- /dev/null +++ b/uni_modules/uview-ui/components/u-list/u-list.vue @@ -0,0 +1,157 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-loading-icon/props.js b/uni_modules/uview-ui/components/u-loading-icon/props.js new file mode 100644 index 0000000..c35524e --- /dev/null +++ b/uni_modules/uview-ui/components/u-loading-icon/props.js @@ -0,0 +1,59 @@ +export default { + props: { + // 是否显示组件 + show: { + type: Boolean, + default: uni.$u.props.loadingIcon.show + }, + // 颜色 + color: { + type: String, + default: uni.$u.props.loadingIcon.color + }, + // 提示文字颜色 + textColor: { + type: String, + default: uni.$u.props.loadingIcon.textColor + }, + // 文字和图标是否垂直排列 + vertical: { + type: Boolean, + default: uni.$u.props.loadingIcon.vertical + }, + // 模式选择,circle-圆形,spinner-花朵形,semicircle-半圆形 + mode: { + type: String, + default: uni.$u.props.loadingIcon.mode + }, + // 图标大小,单位默认px + size: { + type: [String, Number], + default: uni.$u.props.loadingIcon.size + }, + // 文字大小 + textSize: { + type: [String, Number], + default: uni.$u.props.loadingIcon.textSize + }, + // 文字内容 + text: { + type: [String, Number], + default: uni.$u.props.loadingIcon.text + }, + // 动画模式 + timingFunction: { + type: String, + default: uni.$u.props.loadingIcon.timingFunction + }, + // 动画执行周期时间 + duration: { + type: [String, Number], + default: uni.$u.props.loadingIcon.duration + }, + // mode=circle时的暗边颜色 + inactiveColor: { + type: String, + default: uni.$u.props.loadingIcon.inactiveColor + } + } +} diff --git a/uni_modules/uview-ui/components/u-loading-icon/u-loading-icon.vue b/uni_modules/uview-ui/components/u-loading-icon/u-loading-icon.vue new file mode 100644 index 0000000..2ede5c3 --- /dev/null +++ b/uni_modules/uview-ui/components/u-loading-icon/u-loading-icon.vue @@ -0,0 +1,343 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-loading-page/props.js b/uni_modules/uview-ui/components/u-loading-page/props.js new file mode 100644 index 0000000..e239b61 --- /dev/null +++ b/uni_modules/uview-ui/components/u-loading-page/props.js @@ -0,0 +1,49 @@ +export default { + props: { + // 提示内容 + loadingText: { + type: [String, Number], + default: uni.$u.props.loadingPage.loadingText + }, + // 文字上方用于替换loading动画的图片 + image: { + type: String, + default: uni.$u.props.loadingPage.image + }, + // 加载动画的模式,circle-圆形,spinner-花朵形,semicircle-半圆形 + loadingMode: { + type: String, + default: uni.$u.props.loadingPage.loadingMode + }, + // 是否加载中 + loading: { + type: Boolean, + default: uni.$u.props.loadingPage.loading + }, + // 背景色 + bgColor: { + type: String, + default: uni.$u.props.loadingPage.bgColor + }, + // 文字颜色 + color: { + type: String, + default: uni.$u.props.loadingPage.color + }, + // 文字大小 + fontSize: { + type: [String, Number], + default: uni.$u.props.loadingPage.fontSize + }, + // 图标大小 + iconSize: { + type: [String, Number], + default: uni.$u.props.loadingPage.fontSize + }, + // 加载中图标的颜色,只能rgb或者十六进制颜色值 + loadingColor: { + type: String, + default: uni.$u.props.loadingPage.loadingColor + } + } +} diff --git a/uni_modules/uview-ui/components/u-loading-page/u-loading-page.vue b/uni_modules/uview-ui/components/u-loading-page/u-loading-page.vue new file mode 100644 index 0000000..03a78ad --- /dev/null +++ b/uni_modules/uview-ui/components/u-loading-page/u-loading-page.vue @@ -0,0 +1,115 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-loadmore/props.js b/uni_modules/uview-ui/components/u-loadmore/props.js new file mode 100644 index 0000000..1e67d89 --- /dev/null +++ b/uni_modules/uview-ui/components/u-loadmore/props.js @@ -0,0 +1,94 @@ +export default { + props: { + // 组件状态,loadmore-加载前的状态,loading-加载中的状态,nomore-没有更多的状态 + status: { + type: String, + default: uni.$u.props.loadmore.status + }, + // 组件背景色 + bgColor: { + type: String, + default: uni.$u.props.loadmore.bgColor + }, + // 是否显示加载中的图标 + icon: { + type: Boolean, + default: uni.$u.props.loadmore.icon + }, + // 字体大小 + fontSize: { + type: [String, Number], + default: uni.$u.props.loadmore.fontSize + }, + // 图标大小 + iconSize: { + type: [String, Number], + default: uni.$u.props.loadmore.iconSize + }, + // 字体颜色 + color: { + type: String, + default: uni.$u.props.loadmore.color + }, + // 加载中状态的图标,spinner-花朵状图标,circle-圆圈状,semicircle-半圆 + loadingIcon: { + type: String, + default: uni.$u.props.loadmore.loadingIcon + }, + // 加载前的提示语 + loadmoreText: { + type: String, + default: uni.$u.props.loadmore.loadmoreText + }, + // 加载中提示语 + loadingText: { + type: String, + default: uni.$u.props.loadmore.loadingText + }, + // 没有更多的提示语 + nomoreText: { + type: String, + default: uni.$u.props.loadmore.nomoreText + }, + // 在“没有更多”状态下,是否显示粗点 + isDot: { + type: Boolean, + default: uni.$u.props.loadmore.isDot + }, + // 加载中图标的颜色 + iconColor: { + type: String, + default: uni.$u.props.loadmore.iconColor + }, + // 上边距 + marginTop: { + type: [String, Number], + default: uni.$u.props.loadmore.marginTop + }, + // 下边距 + marginBottom: { + type: [String, Number], + default: uni.$u.props.loadmore.marginBottom + }, + // 高度,单位px + height: { + type: [String, Number], + default: uni.$u.props.loadmore.height + }, + // 是否显示左边分割线 + line: { + type: Boolean, + default: uni.$u.props.loadmore.line + }, + // 线条颜色 + lineColor: { + type: String, + default: uni.$u.props.loadmore.lineColor + }, + // 是否虚线,true-虚线,false-实线 + dashed: { + type: Boolean, + default: uni.$u.props.loadmore.dashed + } + } +} diff --git a/uni_modules/uview-ui/components/u-loadmore/u-loadmore.vue b/uni_modules/uview-ui/components/u-loadmore/u-loadmore.vue new file mode 100644 index 0000000..73c79fe --- /dev/null +++ b/uni_modules/uview-ui/components/u-loadmore/u-loadmore.vue @@ -0,0 +1,150 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-modal/props.js b/uni_modules/uview-ui/components/u-modal/props.js new file mode 100644 index 0000000..94b3078 --- /dev/null +++ b/uni_modules/uview-ui/components/u-modal/props.js @@ -0,0 +1,89 @@ +export default { + props: { + // 是否展示modal + show: { + type: Boolean, + default: uni.$u.props.modal.show + }, + // 标题 + title: { + type: [String], + default: uni.$u.props.modal.title + }, + // 弹窗内容 + content: { + type: String, + default: uni.$u.props.modal.content + }, + // 确认文案 + confirmText: { + type: String, + default: uni.$u.props.modal.confirmText + }, + // 取消文案 + cancelText: { + type: String, + default: uni.$u.props.modal.cancelText + }, + // 是否显示确认按钮 + showConfirmButton: { + type: Boolean, + default: uni.$u.props.modal.showConfirmButton + }, + // 是否显示取消按钮 + showCancelButton: { + type: Boolean, + default: uni.$u.props.modal.showCancelButton + }, + // 确认按钮颜色 + confirmColor: { + type: String, + default: uni.$u.props.modal.confirmColor + }, + // 取消文字颜色 + cancelColor: { + type: String, + default: uni.$u.props.modal.cancelColor + }, + // 对调确认和取消的位置 + buttonReverse: { + type: Boolean, + default: uni.$u.props.modal.buttonReverse + }, + // 是否开启缩放效果 + zoom: { + type: Boolean, + default: uni.$u.props.modal.zoom + }, + // 是否异步关闭,只对确定按钮有效 + asyncClose: { + type: Boolean, + default: uni.$u.props.modal.asyncClose + }, + // 是否允许点击遮罩关闭modal + closeOnClickOverlay: { + type: Boolean, + default: uni.$u.props.modal.closeOnClickOverlay + }, + // 给一个负的margin-top,往上偏移,避免和键盘重合的情况 + negativeTop: { + type: [String, Number], + default: uni.$u.props.modal.negativeTop + }, + // modal宽度,不支持百分比,可以数值,px,rpx单位 + width: { + type: [String, Number], + default: uni.$u.props.modal.width + }, + // 确认按钮的样式,circle-圆形,square-方形,如设置,将不会显示取消按钮 + confirmButtonShape: { + type: String, + default: uni.$u.props.modal.confirmButtonShape + }, + // 弹窗动画过度时间 + duration:{ + type:String | Number, + default: uni.$u.props.modal.duration + } + } +} diff --git a/uni_modules/uview-ui/components/u-modal/u-modal.vue b/uni_modules/uview-ui/components/u-modal/u-modal.vue new file mode 100644 index 0000000..72e1ed2 --- /dev/null +++ b/uni_modules/uview-ui/components/u-modal/u-modal.vue @@ -0,0 +1,228 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-navbar/props.js b/uni_modules/uview-ui/components/u-navbar/props.js new file mode 100644 index 0000000..5398de2 --- /dev/null +++ b/uni_modules/uview-ui/components/u-navbar/props.js @@ -0,0 +1,84 @@ +export default { + props: { + // 是否开启顶部安全区适配 + safeAreaInsetTop: { + type: Boolean, + default: uni.$u.props.navbar.safeAreaInsetTop + }, + // 固定在顶部时,是否生成一个等高元素,以防止塌陷 + placeholder: { + type: Boolean, + default: uni.$u.props.navbar.placeholder + }, + // 是否固定在顶部 + fixed: { + type: Boolean, + default: uni.$u.props.navbar.fixed + }, + // 是否显示下边框 + border: { + type: Boolean, + default: uni.$u.props.navbar.border + }, + // 左边的图标 + leftIcon: { + type: String, + default: uni.$u.props.navbar.leftIcon + }, + // 左边的提示文字 + leftText: { + type: String, + default: uni.$u.props.navbar.leftText + }, + // 左右的提示文字 + rightText: { + type: String, + default: uni.$u.props.navbar.rightText + }, + // 右边的图标 + rightIcon: { + type: String, + default: uni.$u.props.navbar.rightIcon + }, + // 标题 + title: { + type: [String, Number], + default: uni.$u.props.navbar.title + }, + // 背景颜色 + bgColor: { + type: String, + default: uni.$u.props.navbar.bgColor + }, + // 标题的宽度 + titleWidth: { + type: [String, Number], + default: uni.$u.props.navbar.titleWidth + }, + // 导航栏高度 + height: { + type: [String, Number], + default: uni.$u.props.navbar.height + }, + // 左侧返回图标的大小 + leftIconSize: { + type: [String, Number], + default: uni.$u.props.navbar.leftIconSize + }, + // 左侧返回图标的颜色 + leftIconColor: { + type: String, + default: uni.$u.props.navbar.leftIconColor + }, + // 点击左侧区域(返回图标),是否自动返回上一页 + autoBack: { + type: Boolean, + default: uni.$u.props.navbar.autoBack + }, + // 标题的样式,对象或字符串 + titleStyle: { + type: [String, Object], + default: uni.$u.props.navbar.titleStyle + } + } +} diff --git a/uni_modules/uview-ui/components/u-navbar/u-navbar.vue b/uni_modules/uview-ui/components/u-navbar/u-navbar.vue new file mode 100644 index 0000000..a2bc48b --- /dev/null +++ b/uni_modules/uview-ui/components/u-navbar/u-navbar.vue @@ -0,0 +1,186 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-no-network/props.js b/uni_modules/uview-ui/components/u-no-network/props.js new file mode 100644 index 0000000..9f3af62 --- /dev/null +++ b/uni_modules/uview-ui/components/u-no-network/props.js @@ -0,0 +1,19 @@ +export default { + props: { + // 页面文字提示 + tips: { + type: String, + default: uni.$u.props.noNetwork.tips + }, + // 一个z-index值,用于设置没有网络这个组件的层次,因为页面可能会有其他定位的元素层级过高,导致此组件被覆盖 + zIndex: { + type: [String, Number], + default: uni.$u.props.noNetwork.zIndex + }, + // image 没有网络的图片提示 + image: { + type: String, + default: uni.$u.props.noNetwork.image + } + } +} diff --git a/uni_modules/uview-ui/components/u-no-network/u-no-network.vue b/uni_modules/uview-ui/components/u-no-network/u-no-network.vue new file mode 100644 index 0000000..9710729 --- /dev/null +++ b/uni_modules/uview-ui/components/u-no-network/u-no-network.vue @@ -0,0 +1,220 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-notice-bar/props.js b/uni_modules/uview-ui/components/u-notice-bar/props.js new file mode 100644 index 0000000..7040c29 --- /dev/null +++ b/uni_modules/uview-ui/components/u-notice-bar/props.js @@ -0,0 +1,70 @@ +export default { + props: { + // 显示的内容,数组 + text: { + type: [Array, String], + default: uni.$u.props.noticeBar.text + }, + // 通告滚动模式,row-横向滚动,column-竖向滚动 + direction: { + type: String, + default: uni.$u.props.noticeBar.direction + }, + // direction = row时,是否使用步进形式滚动 + step: { + type: Boolean, + default: uni.$u.props.noticeBar.step + }, + // 是否显示左侧的音量图标 + icon: { + type: String, + default: uni.$u.props.noticeBar.icon + }, + // 通告模式,link-显示右箭头,closable-显示右侧关闭图标 + mode: { + type: String, + default: uni.$u.props.noticeBar.mode + }, + // 文字颜色,各图标也会使用文字颜色 + color: { + type: String, + default: uni.$u.props.noticeBar.color + }, + // 背景颜色 + bgColor: { + type: String, + default: uni.$u.props.noticeBar.bgColor + }, + // 水平滚动时的滚动速度,即每秒滚动多少px(px),这有利于控制文字无论多少时,都能有一个恒定的速度 + speed: { + type: [String, Number], + default: uni.$u.props.noticeBar.speed + }, + // 字体大小 + fontSize: { + type: [String, Number], + default: uni.$u.props.noticeBar.fontSize + }, + // 滚动一个周期的时间长,单位ms + duration: { + type: [String, Number], + default: uni.$u.props.noticeBar.duration + }, + // 是否禁止用手滑动切换 + // 目前HX2.6.11,只支持App 2.5.5+、H5 2.5.5+、支付宝小程序、字节跳动小程序 + disableTouch: { + type: Boolean, + default: uni.$u.props.noticeBar.disableTouch + }, + // 跳转的页面路径 + url: { + type: String, + default: uni.$u.props.noticeBar.url + }, + // 页面跳转的类型 + linkType: { + type: String, + default: uni.$u.props.noticeBar.linkType + } + } +} diff --git a/uni_modules/uview-ui/components/u-notice-bar/u-notice-bar.vue b/uni_modules/uview-ui/components/u-notice-bar/u-notice-bar.vue new file mode 100644 index 0000000..a06eb39 --- /dev/null +++ b/uni_modules/uview-ui/components/u-notice-bar/u-notice-bar.vue @@ -0,0 +1,101 @@ + + + + diff --git a/uni_modules/uview-ui/components/u-notify/props.js b/uni_modules/uview-ui/components/u-notify/props.js new file mode 100644 index 0000000..57a9d71 --- /dev/null +++ b/uni_modules/uview-ui/components/u-notify/props.js @@ -0,0 +1,49 @@ +export default { + props: { + // 到顶部的距离 + top: { + type: [String, Number], + default: uni.$u.props.notify.top + }, + // 是否展示组件 + // show: { + // type: Boolean, + // default: uni.$u.props.notify.show + // }, + // type主题,primary,success,warning,error + type: { + type: String, + default: uni.$u.props.notify.type + }, + // 字体颜色 + color: { + type: String, + default: uni.$u.props.notify.color + }, + // 背景颜色 + bgColor: { + type: String, + default: uni.$u.props.notify.bgColor + }, + // 展示的文字内容 + message: { + type: String, + default: uni.$u.props.notify.message + }, + // 展示时长,为0时不消失,单位ms + duration: { + type: [String, Number], + default: uni.$u.props.notify.duration + }, + // 字体大小 + fontSize: { + type: [String, Number], + default: uni.$u.props.notify.fontSize + }, + // 是否留出顶部安全距离(状态栏高度) + safeAreaInsetTop: { + type: Boolean, + default: uni.$u.props.notify.safeAreaInsetTop + } + } +} diff --git a/uni_modules/uview-ui/components/u-notify/u-notify.vue b/uni_modules/uview-ui/components/u-notify/u-notify.vue new file mode 100644 index 0000000..30adb72 --- /dev/null +++ b/uni_modules/uview-ui/components/u-notify/u-notify.vue @@ -0,0 +1,211 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-number-box/props.js b/uni_modules/uview-ui/components/u-number-box/props.js new file mode 100644 index 0000000..fb0fa94 --- /dev/null +++ b/uni_modules/uview-ui/components/u-number-box/props.js @@ -0,0 +1,109 @@ +export default { + props: { + // 步进器标识符,在change回调返回 + name: { + type: [String, Number], + default: uni.$u.props.numberBox.name + }, + // 用于双向绑定的值,初始化时设置设为默认min值(最小值) + value: { + type: [String, Number], + default: uni.$u.props.numberBox.value + }, + // 最小值 + min: { + type: [String, Number], + default: uni.$u.props.numberBox.min + }, + // 最大值 + max: { + type: [String, Number], + default: uni.$u.props.numberBox.max + }, + // 加减的步长,可为小数 + step: { + type: [String, Number], + default: uni.$u.props.numberBox.step + }, + // 是否只允许输入整数 + integer: { + type: Boolean, + default: uni.$u.props.numberBox.integer + }, + // 是否禁用,包括输入框,加减按钮 + disabled: { + type: Boolean, + default: uni.$u.props.numberBox.disabled + }, + // 是否禁用输入框 + disabledInput: { + type: Boolean, + default: uni.$u.props.numberBox.disabledInput + }, + // 是否开启异步变更,开启后需要手动控制输入值 + asyncChange: { + type: Boolean, + default: uni.$u.props.numberBox.asyncChange + }, + // 输入框宽度,单位为px + inputWidth: { + type: [String, Number], + default: uni.$u.props.numberBox.inputWidth + }, + // 是否显示减少按钮 + showMinus: { + type: Boolean, + default: uni.$u.props.numberBox.showMinus + }, + // 是否显示增加按钮 + showPlus: { + type: Boolean, + default: uni.$u.props.numberBox.showPlus + }, + // 显示的小数位数 + decimalLength: { + type: [String, Number, null], + default: uni.$u.props.numberBox.decimalLength + }, + // 是否开启长按加减手势 + longPress: { + type: Boolean, + default: uni.$u.props.numberBox.longPress + }, + // 输入框文字和加减按钮图标的颜色 + color: { + type: String, + default: uni.$u.props.numberBox.color + }, + // 按钮大小,宽高等于此值,单位px,输入框高度和此值保持一致 + buttonSize: { + type: [String, Number], + default: uni.$u.props.numberBox.buttonSize + }, + // 输入框和按钮的背景颜色 + bgColor: { + type: String, + default: uni.$u.props.numberBox.bgColor + }, + // 指定光标于键盘的距离,避免键盘遮挡输入框,单位px + cursorSpacing: { + type: [String, Number], + default: uni.$u.props.numberBox.cursorSpacing + }, + // 是否禁用增加按钮 + disablePlus: { + type: Boolean, + default: uni.$u.props.numberBox.disablePlus + }, + // 是否禁用减少按钮 + disableMinus: { + type: Boolean, + default: uni.$u.props.numberBox.disableMinus + }, + // 加减按钮图标的样式 + iconStyle: { + type: [Object, String], + default: uni.$u.props.numberBox.iconStyle + } + } +} diff --git a/uni_modules/uview-ui/components/u-number-box/u-number-box.vue b/uni_modules/uview-ui/components/u-number-box/u-number-box.vue new file mode 100644 index 0000000..69211c5 --- /dev/null +++ b/uni_modules/uview-ui/components/u-number-box/u-number-box.vue @@ -0,0 +1,416 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-number-keyboard/props.js b/uni_modules/uview-ui/components/u-number-keyboard/props.js new file mode 100644 index 0000000..5e3bf55 --- /dev/null +++ b/uni_modules/uview-ui/components/u-number-keyboard/props.js @@ -0,0 +1,19 @@ +export default { + props: { + // 键盘的类型,number-数字键盘,card-身份证键盘 + mode: { + type: String, + default: uni.$u.props.numberKeyboard.value + }, + // 是否显示键盘的"."符号 + dotDisabled: { + type: Boolean, + default: uni.$u.props.numberKeyboard.dotDisabled + }, + // 是否打乱键盘按键的顺序 + random: { + type: Boolean, + default: uni.$u.props.numberKeyboard.random + } + } +} diff --git a/uni_modules/uview-ui/components/u-number-keyboard/u-number-keyboard.vue b/uni_modules/uview-ui/components/u-number-keyboard/u-number-keyboard.vue new file mode 100644 index 0000000..4f505c6 --- /dev/null +++ b/uni_modules/uview-ui/components/u-number-keyboard/u-number-keyboard.vue @@ -0,0 +1,196 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-overlay/props.js b/uni_modules/uview-ui/components/u-overlay/props.js new file mode 100644 index 0000000..e6974df --- /dev/null +++ b/uni_modules/uview-ui/components/u-overlay/props.js @@ -0,0 +1,24 @@ +export default { + props: { + // 是否显示遮罩 + show: { + type: Boolean, + default: uni.$u.props.overlay.show + }, + // 层级z-index + zIndex: { + type: [String, Number], + default: uni.$u.props.overlay.zIndex + }, + // 遮罩的过渡时间,单位为ms + duration: { + type: [String, Number], + default: uni.$u.props.overlay.duration + }, + // 不透明度值,当做rgba的第四个参数 + opacity: { + type: [String, Number], + default: uni.$u.props.overlay.opacity + } + } +} diff --git a/uni_modules/uview-ui/components/u-overlay/u-overlay.vue b/uni_modules/uview-ui/components/u-overlay/u-overlay.vue new file mode 100644 index 0000000..92de4e9 --- /dev/null +++ b/uni_modules/uview-ui/components/u-overlay/u-overlay.vue @@ -0,0 +1,68 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-parse/node/node.vue b/uni_modules/uview-ui/components/u-parse/node/node.vue new file mode 100644 index 0000000..73e30fd --- /dev/null +++ b/uni_modules/uview-ui/components/u-parse/node/node.vue @@ -0,0 +1,499 @@ +