├── src
├── pages
│ ├── about
│ │ ├── about.json
│ │ ├── about.js
│ │ ├── about.wxss
│ │ └── about.wxml
│ ├── create
│ │ ├── create.json
│ │ ├── create.wxss
│ │ ├── create.wxml
│ │ └── create.js
│ ├── done
│ │ ├── done.json
│ │ ├── done.wxss
│ │ ├── done.wxml
│ │ └── done.js
│ ├── open
│ │ ├── open.json
│ │ ├── open.wxss
│ │ ├── open.wxml
│ │ └── open.js
│ └── index
│ │ ├── index.js
│ │ ├── index.wxml
│ │ └── index.wxss
├── components
│ ├── topToast
│ │ ├── topToast.json
│ │ ├── topToast.wxml
│ │ ├── topToast.wxss
│ │ └── topToast.js
│ └── happyLoading
│ │ ├── happyLoading.json
│ │ ├── happyLoading.wxml
│ │ ├── happyLoading.js
│ │ └── happyLoading.wxss
├── resources
│ ├── icons
│ │ ├── icon_send.png
│ │ ├── icon_about.png
│ │ ├── icon_receive.png
│ │ ├── icon_about_81x81.png
│ │ ├── icon_home_81x81.png
│ │ ├── icon_send_81x81.png
│ │ ├── icon_receive_81x81.png
│ │ ├── icon_send_sel_81x81.png
│ │ ├── icon_about_sel_81x81.png
│ │ └── icon_receive_sel_81x81.png
│ ├── images
│ │ ├── envelope.png
│ │ ├── icon_secret_round.png
│ │ ├── icon_secret_square.png
│ │ ├── icon_secret_round_c.png
│ │ ├── icon_secret_round_256x256.png
│ │ ├── icon_secret_square_144x144.png
│ │ ├── icon_secret_square_400x400.jpg
│ │ ├── icon_secret_square_400x400.png
│ │ └── icon_secret_round.svg
│ ├── screenshots
│ │ ├── secretends_01.png
│ │ ├── secretends_02.png
│ │ ├── secretends_03.png
│ │ ├── secretends_04.png
│ │ ├── secretends_05.png
│ │ ├── secretends_1829.png
│ │ └── qr_secretends_860x860.jpg
│ └── style
│ │ └── weui.wxss
├── app.wxss
├── project.config.json
├── libs
│ ├── wdatetime.js
│ ├── wchar.js
│ ├── wlib.js
│ ├── wurl.js
│ └── cipher
│ │ ├── wsha256.js
│ │ └── waes.js
├── models
│ └── secret
│ │ ├── CSignature.js
│ │ ├── CEncryptHint.js
│ │ └── CSecretEnds.js
├── app.js
└── app.json
├── design
├── index.psd
├── envelope.psd
├── SecretEnds_1280.jpg
├── SecretEnds_258.jpg
├── SecretEnds_344.jpg
├── SecretEnds_430.jpg
├── references
│ ├── 223213.png
│ ├── 3-512.png
│ ├── email2.jpg
│ ├── envelope.png
│ ├── unnamed.png
│ ├── 1200x630bb.jpg
│ ├── 1408500330.jpg
│ ├── unnamed (1).png
│ ├── 11915-envelope.png
│ ├── envelope-icon.png
│ ├── icon_receive.png
│ ├── top-secret-mail.jpg
│ ├── top_secret_stamp.png
│ ├── encrypted-message.png
│ ├── icon_receive_81x81.png
│ ├── buaaqkzbhytexqawqsop.jpg
│ ├── encrypted-email-icons.png
│ ├── windows_10_mail_icon.jpg
│ ├── Secure-Mail-icon-300x212.png
│ ├── icon_receive_sel_81x81.png
│ ├── sendsafely-envelope-logo.png
│ ├── top-secret-stamp-EMEF4X.jpg
│ ├── Office-365-Encrypted-Email.jpg
│ ├── 55118-envelope-back-outline.png
│ ├── letter_open_email_read_text-512.png
│ ├── 0cf1a44bf2a8b732596c571040b857f6.jpg
│ ├── 413d353506bd4e2348f103ef0dacb235.jpg
│ ├── 6507dbf05c8ef354a4ef3dbb5dc3a606.jpg
│ ├── 6e42939a4366946404ace06152a83362.jpg
│ ├── 7d8657ceb98c4292acd9ad661df4e7a4.jpg
│ ├── afd376134c5b330e0fbe4da83b43d073.jpg
│ ├── ccc7cadcb760ba13b1489af0dcb5d002.jpg
│ ├── ee3aa003f2667a02e135420ebca852f0.jpg
│ ├── best-encrypted-email-services-business.png
│ ├── envelope-icon-white-background-33918180.jpg
│ ├── voltage-comprehensive-streamline-compliance-feature-icon.png
│ ├── 4d5cc0e6a7b43f5e5aff90f01c655544--top-secret-stamp-old-paper.jpg
│ ├── depositphotos_69206881-stock-illustration-sealed-envelope-icon.jpg
│ ├── mail-encryption-interface-symbol-of-an-envelope-back-with-a-padlock_318-49727.jpg
│ ├── 40210741-brown-paper-sealed-with-string-envelope-template-vector-isolated-on-white.jpg
│ ├── correspondence_express_envelope_folder_post_postal_courier_mail_papers_business_service_message_documents_packet_package_packaging_sealed_confidential_information_send_flat_design_icon-512.png
│ ├── envelope-icon.svg
│ └── secret.svg
├── SecretEnds_860x860.jpg
└── screenshots
│ ├── IMG_1828.PNG
│ ├── IMG_1828.jpg
│ ├── IMG_1829.PNG
│ ├── IMG_1829.jpg
│ ├── IMG_1830.PNG
│ ├── IMG_1830.jpg
│ ├── IMG_1831.PNG
│ ├── IMG_1831.jpg
│ ├── IMG_1832.PNG
│ └── IMG_1832.jpg
├── LICENSE
├── .gitignore
└── README.md
/src/pages/about/about.json:
--------------------------------------------------------------------------------
1 | {
2 | "navigationBarTitleText": "关于"
3 | }
--------------------------------------------------------------------------------
/design/index.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/index.psd
--------------------------------------------------------------------------------
/src/components/topToast/topToast.json:
--------------------------------------------------------------------------------
1 | {
2 | "component": true,
3 | "usingComponents": {}
4 | }
--------------------------------------------------------------------------------
/design/envelope.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/envelope.psd
--------------------------------------------------------------------------------
/src/components/happyLoading/happyLoading.json:
--------------------------------------------------------------------------------
1 | {
2 | "component": true,
3 | "usingComponents": {}
4 | }
--------------------------------------------------------------------------------
/design/SecretEnds_1280.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/SecretEnds_1280.jpg
--------------------------------------------------------------------------------
/design/SecretEnds_258.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/SecretEnds_258.jpg
--------------------------------------------------------------------------------
/design/SecretEnds_344.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/SecretEnds_344.jpg
--------------------------------------------------------------------------------
/design/SecretEnds_430.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/SecretEnds_430.jpg
--------------------------------------------------------------------------------
/design/references/223213.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/references/223213.png
--------------------------------------------------------------------------------
/design/references/3-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/references/3-512.png
--------------------------------------------------------------------------------
/design/references/email2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/references/email2.jpg
--------------------------------------------------------------------------------
/design/SecretEnds_860x860.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/SecretEnds_860x860.jpg
--------------------------------------------------------------------------------
/design/references/envelope.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/references/envelope.png
--------------------------------------------------------------------------------
/design/references/unnamed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/references/unnamed.png
--------------------------------------------------------------------------------
/design/screenshots/IMG_1828.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/screenshots/IMG_1828.PNG
--------------------------------------------------------------------------------
/design/screenshots/IMG_1828.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/screenshots/IMG_1828.jpg
--------------------------------------------------------------------------------
/design/screenshots/IMG_1829.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/screenshots/IMG_1829.PNG
--------------------------------------------------------------------------------
/design/screenshots/IMG_1829.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/screenshots/IMG_1829.jpg
--------------------------------------------------------------------------------
/design/screenshots/IMG_1830.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/screenshots/IMG_1830.PNG
--------------------------------------------------------------------------------
/design/screenshots/IMG_1830.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/screenshots/IMG_1830.jpg
--------------------------------------------------------------------------------
/design/screenshots/IMG_1831.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/screenshots/IMG_1831.PNG
--------------------------------------------------------------------------------
/design/screenshots/IMG_1831.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/screenshots/IMG_1831.jpg
--------------------------------------------------------------------------------
/design/screenshots/IMG_1832.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/screenshots/IMG_1832.PNG
--------------------------------------------------------------------------------
/design/screenshots/IMG_1832.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/screenshots/IMG_1832.jpg
--------------------------------------------------------------------------------
/design/references/1200x630bb.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/references/1200x630bb.jpg
--------------------------------------------------------------------------------
/design/references/1408500330.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/references/1408500330.jpg
--------------------------------------------------------------------------------
/design/references/unnamed (1).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/references/unnamed (1).png
--------------------------------------------------------------------------------
/src/resources/icons/icon_send.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/src/resources/icons/icon_send.png
--------------------------------------------------------------------------------
/src/resources/images/envelope.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/src/resources/images/envelope.png
--------------------------------------------------------------------------------
/design/references/11915-envelope.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/references/11915-envelope.png
--------------------------------------------------------------------------------
/design/references/envelope-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/references/envelope-icon.png
--------------------------------------------------------------------------------
/design/references/icon_receive.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/references/icon_receive.png
--------------------------------------------------------------------------------
/src/resources/icons/icon_about.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/src/resources/icons/icon_about.png
--------------------------------------------------------------------------------
/src/resources/icons/icon_receive.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/src/resources/icons/icon_receive.png
--------------------------------------------------------------------------------
/design/references/top-secret-mail.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/references/top-secret-mail.jpg
--------------------------------------------------------------------------------
/design/references/top_secret_stamp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/references/top_secret_stamp.png
--------------------------------------------------------------------------------
/design/references/encrypted-message.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/references/encrypted-message.png
--------------------------------------------------------------------------------
/design/references/icon_receive_81x81.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/references/icon_receive_81x81.png
--------------------------------------------------------------------------------
/src/resources/icons/icon_about_81x81.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/src/resources/icons/icon_about_81x81.png
--------------------------------------------------------------------------------
/src/resources/icons/icon_home_81x81.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/src/resources/icons/icon_home_81x81.png
--------------------------------------------------------------------------------
/src/resources/icons/icon_send_81x81.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/src/resources/icons/icon_send_81x81.png
--------------------------------------------------------------------------------
/design/references/buaaqkzbhytexqawqsop.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/references/buaaqkzbhytexqawqsop.jpg
--------------------------------------------------------------------------------
/design/references/encrypted-email-icons.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/references/encrypted-email-icons.png
--------------------------------------------------------------------------------
/design/references/windows_10_mail_icon.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/references/windows_10_mail_icon.jpg
--------------------------------------------------------------------------------
/src/resources/icons/icon_receive_81x81.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/src/resources/icons/icon_receive_81x81.png
--------------------------------------------------------------------------------
/src/resources/icons/icon_send_sel_81x81.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/src/resources/icons/icon_send_sel_81x81.png
--------------------------------------------------------------------------------
/src/resources/images/icon_secret_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/src/resources/images/icon_secret_round.png
--------------------------------------------------------------------------------
/src/resources/images/icon_secret_square.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/src/resources/images/icon_secret_square.png
--------------------------------------------------------------------------------
/src/resources/screenshots/secretends_01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/src/resources/screenshots/secretends_01.png
--------------------------------------------------------------------------------
/src/resources/screenshots/secretends_02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/src/resources/screenshots/secretends_02.png
--------------------------------------------------------------------------------
/src/resources/screenshots/secretends_03.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/src/resources/screenshots/secretends_03.png
--------------------------------------------------------------------------------
/src/resources/screenshots/secretends_04.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/src/resources/screenshots/secretends_04.png
--------------------------------------------------------------------------------
/src/resources/screenshots/secretends_05.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/src/resources/screenshots/secretends_05.png
--------------------------------------------------------------------------------
/design/references/Secure-Mail-icon-300x212.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/references/Secure-Mail-icon-300x212.png
--------------------------------------------------------------------------------
/design/references/icon_receive_sel_81x81.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/references/icon_receive_sel_81x81.png
--------------------------------------------------------------------------------
/design/references/sendsafely-envelope-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/references/sendsafely-envelope-logo.png
--------------------------------------------------------------------------------
/design/references/top-secret-stamp-EMEF4X.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/references/top-secret-stamp-EMEF4X.jpg
--------------------------------------------------------------------------------
/src/resources/icons/icon_about_sel_81x81.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/src/resources/icons/icon_about_sel_81x81.png
--------------------------------------------------------------------------------
/src/resources/icons/icon_receive_sel_81x81.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/src/resources/icons/icon_receive_sel_81x81.png
--------------------------------------------------------------------------------
/src/resources/images/icon_secret_round_c.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/src/resources/images/icon_secret_round_c.png
--------------------------------------------------------------------------------
/src/resources/screenshots/secretends_1829.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/src/resources/screenshots/secretends_1829.png
--------------------------------------------------------------------------------
/design/references/Office-365-Encrypted-Email.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/references/Office-365-Encrypted-Email.jpg
--------------------------------------------------------------------------------
/design/references/55118-envelope-back-outline.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/references/55118-envelope-back-outline.png
--------------------------------------------------------------------------------
/src/pages/create/create.json:
--------------------------------------------------------------------------------
1 | {
2 | "navigationBarTitleText": "创建",
3 | "usingComponents":
4 | {
5 | "toptoast": "/components/topToast/topToast"
6 | }
7 | }
--------------------------------------------------------------------------------
/src/pages/done/done.json:
--------------------------------------------------------------------------------
1 | {
2 | "navigationBarTitleText": "纸条已加密",
3 | "usingComponents":
4 | {
5 | "toptoast": "/components/topToast/topToast"
6 | }
7 | }
--------------------------------------------------------------------------------
/src/resources/images/icon_secret_round_256x256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/src/resources/images/icon_secret_round_256x256.png
--------------------------------------------------------------------------------
/src/resources/images/icon_secret_square_144x144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/src/resources/images/icon_secret_square_144x144.png
--------------------------------------------------------------------------------
/src/resources/images/icon_secret_square_400x400.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/src/resources/images/icon_secret_square_400x400.jpg
--------------------------------------------------------------------------------
/src/resources/images/icon_secret_square_400x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/src/resources/images/icon_secret_square_400x400.png
--------------------------------------------------------------------------------
/src/resources/screenshots/qr_secretends_860x860.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/src/resources/screenshots/qr_secretends_860x860.jpg
--------------------------------------------------------------------------------
/design/references/letter_open_email_read_text-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/references/letter_open_email_read_text-512.png
--------------------------------------------------------------------------------
/design/references/0cf1a44bf2a8b732596c571040b857f6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/references/0cf1a44bf2a8b732596c571040b857f6.jpg
--------------------------------------------------------------------------------
/design/references/413d353506bd4e2348f103ef0dacb235.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/references/413d353506bd4e2348f103ef0dacb235.jpg
--------------------------------------------------------------------------------
/design/references/6507dbf05c8ef354a4ef3dbb5dc3a606.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/references/6507dbf05c8ef354a4ef3dbb5dc3a606.jpg
--------------------------------------------------------------------------------
/design/references/6e42939a4366946404ace06152a83362.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/references/6e42939a4366946404ace06152a83362.jpg
--------------------------------------------------------------------------------
/design/references/7d8657ceb98c4292acd9ad661df4e7a4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/references/7d8657ceb98c4292acd9ad661df4e7a4.jpg
--------------------------------------------------------------------------------
/design/references/afd376134c5b330e0fbe4da83b43d073.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/references/afd376134c5b330e0fbe4da83b43d073.jpg
--------------------------------------------------------------------------------
/design/references/ccc7cadcb760ba13b1489af0dcb5d002.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/references/ccc7cadcb760ba13b1489af0dcb5d002.jpg
--------------------------------------------------------------------------------
/design/references/ee3aa003f2667a02e135420ebca852f0.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/references/ee3aa003f2667a02e135420ebca852f0.jpg
--------------------------------------------------------------------------------
/design/references/best-encrypted-email-services-business.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/references/best-encrypted-email-services-business.png
--------------------------------------------------------------------------------
/design/references/envelope-icon-white-background-33918180.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/references/envelope-icon-white-background-33918180.jpg
--------------------------------------------------------------------------------
/src/components/happyLoading/happyLoading.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
--------------------------------------------------------------------------------
/design/references/voltage-comprehensive-streamline-compliance-feature-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/references/voltage-comprehensive-streamline-compliance-feature-icon.png
--------------------------------------------------------------------------------
/src/pages/open/open.json:
--------------------------------------------------------------------------------
1 | {
2 | "navigationBarTitleText": "接收",
3 | "usingComponents":
4 | {
5 | "toptoast": "/components/topToast/topToast",
6 | "happyloading": "/components/happyLoading/happyLoading"
7 | }
8 | }
--------------------------------------------------------------------------------
/design/references/4d5cc0e6a7b43f5e5aff90f01c655544--top-secret-stamp-old-paper.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/references/4d5cc0e6a7b43f5e5aff90f01c655544--top-secret-stamp-old-paper.jpg
--------------------------------------------------------------------------------
/design/references/depositphotos_69206881-stock-illustration-sealed-envelope-icon.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/references/depositphotos_69206881-stock-illustration-sealed-envelope-icon.jpg
--------------------------------------------------------------------------------
/design/references/mail-encryption-interface-symbol-of-an-envelope-back-with-a-padlock_318-49727.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/references/mail-encryption-interface-symbol-of-an-envelope-back-with-a-padlock_318-49727.jpg
--------------------------------------------------------------------------------
/design/references/40210741-brown-paper-sealed-with-string-envelope-template-vector-isolated-on-white.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/references/40210741-brown-paper-sealed-with-string-envelope-template-vector-isolated-on-white.jpg
--------------------------------------------------------------------------------
/src/components/topToast/topToast.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 | {{ message }}
7 |
8 |
--------------------------------------------------------------------------------
/src/app.wxss:
--------------------------------------------------------------------------------
1 | @import "resources/style/weui.wxss";
2 |
3 | /**
4 | * app.wxss
5 | */
6 | .container
7 | {
8 | width: 100%;
9 | height: 100%;
10 | padding: 0;
11 | background-color: #fff;
12 | }
13 |
14 |
15 |
16 | .footer-buttons
17 | {
18 | padding: 20rpx 30rpx 20rpx 30rpx;
19 | }
20 | .footer-buttons .footer-buttons-primary
21 | {
22 | width: 100%;
23 | color: #fff;
24 | background-color: #273b7a;
25 | }
--------------------------------------------------------------------------------
/design/references/correspondence_express_envelope_folder_post_postal_courier_mail_papers_business_service_message_documents_packet_package_packaging_sealed_confidential_information_send_flat_design_icon-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dekuan/mini.wx.secretends/HEAD/design/references/correspondence_express_envelope_folder_post_postal_courier_mail_papers_business_service_message_documents_packet_package_packaging_sealed_confidential_information_send_flat_design_icon-512.png
--------------------------------------------------------------------------------
/src/pages/about/about.js:
--------------------------------------------------------------------------------
1 | /**
2 | * about
3 | */
4 | const app = getApp();
5 |
6 |
7 |
8 |
9 | Page({
10 |
11 | data:
12 | {
13 | },
14 |
15 | onLoad: function ( oOptions )
16 | {
17 | },
18 |
19 | onShareAppMessage : function( res )
20 | {
21 | // if ('button' === res.from )
22 | // {
23 | // // 来自页面内转发按钮
24 | // console.log( res.target );
25 | // }
26 |
27 | return {
28 | title : '关于「加密纸条」',
29 | path : '/pages/about/about',
30 | success : function( res )
31 | {
32 | // 转发成功
33 | },
34 | fail : function( res )
35 | {
36 | // 转发失败
37 | }
38 | }
39 | }
40 |
41 |
42 |
43 |
44 |
45 |
46 | })
--------------------------------------------------------------------------------
/src/components/happyLoading/happyLoading.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Component
3 | */
4 | Component
5 | ({
6 | /**
7 | * 组件的属性列表
8 | */
9 | properties:
10 | {
11 | show:
12 | {
13 | type: Boolean,
14 | value: false
15 | },
16 | src:
17 | {
18 | type: String,
19 | value: ""
20 | }
21 | },
22 |
23 | /**
24 | * 组件的初始数据/内部数据
25 | */
26 | data:
27 | {
28 | },
29 |
30 | /**
31 | * 组件的方法列表
32 | */
33 | methods:
34 | {
35 | showLoading()
36 | {
37 | this.setData
38 | ({
39 | show: true
40 | });
41 | },
42 | hideLoading()
43 | {
44 | this.setData
45 | ({
46 | show: false
47 | });
48 | }
49 | }
50 |
51 |
52 |
53 | })
--------------------------------------------------------------------------------
/src/project.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "description": "项目配置文件。",
3 | "setting": {
4 | "urlCheck": true,
5 | "es6": true,
6 | "postcss": true,
7 | "minified": true,
8 | "newFeature": true
9 | },
10 | "compileType": "miniprogram",
11 | "libVersion": "1.9.1",
12 | "appid": "wxebbcee4290016dbf",
13 | "projectname": "SecretEnds",
14 | "isGameTourist": false,
15 | "condition": {
16 | "search": {
17 | "current": -1,
18 | "list": []
19 | },
20 | "conversation": {
21 | "current": -1,
22 | "list": []
23 | },
24 | "game": {
25 | "currentL": -1,
26 | "list": []
27 | },
28 | "miniprogram": {
29 | "current": -1,
30 | "list": []
31 | }
32 | }
33 | }
--------------------------------------------------------------------------------
/src/pages/done/done.wxss:
--------------------------------------------------------------------------------
1 | /**
2 | * envelope
3 | */
4 | .envelope
5 | {
6 | display: flex;
7 | flex-direction: column;
8 | align-items: center;
9 | padding: 90rpx 0 90rpx 0;
10 | background-color: #273b7a;
11 | }
12 | .envelope .envelope-icon
13 | {
14 | width: 420rpx;
15 | height: 320rpx;
16 | background-size: cover;
17 | }
18 |
19 |
20 |
21 | /**
22 | * main
23 | */
24 | .main
25 | {
26 | padding: 20rpx 0 0 0;
27 | }
28 | .main .main-section
29 | {
30 | padding: 20rpx 30rpx 10rpx 30rpx;
31 | }
32 | .main .main-label
33 | {
34 | color: #273b7a;
35 | font-weight: bold;
36 | padding: 10rpx 20rpx 10rpx 0;
37 | }
38 | .main .main-text
39 | {
40 | color: #273b7a;
41 | font-weight: normal;
42 | padding: 10rpx 20rpx 10rpx 0;
43 | }
44 |
45 |
--------------------------------------------------------------------------------
/src/pages/about/about.wxss:
--------------------------------------------------------------------------------
1 | /**
2 | * product
3 | */
4 | .product
5 | {
6 | display: flex;
7 | flex-direction: column;
8 | align-items: center;
9 | padding: 120rpx 0 120rpx 0;
10 | background-color: #273b7a;
11 | }
12 | .product .logo
13 | {
14 | width: 260rpx;
15 | height: 260rpx;
16 | background-size: 260rpx 260rpx;
17 | border-radius: 130rpx;
18 | }
19 |
20 |
21 |
22 | /**
23 | * main
24 | */
25 | .main
26 | {
27 | display: flex;
28 | flex-direction: column;
29 | align-items: center;
30 | padding: 40rpx 0 0 0;
31 | }
32 | .main .main-body
33 | {
34 | padding: 0 40rpx 60rpx 40rpx;
35 | }
36 | .main .main-body .main-body-title
37 | {
38 | display: block;
39 | font-size: 38rpx;
40 | font-weight: bold;
41 | color: #273b7a;
42 | padding: 0rpx 0 16rpx 0;
43 | }
44 | .main .main-body .main-body-text
45 | {
46 | display: block;
47 | font-size: 38rpx;
48 | font-weight: normal;
49 | color: #273b7a;
50 | padding: 10rpx 0 10rpx 0;
51 | }
--------------------------------------------------------------------------------
/src/components/topToast/topToast.wxss:
--------------------------------------------------------------------------------
1 | /**
2 | * components/top-toast/top-toast.wxss
3 | */
4 | .center-block
5 | {
6 | z-index: 2000;
7 | display: block;
8 | margin-right: auto;
9 | margin-left: auto;
10 | }
11 |
12 |
13 | /**
14 | * top-toast
15 | */
16 | .top-toast
17 | {
18 | z-index: 2000;
19 | display: block;
20 | position: fixed;
21 | top: 0rpx;
22 | left: 0rpx;
23 | width: 100%;
24 | min-height: 120rpx;
25 | padding: 0;
26 | }
27 | .top-toast .top-toast-content
28 | {
29 | position: relative;
30 | padding: 30rpx;
31 | }
32 | .top-toast .top-toast-content .text
33 | {
34 | width: 100%;
35 | font-size: 38rpx;
36 | color: #FFFFFF;
37 | line-height: 58rpx;
38 | border-width: 0rpx;
39 | text-align: center;
40 | }
41 |
42 | .top-toast-ok { background: rgba( 3, 201, 3, 0.9 ); }
43 | .top-toast-wrn { background: rgba( 255, 153, 00, 0.9 ); }
44 | .top-toast-err { background: rgba( 237, 66, 75, 0.9 ); }
45 | .top-toast-def { background: rgba( 17, 17, 17, 0.9 ); }
--------------------------------------------------------------------------------
/src/pages/done/done.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
9 |
10 |
11 |
12 |
13 |
14 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | 这是一张「加密纸条」,解密提示:
26 | {{ sPasswordHint }}
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/src/pages/index/index.js:
--------------------------------------------------------------------------------
1 | //
2 | // index.js
3 | // 获取应用实例
4 | //
5 | var wurl = require( '../../libs/wurl.js' );
6 | const app = getApp();
7 |
8 |
9 |
10 |
11 | Page({
12 |
13 | data:
14 | {
15 | },
16 |
17 | onLoad: function ( oOptions )
18 | {
19 | console.log( "##########" );
20 | console.log( oOptions );
21 | console.log("wurl.getCurrentPageUrl() = " + wurl.getCurrentPageUrl());
22 | console.log("wurl.getCurrentPageArgs() = ", wurl.getCurrentPageArgs());
23 | console.log("wurl.getCurrentPageUrlWithArgs() = " + wurl.getCurrentPageUrlWithArgs());
24 | console.log( "##########" );
25 | },
26 |
27 | onShareAppMessage : function( res )
28 | {
29 | if ('button' === res.from )
30 | {
31 | // 来自页面内转发按钮
32 | console.log( res.target );
33 | }
34 |
35 | return {
36 | title : '「加密纸条」',
37 | path : '/pages/index/index?fp=share',
38 | success : function( res )
39 | {
40 | // 转发成功
41 | },
42 | fail : function( res )
43 | {
44 | // 转发失败
45 | }
46 | }
47 | }
48 |
49 |
50 |
51 |
52 |
53 |
54 | })
--------------------------------------------------------------------------------
/src/pages/index/index.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | 超强 AES 256bits 加密,美国军方使用
8 |
9 |
10 | 端到端通讯,无服务器中转,非常安全
11 |
12 |
13 |
14 |
15 |
16 |
17 |
20 |
21 |
22 | 了解安全原理
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | 创建加密纸条
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/src/libs/wdatetime.js:
--------------------------------------------------------------------------------
1 | const formatDateTime = oDate =>
2 | {
3 | return formatDate( oDate ) + ' ' + formatTime( oDate );
4 | }
5 |
6 | const formatDate = oDate =>
7 | {
8 | const nYear = oDate.getFullYear();
9 | const nMonth = oDate.getMonth() + 1;
10 | const nDay = oDate.getDate();
11 |
12 | return [ nYear, nMonth, nDay ].map( _formatNumber ).join( '-' );
13 | }
14 |
15 | const formatTime = oDate =>
16 | {
17 | const nHour = oDate.getHours();
18 | const nMinute = oDate.getMinutes();
19 | const nSecond = oDate.getSeconds();
20 |
21 | return [ nHour, nMinute, nSecond ].map( _formatNumber ).join( ':' );
22 | }
23 |
24 | function getCurrentTimestamp()
25 | {
26 | return ( new Date() ).getTime();
27 | }
28 |
29 |
30 |
31 | /**
32 | * @ private
33 | */
34 | const _formatNumber = nItem =>
35 | {
36 | return nItem > 9 ? new String( nItem ) : '0' + new String( nItem );
37 | }
38 |
39 |
40 |
41 |
42 | /**
43 | * exports
44 | */
45 | module.exports =
46 | {
47 | formatDateTime : formatDateTime,
48 | formatDate : formatDate,
49 | formatTime : formatTime,
50 | getCurrentTimestamp : getCurrentTimestamp
51 | };
--------------------------------------------------------------------------------
/src/models/secret/CSignature.js:
--------------------------------------------------------------------------------
1 | var wlib = require( '../../libs/wlib.js' );
2 | var wdatetime = require( '../../libs/wdatetime.js' );
3 | var wsha256 = require( '../../libs/cipher/wsha256.js' );
4 |
5 |
6 |
7 |
8 | /**
9 | * CSignature
10 | */
11 | class CSignature
12 | {
13 | constructor()
14 | {
15 | }
16 |
17 |
18 | /**
19 | * @ public
20 | *
21 | * @param array arrSourceList
22 | * @return string signature string
23 | */
24 | createSignature( arrSourceList )
25 | {
26 | var sRet;
27 | let i;
28 | let sSource;
29 |
30 | if ( ! wlib.isArray( arrSourceList ) || 0 == arrSourceList.length )
31 | {
32 | return null;
33 | }
34 |
35 | // ...
36 | sRet = null;
37 | sSource = '';
38 |
39 | for ( i = 0; i < arrSourceList.length; i ++ )
40 | {
41 | sSource += '..........,..........';
42 | sSource += new String( arrSourceList[ i ] );
43 | sSource += '..........,..........';
44 | }
45 |
46 | // ...
47 | return wsha256.hex( sSource );
48 | }
49 |
50 | }
51 |
52 |
53 |
54 |
55 | /**
56 | * exports
57 | */
58 | module.exports =
59 | {
60 | CSignature : CSignature
61 | };
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 DeKuan, Inc.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/design/references/envelope-icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
--------------------------------------------------------------------------------
/src/app.js:
--------------------------------------------------------------------------------
1 | //app.js
2 | App({
3 | onLaunch: function () {
4 | // // 展示本地存储能力
5 | // var logs = wx.getStorageSync('logs') || []
6 | // logs.unshift(Date.now())
7 | // wx.setStorageSync('logs', logs)
8 |
9 | // // 登录
10 | // wx.login({
11 | // success: res => {
12 | // // 发送 res.code 到后台换取 openId, sessionKey, unionId
13 | // }
14 | // })
15 | // // 获取用户信息
16 | // wx.getSetting({
17 | // success: res => {
18 | // if (res.authSetting['scope.userInfo']) {
19 | // // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框
20 | // wx.getUserInfo({
21 | // success: res => {
22 | // // 可以将 res 发送给后台解码出 unionId
23 | // this.globalData.userInfo = res.userInfo
24 |
25 | // // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
26 | // // 所以此处加入 callback 以防止这种情况
27 | // if (this.userInfoReadyCallback) {
28 | // this.userInfoReadyCallback(res)
29 | // }
30 | // }
31 | // })
32 | // }
33 | // }
34 | // })
35 |
36 |
37 | },
38 | globalData: {
39 | userInfo: null
40 | }
41 | })
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | package-lock.json
2 | .DS_Store
3 | .idea
4 |
5 |
6 |
7 | # Logs
8 | logs
9 | *.log
10 | npm-debug.log*
11 | yarn-debug.log*
12 | yarn-error.log*
13 |
14 | # Runtime data
15 | pids
16 | *.pid
17 | *.seed
18 | *.pid.lock
19 |
20 | # Directory for instrumented libs generated by jscoverage/JSCover
21 | lib-cov
22 |
23 | # Coverage directory used by tools like istanbul
24 | coverage
25 |
26 | # nyc test coverage
27 | .nyc_output
28 |
29 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
30 | .grunt
31 |
32 | # Bower dependency directory (https://bower.io/)
33 | bower_components
34 |
35 | # node-waf configuration
36 | .lock-wscript
37 |
38 | # Compiled binary addons (http://nodejs.org/api/addons.html)
39 | build/Release
40 |
41 | # Dependency directories
42 | node_modules/
43 | jspm_packages/
44 |
45 | # Typescript v1 declaration files
46 | typings/
47 |
48 | # Optional npm cache directory
49 | .npm
50 |
51 | # Optional eslint cache
52 | .eslintcache
53 |
54 | # Optional REPL history
55 | .node_repl_history
56 |
57 | # Output of 'npm pack'
58 | *.tgz
59 |
60 | # Yarn Integrity file
61 | .yarn-integrity
62 |
63 | # dotenv environment variables file
64 | .env
65 |
66 |
--------------------------------------------------------------------------------
/src/pages/about/about.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | 采用美国军方和美国联盟政府推荐使用的 AES 256bits 超强加密算法,确保了「加密纸条」非常安全。
19 |
20 |
21 |
22 |
23 | 每一个纸条只在本地进行强加密,然后,直接发送给微信好友。整个通讯过程不经过任何服务器中转,保证了「加密纸条」非常安全。
24 |
25 |
26 |
27 |
28 |
29 |
30 | 花了一天时间看了小程序文档,发现构架师设计得很棒,对小程序产生了浓厚兴趣,于是继续花了几天时间,便完成了这个小程序。
31 |
32 |
33 |
34 |
35 | 刘其星,曾就职于 360 公司,对网络安全有浓厚的兴趣与多年的实战工作经验。有兴趣的朋友可以加我微信 18811070903 批评指正。
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/src/pages/index/index.wxss:
--------------------------------------------------------------------------------
1 | /**
2 | * top info
3 | */
4 | .topinfo
5 | {
6 | display: flex;
7 | flex-direction: column;
8 | align-items: center;
9 | background-color: #273b7a;
10 | padding: 30rpx 0 60rpx 0;
11 | }
12 | .topinfo .topinfo-line
13 | {
14 | padding: 5rpx 0 5rpx 0;
15 | }
16 | .topinfo .topinfo-line-text
17 | {
18 | font-size: 38rpx;
19 | font-weight: normal;
20 | color: #DDDDDD;
21 | }
22 |
23 |
24 |
25 |
26 | /**
27 | * product
28 | */
29 | .product
30 | {
31 | display: flex;
32 | flex-direction: column;
33 | align-items: center;
34 | padding: 80rpx 0 0 0;
35 | }
36 | .product .logo
37 | {
38 | width: 260rpx;
39 | height: 260rpx;
40 | background-size: contain;
41 | }
42 | .product .link-view
43 | {
44 | padding: 10rpx 0 0 0;
45 | }
46 | .product .link-view .link-view-button
47 | {
48 | background-color: #FFFFFF;
49 | font-size: 34rpx;
50 | font-weight: normal;
51 | color: #273b7a;
52 | text-decoration: underline;
53 | cursor: pointer;
54 | }
55 |
56 |
57 |
58 |
59 | /**
60 | * main
61 | */
62 | .main
63 | {
64 | display: flex;
65 | flex-direction: column;
66 | align-items: center;
67 | padding: 140rpx 0 0 0;
68 | }
69 | .main .link-view
70 | {
71 | }
72 | .main .link-view .link-view-button
73 | {
74 | background-color: #FFFFFF;
75 | font-size: 50rpx;
76 | font-weight: normal;
77 | color: #273b7a;
78 | text-decoration: underline;
79 | }
--------------------------------------------------------------------------------
/src/components/happyLoading/happyLoading.wxss:
--------------------------------------------------------------------------------
1 | /**
2 | * components/top-toast/top-toast.wxss
3 | */
4 | .center-block
5 | {
6 | display: block;
7 | margin-right: auto;
8 | margin-left: auto;
9 |
10 | position: fixed;
11 | z-index: 5000;
12 | width: 260rpx;
13 | height: 260rpx;
14 | top: 35%;
15 | left: 50%;
16 | margin-left: -130rpx;
17 | text-align: center;
18 | }
19 |
20 |
21 |
22 |
23 | /**
24 | * top-toast
25 | */
26 | .de-loading
27 | {
28 | margin: 0;
29 | width: 260rpx;
30 | height: 260rpx;
31 | display: inline-block;
32 | vertical-align: middle;
33 | -webkit-animation: a 1s steps(36) infinite;
34 | animation: a 1s steps(36) infinite;
35 | background-repeat: no-repeat;
36 | background-size: 100%;
37 |
38 | border-radius: 130rpx;
39 | -webkit-box-shadow:0 0 100rpx rgba( 81, 124, 212, .8 );
40 | -moz-box-shadow:0 0 100rpx rgba( 81, 124, 212, .8 );
41 | box-shadow:0 0 100rpx rgba( 81, 124, 212, .8 );
42 | }
43 | .de-loading.de-loading_transparent
44 | {
45 | }
46 | @-webkit-keyframes a
47 | {
48 | 0% {
49 | -webkit-transform:rotate(0deg);
50 | transform:rotate(0deg);
51 | }
52 | to {
53 | -webkit-transform:rotate(1turn);
54 | transform:rotate(1turn);
55 | }
56 | }
57 | @keyframes a
58 | {
59 | 0% {
60 | -webkit-transform:rotate(0deg);
61 | transform:rotate(0deg);
62 | }
63 | to {
64 | -webkit-transform:rotate(1turn);
65 | transform:rotate(1turn);
66 | }
67 | }
--------------------------------------------------------------------------------
/src/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "pages":
3 | [
4 | "pages/index/index",
5 | "pages/create/create",
6 | "pages/done/done",
7 | "pages/open/open",
8 | "pages/about/about"
9 | ],
10 | "window":
11 | {
12 | "navigationBarBackgroundColor" : "#273b7a",
13 | "navigationBarTitleText" : "加密纸条",
14 | "navigationBarTextStyle" : "white",
15 | "backgroundColor" : "#fff",
16 | "backgroundTextStyle" : "light",
17 | "enablePullDownRefresh" : false
18 | },
19 | "networkTimeout":
20 | {
21 | "request" : 60000,
22 | "uploadFile" : 60000,
23 | "downloadFile" : 60000,
24 | "connectSocket" : 60000
25 | },
26 | "tabBar":
27 | {
28 | "color" : "#F8F8F8",
29 | "selectedColor" : "#FFF",
30 | "backgroundColor" : "#273b7a",
31 | "borderStyle" : "white",
32 | "position" : "bottom",
33 | "list":
34 | [
35 | {
36 | "pagePath": "pages/index/index",
37 | "text": "发送",
38 | "iconPath":"resources/icons/icon_send_81x81.png",
39 | "selectedIconPath": "resources/icons/icon_send_sel_81x81.png"
40 | },
41 | {
42 | "pagePath": "pages/open/open",
43 | "text": "接收",
44 | "iconPath": "resources/icons/icon_receive_81x81.png",
45 | "selectedIconPath": "resources/icons/icon_receive_sel_81x81.png"
46 | },
47 | {
48 | "pagePath": "pages/about/about",
49 | "text": "关于",
50 | "iconPath": "resources/icons/icon_about_81x81.png",
51 | "selectedIconPath": "resources/icons/icon_about_sel_81x81.png"
52 | }
53 | ]
54 | }
55 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 加密纸条
2 |
3 | 
4 |
5 |
6 | ### 超强加密
7 |
8 | 采用美国军方和美国联盟政府推荐使用的 AES 256bits 超强加密算法,确保了「加密纸条」非常安全。
9 |
10 |
11 | ### 开放源码
12 |
13 | 为了《加密纸条》更具公信力,让更多有兴趣的朋友参与进来开发,《加密纸条》彻底开放源码。
14 |
15 |
16 |
17 | ### 端对端通讯,无服务器转发
18 |
19 | 每一个纸条只在本地进行强加密,然后,直接发送给微信好友。整个通讯过程不经过任何服务器中转,保证了「加密纸条」非常安全。
20 |
21 |
22 |
23 | ### 关于软件
24 |
25 | 花了一天时间看了小程序文档,发现构架师设计得很棒,对小程序产生了浓厚兴趣,于是继续花了几天时间,便完成了这个小程序。
26 |
27 |
28 |
29 | ### 关于作者
30 | 刘其星,曾就职于 360 公司,对网络安全有浓厚的兴趣与多年的实战工作经验。有兴趣的朋友可以加我微信 18811070903 批评指正。
31 |
32 |
33 | ### 开始使用
34 |
35 | 
36 |
37 |
38 | ### 软件截图
39 |
40 | 
41 |
42 | 
43 |
44 | 
45 |
46 | 
47 |
48 | 
49 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/src/libs/wchar.js:
--------------------------------------------------------------------------------
1 | var wlib = require('wlib.js');
2 |
3 |
4 | /**
5 | * check if the given string sString is a valid Chinese characters
6 | */
7 | function isChineseChars( sString )
8 | {
9 | let rePattern;
10 | let sNewString;
11 |
12 | if ( 0 === wlib.getStrLen( sString ) )
13 | {
14 | return false;
15 | }
16 |
17 | //
18 | // /[\u4E00-\u9FA5\uF900-\uFA2D]/
19 | // 说明: u4e00 - u9fbf : unicode CJK(中日韩)统一表意字符。u9fa5后至u9fbf为空
20 | // uF900 - uFAFF : 为unicode CJK 兼容象形文字 。uFA2D后至uFAFF为空
21 | // 具体可参考unicode编码表:http://www.nengcha.com/code/unicode/class/
22 | //
23 |
24 | // \w 匹配 [0-9a-zA-Z_]
25 | // " -~" 匹配所有可见的英文字符
26 | // \uFF00-\uFFEF 部分中文全角符号
27 |
28 | // 下面是部分特殊的中文全角
29 | //
30 | // ¥ \xA5
31 | // … \u2026
32 | // — \u2014
33 | // · \xB7
34 | //
35 | // 【 \u3010
36 | // 】 \u3011
37 | // 、 \u3001
38 | // ; \uFF1B
39 | // ‘ \u2018
40 | // , \uFF0C
41 | // 。 \u3002
42 | // / \x2F
43 | // 「 \u300C
44 | // 」 \u300D
45 | // | \x7C
46 | // : \uFF1A
47 | // “ \u201C
48 | // ” \u201D
49 | // 《 \u300A
50 | // 》 \u300B
51 | // ? \uFF1F
52 | // ...
53 | rePattern = /^[\u4E00-\u9FA5\uF900-\uFA2D\uFF00-\uFFEF\w -~\xA5\xB7\u2026\u2014\u3010\u3011\u3001\uFF1B\u2018\uFF0C\u3002\x2F\u300C\u300D\x7C\uFF1A\u201C\u201D\u300A\u300B\uFF1F]*$/mg;
54 | sNewString = ( new String( sString ) ).replace( /\r?\n/g, "" );
55 |
56 | return rePattern.test( sNewString );
57 | }
58 |
59 |
60 | /**
61 | * exports
62 | */
63 | module.exports =
64 | {
65 | isChineseChars : isChineseChars
66 | }
--------------------------------------------------------------------------------
/src/pages/open/open.wxss:
--------------------------------------------------------------------------------
1 | /**
2 | * envelope
3 | */
4 | .envelope
5 | {
6 | display: flex;
7 | flex-direction: column;
8 | align-items: center;
9 | padding: 90rpx 0 90rpx 0;
10 | background-color: #273b7a;
11 | }
12 | .envelope .envelope-icon
13 | {
14 | width: 420rpx;
15 | height: 320rpx;
16 | background-size: 420rpx 320rpx;
17 | }
18 | .envelope .envelope-empty
19 | {
20 | width: 420rpx;
21 | height: 336rpx;
22 | color: #fff;
23 | line-height: 320rpx;
24 | text-align: center;
25 | }
26 |
27 |
28 | /**
29 | * main
30 | */
31 | .main
32 | {
33 | padding: 20rpx 0 60rpx 0;
34 | }
35 | .main .main-body
36 | {
37 | padding: 0 40rpx 0 40rpx;
38 | }
39 | .main .main-section
40 | {
41 | padding: 20rpx 0 10rpx 0;
42 | }
43 | .main .main-label
44 | {
45 | color: #273b7a;
46 | font-weight: bold;
47 | padding: 10rpx 0 10rpx 0;
48 | }
49 | .main .main-text
50 | {
51 | color: #273b7a;
52 | font-weight: normal;
53 | padding: 10rpx 0 10rpx 0;
54 | }
55 | .main .main-empty
56 | {
57 | color: #273b7a;
58 | }
59 |
60 | .main .decrypt-area
61 | {
62 | width: 100%;
63 | display: inline-flex;
64 | flex-direction: row;
65 | }
66 | .main .decrypt-area .decrypt-input-area
67 | {
68 | flex: 1;
69 | }
70 | .main .decrypt-area .decrypt-space-area
71 | {
72 | flex: 0 0 10rpx;
73 | }
74 | .main .decrypt-area .decrypt-button-area
75 | {
76 | flex: 0 0 140rpx;
77 | padding: 20rpx 0 0 0;
78 | }
79 | .main .decrypt-area .decrypt-input-area .decrypt-input-item
80 | {
81 | height: 90rpx;
82 | border-bottom: 2px solid #273b7a;
83 | }
84 | .main .decrypt-area .decrypt-input-area .decrypt-input-item-placeholder
85 | {
86 | color: #505b80;
87 | }
88 | .main .decrypt-area .decrypt-button-area .decrypt-button-item
89 | {
90 | width: 140rpx;
91 | height: 80rpx;
92 | color: #fff;
93 | font-size: 32rpx;
94 | background-color: #273b7a;
95 | }
--------------------------------------------------------------------------------
/src/components/topToast/topToast.js:
--------------------------------------------------------------------------------
1 | // components/top-toast/top-toast.js
2 | Component
3 | ({
4 | /**
5 | * 组件的属性列表
6 | */
7 | properties:
8 | {
9 | show:
10 | {
11 | type: Boolean,
12 | value: false
13 | },
14 | mode:
15 | {
16 | type: String,
17 | value: "err"
18 | },
19 | delay:
20 | {
21 | type : Number,
22 | value : 3000
23 | },
24 |
25 | // 显示的消息
26 | message :
27 | {
28 | // 类型(必填),目前接受的类型包括:String, Number, Boolean, Object, Array, null(表示任意类型)
29 | type : String,
30 |
31 | // 属性初始值(可选),如果未指定则会根据类型选择一个
32 | value : "消息内容"
33 | },
34 | },
35 |
36 | /**
37 | * 组件的初始数据/内部数据
38 | */
39 | data:
40 | {
41 | m_nInterval : null
42 | },
43 |
44 | /**
45 | * 组件的方法列表
46 | */
47 | methods:
48 | {
49 | // 展示弹框
50 | showTopToast( sMode, sMessage )
51 | {
52 | this.setData
53 | ({
54 | message : sMessage,
55 | mode: sMode,
56 | show: true
57 | });
58 | this._createInterval();
59 | },
60 |
61 | // 隐藏弹框
62 | hideTopToast()
63 | {
64 | this.setData
65 | ({
66 | show: false
67 | });
68 | },
69 |
70 | /*
71 | * 内部私有方法
72 | * triggerEvent 用于触发事件
73 | */
74 | _cancelEvent()
75 | {
76 | // 触发取消回调
77 | this.triggerEvent( "cancelEvent" )
78 | },
79 |
80 | /**
81 | * @ private
82 | */
83 | _createInterval()
84 | {
85 | if ( null !== this.data.m_nInterval )
86 | {
87 | clearTimeout( this.data.m_nInterval );
88 | this.data.m_nInterval = null;
89 | }
90 |
91 | // ...
92 | setTimeout( () =>
93 | {
94 | this.hideTopToast();
95 | },
96 | this.properties.delay > 0 ? this.properties.delay : 3000
97 | );
98 | }
99 |
100 |
101 |
102 | }
103 |
104 |
105 |
106 | })
--------------------------------------------------------------------------------
/src/pages/done/done.js:
--------------------------------------------------------------------------------
1 | //
2 | // index.js
3 | // 获取应用实例
4 | //
5 | var wurl = require( '../../libs/wurl.js' );
6 | var wlib = require( '../../libs/wlib.js' );
7 | var mhint = require( '../../models/secret/CEncryptHint.js' );
8 |
9 | const app = getApp();
10 |
11 | var m_oTopToast = null;
12 |
13 |
14 |
15 | Page({
16 |
17 | data:
18 | {
19 | sPasswordHint : ''
20 | },
21 |
22 | onReady: function()
23 | {
24 | // 获得 dialog组件
25 | m_oTopToast = this.selectComponent("#id-top-toast");
26 |
27 | // ...
28 | this._initPage();
29 | },
30 |
31 | onLoad: function( oOptions )
32 | {
33 | console.log( "DONE / wurl.getCurrentPageArgs() = ", wurl.getCurrentPageArgs() );
34 | },
35 |
36 |
37 | onTopToastCancel: function ( oEvent )
38 | {
39 | console.log( "onTopToastCancel", oEvent );
40 | m_oTopToast.hideTopToast();
41 | },
42 | onShareAppMessage: function( oArgs )
43 | {
44 | var oPageArgs;
45 | var sShareUrl;
46 |
47 | if ( 'button' === oArgs.from )
48 | {
49 | // 来自页面内转发按钮
50 | console.log( oArgs.target );
51 | }
52 |
53 | // ...
54 | oPageArgs = wurl.getCurrentPageArgs();
55 |
56 | if ( ! wlib.isObjectWithKeys( oPageArgs, [ 'v', 'i', 'm', 's', 'h', 'ts', 'te', '_' ] ) )
57 | {
58 | m_oTopToast.showTopToast( 'err', '参数错误,无法发送给朋友,请联系软件作者' );
59 | return false;
60 | }
61 |
62 | // ...
63 | sShareUrl = "/pages/open/open?" + wurl.serializeArgs( oPageArgs );
64 |
65 | return {
66 | title: '收到一张「加密纸条」',
67 | path: sShareUrl,
68 | success: function( oRes )
69 | {
70 | console.log( "转发成功", oRes );
71 | },
72 | fail: function( oRes )
73 | {
74 | console.log( "转发失败", oRes );
75 | }
76 | };
77 | },
78 |
79 |
80 | /**
81 | * initalize page
82 | */
83 | _initPage : function()
84 | {
85 | var oMHint;
86 | var oPageArgs;
87 |
88 |
89 | // ...
90 | oMHint = new mhint.CEncryptHint();
91 | oPageArgs = wurl.getCurrentPageArgs();
92 |
93 | if ( wlib.isObjectWithKeys( oPageArgs, 'h' ) )
94 | {
95 | this.setData({
96 | sPasswordHint: oMHint.decryptSecret( oPageArgs.h )
97 | });
98 | }
99 | else
100 | {
101 | m_oTopToast.showTopToast( 'err', '没有发现解密提示文字');
102 | }
103 |
104 | }
105 |
106 | })
--------------------------------------------------------------------------------
/src/pages/open/open.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
9 |
10 |
11 |
12 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
24 |
25 |
26 | 没有消息
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
60 |
61 |
62 | 收到一张「加密纸条」,解密提示:
63 | {{ sPasswordHint }}
64 |
65 |
66 |
67 |
68 |
69 |
70 | 这张「加密纸条」的内容是:
71 | {{ sMessage }}
72 |
73 |
74 |
75 |
76 |
77 |
78 | 感谢使用 AES 256bits 端对端超强加密的「加密纸条」,相信你偶尔还是会用到的!
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/src/libs/wlib.js:
--------------------------------------------------------------------------------
1 | function isNumeric( oObj )
2 | {
3 | return ( ! isNaN( oObj ) && "[object Number]" === Object.prototype.toString.call( oObj ) );
4 | }
5 |
6 | function isString( oObj )
7 | {
8 | return ( "[object String]" === Object.prototype.toString.call( oObj ) );
9 | }
10 |
11 | function isBool( oObj )
12 | {
13 | return ( "[object Boolean]" === Object.prototype.toString.call( oObj ) );
14 | }
15 |
16 | function isArray( oObj )
17 | {
18 | return ( "[object Array]" === Object.prototype.toString.call( oObj ) ||
19 | "[object Uint8Array]" === Object.prototype.toString.call( oObj ) );
20 | }
21 |
22 | function isObject( oObj )
23 | {
24 | return ( "[object Object]" === Object.prototype.toString.call( oObj ) ||
25 | "[object Blob]" === Object.prototype.toString.call( oObj ) );
26 | }
27 |
28 | function isFunction( oObj )
29 | {
30 | return ( "[object Function]" === Object.prototype.toString.call( oObj ) );
31 | }
32 |
33 | function isValidDateObject( oObj )
34 | {
35 | // d.valueOf() could also work
36 | return ( "[object Date]" === Object.prototype.toString.call( oObj ) && ( ! isNaN( oObj.getTime() ) ) );
37 | }
38 |
39 | function isObjectWithKeys( oObj, vKey )
40 | {
41 | var bRet;
42 | var vKeyKey;
43 |
44 | // ...
45 | bRet = false;
46 |
47 | if ( isObject( oObj ) )
48 | {
49 | if ( isArray( vKey ) )
50 | {
51 | bRet = true;
52 | for ( vKeyKey in vKey )
53 | {
54 | if ( ! oObj.hasOwnProperty( vKey[ vKeyKey ] ) )
55 | {
56 | bRet = false;
57 | break;
58 | }
59 | }
60 | }
61 | else if ( isString( vKey ) || isNumeric( vKey ) )
62 | {
63 | bRet = oObj.hasOwnProperty( vKey );
64 | }
65 | else if ( undefined === vKey )
66 | {
67 | bRet = true;
68 | }
69 | }
70 |
71 | return bRet;
72 | }
73 |
74 | function trimStr( sString )
75 | {
76 | if ( ! isString( sString ) )
77 | {
78 | return '';
79 | }
80 |
81 | //
82 | // Polyfill
83 | //
84 | if ( ! String.prototype.trim )
85 | {
86 | String.prototype.trim = function()
87 | {
88 | return this.replace( /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '' );
89 | };
90 | }
91 |
92 | return ( new String( sString ) ).trim();
93 | }
94 |
95 | function getStrLen( sString, bTrim )
96 | {
97 | var nRet;
98 | var sNewString;
99 |
100 | if ( ! isString( sString ) && ! isNumeric( sString ) )
101 | {
102 | return 0;
103 | }
104 |
105 | // ...
106 | nRet = 0;
107 | sNewString = new String( sString );
108 |
109 | if ( isBool( bTrim ) && bTrim )
110 | {
111 | nRet = trimStr( sNewString ).length;
112 | }
113 | else
114 | {
115 | nRet = sNewString.length;
116 | }
117 |
118 | return nRet;
119 | }
120 |
121 | function getRandomNumber( nLowerValue, nUpperValue )
122 | {
123 | return Math.floor( Math.random() * ( nUpperValue - nLowerValue + 1 ) + nLowerValue );
124 | }
125 |
126 |
127 |
128 |
129 | /**
130 | * exports
131 | */
132 | module.exports =
133 | {
134 | isNumeric: isNumeric,
135 | isString: isString,
136 | isBool: isBool,
137 | isArray: isArray,
138 | isObject: isObject,
139 | isFunction: isFunction,
140 | isValidDateObject: isValidDateObject,
141 | isObjectWithKeys: isObjectWithKeys,
142 | trimStr: trimStr,
143 | getStrLen: getStrLen,
144 | getRandomNumber: getRandomNumber
145 | }
--------------------------------------------------------------------------------
/src/libs/wurl.js:
--------------------------------------------------------------------------------
1 | var wlib = require( 'wlib.js' );
2 |
3 |
4 |
5 | /**
6 | * get page url of current page
7 | */
8 | function getCurrentPageUrl()
9 | {
10 | var sRet;
11 | var arrPages;
12 | var oCurrentPage;
13 |
14 | // ...
15 | sRet = '';
16 |
17 | //
18 | // get stack array of current pages
19 | //
20 | arrPages = getCurrentPages();
21 | if ( wlib.isArray( arrPages ) &&
22 | arrPages.length > 0 )
23 | {
24 | //
25 | // get the object of current page
26 | //
27 | oCurrentPage = arrPages[ arrPages.length - 1 ];
28 | if ( wlib.isObjectWithKeys( oCurrentPage, [ 'route' ] ) )
29 | {
30 | // url of current page
31 | sRet = oCurrentPage.route;
32 | }
33 | }
34 |
35 | return sRet;
36 | }
37 |
38 |
39 | /**
40 | * get all arguments as an object from current page
41 | */
42 | function getCurrentPageArgs()
43 | {
44 | var oRet;
45 | var arrPages;
46 | var oCurrentPage;
47 | var oOptions;
48 |
49 | // ...
50 | oRet = null;
51 |
52 | //
53 | // get stack array of current pages
54 | //
55 | arrPages = getCurrentPages();
56 | if ( wlib.isArray( arrPages ) && arrPages.length > 0 )
57 | {
58 | //
59 | // get the object of current page
60 | //
61 | oCurrentPage = arrPages[ arrPages.length - 1 ];
62 | if ( wlib.isObjectWithKeys(oCurrentPage, [ 'options' ] ) )
63 | {
64 | // all arguments with url
65 | oOptions = oCurrentPage.options;
66 | if ( wlib.isObject( oOptions ) )
67 | {
68 | // yes, there are arguments with the url
69 | oRet = oOptions;
70 | }
71 | }
72 | }
73 |
74 | return oRet;
75 | }
76 |
77 |
78 | /**
79 | * get current page url and its arguments
80 | */
81 | function getCurrentPageUrlWithArgs()
82 | {
83 | var sRet;
84 | var sUrl;
85 | var oOptions;
86 | var sKey;
87 | var sValue;
88 |
89 | // ...
90 | sRet = '';
91 |
92 | // ...
93 | sUrl = getCurrentPageUrl();
94 | oOptions = getCurrentPageArgs();
95 |
96 | if ( wlib.getStrLen( sUrl ) > 0 )
97 | {
98 | // ...
99 | sRet = sUrl;
100 |
101 | if ( wlib.isObject( oOptions ) )
102 | {
103 | // yes, there are arguments with the url
104 | // now we append them to the end of url
105 | sRet += '?';
106 |
107 | for ( sKey in oOptions )
108 | {
109 | sValue = new String( oOptions[ sKey ] );
110 | sRet += ( sKey + '=' + sValue + '&' );
111 | }
112 |
113 | sRet = sRet.substring( 0, sRet.length - 1 );
114 | }
115 | }
116 |
117 | return sRet
118 | }
119 |
120 | /**
121 | * serialize args to query-string
122 | */
123 | function serializeArgs( oArgs )
124 | {
125 | var arrNamedArgs;
126 | var sKey;
127 |
128 | if ( ! wlib.isObjectWithKeys( oArgs ) )
129 | {
130 | return null;
131 | }
132 |
133 | // ...
134 | arrNamedArgs = [];
135 |
136 | for ( sKey in oArgs )
137 | {
138 | if ( oArgs.hasOwnProperty( sKey ) )
139 | {
140 | arrNamedArgs.push
141 | (
142 | encodeURIComponent( sKey ) + "=" + encodeURIComponent( oArgs[ sKey ] )
143 | );
144 | }
145 | }
146 |
147 | return arrNamedArgs.join( "&" );
148 | }
149 |
150 |
151 |
152 | /**
153 | * exports
154 | */
155 | module.exports =
156 | {
157 | getCurrentPageUrl : getCurrentPageUrl,
158 | getCurrentPageArgs : getCurrentPageArgs,
159 | getCurrentPageUrlWithArgs : getCurrentPageUrlWithArgs,
160 | serializeArgs : serializeArgs
161 | }
--------------------------------------------------------------------------------
/src/pages/create/create.wxss:
--------------------------------------------------------------------------------
1 | /**
2 | * main and form
3 | */
4 | .main
5 | {
6 | padding: 20rpx 0 0 0;
7 | }
8 | .main .main-form
9 | {
10 | margin: 0;
11 | }
12 | .main .main-form .main-form-section
13 | {
14 | display: flex;
15 | flex-direction: column;
16 | flex-wrap: nowrap;
17 | justify-content: flex-start;
18 |
19 | padding: 20rpx 30rpx 10rpx 30rpx;
20 | }
21 |
22 | .main .main-form .main-form-label
23 | {
24 | flex: 1;
25 |
26 | color: #273b7a;
27 | font-weight: bold;
28 | padding: 10rpx 20rpx 10rpx 0;
29 | }
30 | .main .main-form .main-form-content
31 | {
32 | position: relative;
33 | }
34 |
35 | .main .main-form .main-form-textarea
36 | {
37 | width: 100%;
38 | height: 120rpx;
39 | padding-bottom: 10rpx;
40 | border-bottom: 2px solid #273b7a;
41 | }
42 | .main .main-form .main-form-textarea-placeholder
43 | {
44 | color: #505b80;
45 | }
46 |
47 | .main .main-form .main-form-input
48 | {
49 | height: 90rpx;
50 | border-bottom: 2px solid #273b7a;
51 | }
52 | .main .main-form .main-form-input-placeholder
53 | {
54 | color: #505b80;
55 | }
56 |
57 |
58 | /**
59 | * password hint
60 | */
61 | .main .main-form .main-form-content .password-hint-input
62 | {
63 | margin-right: 100rpx;
64 | }
65 | .main .main-form .main-form-content .password-hint-button
66 | {
67 | position: absolute;
68 | width: 76rpx;
69 | height: 76rpx;
70 | top: 10rpx;
71 | right: 0rpx;
72 | font-size: 60rpx;
73 | line-height: 38rpx;
74 | color: #273b7a;
75 | border-width: 0;
76 | border: 2px solid #273b7a;
77 | border-radius: 16rpx;
78 | text-align: center;
79 | }
80 |
81 |
82 |
83 | /**
84 | * password hint list
85 | */
86 | .top-view
87 | {
88 | position: fixed;
89 | width: 100%;
90 | height: 100%;
91 | top: 0;
92 | left: 0;
93 |
94 | display: flex;
95 | flex-direction:row;
96 |
97 | z-index: 5000;
98 | background-color: rgba( 0, 0, 0, 0.2 );
99 | }
100 | .top-view .space-left
101 | {
102 | flex: 0 0 30rpx;
103 | }
104 | .top-view .space-right
105 | {
106 | flex: 0 0 30rpx;
107 | }
108 | .top-view .password-hint
109 | {
110 | flex: 1;
111 |
112 | margin: 30rpx 0 30rpx 0;
113 |
114 | border: 2px solid #273b7a;
115 | border-radius: 10rpx;
116 | background-color: #fff;
117 | }
118 | .top-view .password-hint .password-hint-wrap
119 | {
120 | display: flex;
121 | flex-direction:column;
122 | flex-wrap: nowrap;
123 | justify-content: flex-start;
124 |
125 | width: 100%;
126 | height: 100%;
127 | }
128 | .top-view .password-hint .password-hint-wrap .password-hint-wrap-title
129 | {
130 | height: 120rpx;
131 | color: #273b7a;
132 | font-weight: bold;
133 | text-align: center;
134 | line-height: 120rpx;
135 | }
136 | .top-view .password-hint .password-hint-wrap .password-hint-wrap-list
137 | {
138 | flex: 1;
139 | height: 100%;
140 | overflow-y: auto;
141 |
142 | padding: 0rpx 10rpx 20rpx 40rpx;
143 | }
144 | .top-view .password-hint .password-hint-wrap .password-hint-wrap-list .password-hint-wrap-list-item
145 | {
146 | color: #273b7a;
147 | padding: 0 0 30rpx 0;
148 | }
149 | .top-view .password-hint .password-hint-wrap .password-hint-wrap-button
150 | {
151 | flex: 0 0 120rpx;
152 | padding: 10rpx 0 20rpx 0;
153 | }
154 | .top-view .password-hint .password-hint-wrap .password-hint-wrap-button .password-hint-wrap-button-close
155 | {
156 | width: 90%;
157 | color: #fff;
158 | background-color: #273b7a;
159 | }
--------------------------------------------------------------------------------
/src/pages/create/create.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
78 |
79 |
80 |
81 |
85 |
86 |
91 |
92 |
93 |
94 | 预置解密提示文字
95 |
96 |
97 |
99 | ☖ {{ item }}
106 |
107 |
108 |
109 |
110 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
--------------------------------------------------------------------------------
/design/references/secret.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
74 |
--------------------------------------------------------------------------------
/src/resources/images/icon_secret_round.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
74 |
--------------------------------------------------------------------------------
/src/models/secret/CEncryptHint.js:
--------------------------------------------------------------------------------
1 | var wlib = require( '../../libs/wlib.js' );
2 | var wdatetime = require( '../../libs/wdatetime.js' );
3 | var waes = require( '../../libs/cipher/waes.js' );
4 | var wsha256 = require( '../../libs/cipher/wsha256.js' );
5 |
6 |
7 |
8 |
9 | /**
10 | * CEncryptHint
11 | */
12 | class CEncryptHint
13 | {
14 | // version
15 | m_nVersion = 1;
16 | m_arrVersionList = { 1 : 1 };
17 |
18 |
19 | constructor( nVersion )
20 | {
21 | this._initVersion( nVersion );
22 | }
23 |
24 | /**
25 | * @ public
26 | *
27 | * @param string sHint
28 | * @return string encrypted hex string
29 | */
30 | encryptHint( sHint )
31 | {
32 | var sRet;
33 | let arrKey;
34 | let arrHintBytes;
35 | let oAesCtrMode;
36 | let arrEncryptedBytes;
37 | let sEncryptedHex;
38 |
39 | // ...
40 | sRet = null;
41 | arrKey = this._createKey();
42 | if ( wlib.isArray( arrKey ) && 32 === arrKey.length )
43 | {
44 | // Convert sMessage to bytes
45 | arrHintBytes = waes.utils.utf8.toBytes( sHint );
46 | if ( wlib.isArray( arrHintBytes ) )
47 | {
48 | // The counter is optional, and if omitted will begin at 1
49 | oAesCtrMode = new waes.ModeOfOperation.ctr( arrKey, new waes.Counter( 1 ) );
50 | arrEncryptedBytes = oAesCtrMode.encrypt(arrHintBytes );
51 | if ( wlib.isArray( arrEncryptedBytes ) )
52 | {
53 | // To print or store the binary data, you may convert arrEncryptedBytes to hex
54 | sEncryptedHex = waes.utils.hex.fromBytes( arrEncryptedBytes );
55 | if ( wlib.getStrLen( sEncryptedHex ) > 0 )
56 | {
57 | // ...
58 | sRet = sEncryptedHex;
59 | }
60 | }
61 | }
62 | }
63 |
64 | return sRet;
65 | }
66 |
67 |
68 | /**
69 | * @ public
70 | *
71 | * @param string sEncryptedHex
72 | * @return string decrypted message
73 | */
74 | decryptSecret( sEncryptedHex )
75 | {
76 | var sRet;
77 | let arrKey;
78 | let oAesCtrMode;
79 | let arrEncryptedBytes;
80 | let arrDecryptedBytes;
81 | let sDecryptedText;
82 |
83 | if ( 0 === wlib.getStrLen( sEncryptedHex ) )
84 | {
85 | return null;
86 | }
87 |
88 | // ...
89 | sRet = null;
90 | arrKey = this._createKey();
91 | if ( wlib.isArray( arrKey ) && 32 === arrKey.length )
92 | {
93 | // When ready to decrypt the hex string, convert it back to bytes
94 | arrEncryptedBytes = waes.utils.hex.toBytes( sEncryptedHex );
95 | if ( wlib.isArray( arrEncryptedBytes ) )
96 | {
97 | //
98 | // The counter mode of operation maintains internal state, so to
99 | // decrypt a new instance must be instantiated.
100 | //
101 | oAesCtrMode = new waes.ModeOfOperation.ctr( arrKey, new waes.Counter( 1 ) );
102 | arrDecryptedBytes = oAesCtrMode.decrypt( arrEncryptedBytes );
103 | if ( wlib.isArray( arrDecryptedBytes ) )
104 | {
105 | // Convert our arrDecryptedBytes back into text
106 | sDecryptedText = waes.utils.utf8.fromBytes( arrDecryptedBytes );
107 | if ( wlib.getStrLen( sDecryptedText ) > 0 )
108 | {
109 | // ...
110 | sRet = sDecryptedText;
111 | }
112 | }
113 | }
114 | }
115 |
116 | return sRet;
117 | }
118 |
119 |
120 |
121 | /**
122 | * @ private
123 | * init version
124 | */
125 | _initVersion( nVersion )
126 | {
127 | //
128 | // set version
129 | //
130 | if ( wlib.isNumeric( nVersion ) &&
131 | wlib.isObjectWithKeys( this.m_arrVersionList, nVersion ) )
132 | {
133 | this.m_nVersion = nVersion;
134 | }
135 | }
136 |
137 | /**
138 | * create a 256-bits key by sha256
139 | *
140 | * @return array 256-bits key
141 | */
142 | _createKey()
143 | {
144 | var arrRet;
145 | let sSource;
146 | let arrKey;
147 |
148 | // ...
149 | arrRet = null;
150 | sSource = '';
151 |
152 | sSource += '..........,..........';
153 | sSource += '..........,..........';
154 | sSource += ',';
155 | sSource += new String( this.m_nVersion );
156 | sSource += ',';
157 | sSource += '..........,..........';
158 | sSource += '..........,..........';
159 |
160 | // ...
161 | arrKey = wsha256.array( sSource );
162 | if ( wlib.isArray( arrKey ) && 32 === arrKey.length )
163 | {
164 | arrRet = arrKey;
165 | }
166 |
167 | return arrRet;
168 | }
169 |
170 |
171 | }
172 |
173 |
174 |
175 |
176 |
177 | /**
178 | * exports
179 | */
180 | module.exports =
181 | {
182 | CEncryptHint : CEncryptHint
183 | };
--------------------------------------------------------------------------------
/src/pages/open/open.js:
--------------------------------------------------------------------------------
1 | //
2 | // index.js
3 | // 获取应用实例
4 | //
5 | var wurl = require( '../../libs/wurl.js' );
6 | var wlib = require( '../../libs/wlib.js' );
7 | var msecret = require( '../../models/secret/CSecretEnds.js' );
8 | var mhint = require( '../../models/secret/CEncryptHint.js' );
9 | var msign = require( '../../models/secret/CSignature.js' );
10 |
11 | var m_oTopToast = null;
12 | var m_oHappyLoading = null;
13 | const app = getApp();
14 |
15 | /**
16 | * open message status
17 | */
18 | const _CONST_OPEN_MESSAGE_STATUS_EMPTY = 1;
19 | const _CONST_OPEN_MESSAGE_STATUS_DECRYPT = 2;
20 | const _CONST_OPEN_MESSAGE_STATUS_READ = 3;
21 |
22 |
23 |
24 |
25 | /**
26 | * Page
27 | */
28 | Page({
29 |
30 | data:
31 | {
32 | OPEN_MESSAGE_STATUS_EMPTY : _CONST_OPEN_MESSAGE_STATUS_EMPTY,
33 | OPEN_MESSAGE_STATUS_DECRYPT : _CONST_OPEN_MESSAGE_STATUS_DECRYPT,
34 | OPEN_MESSAGE_STATUS_READ : _CONST_OPEN_MESSAGE_STATUS_READ,
35 |
36 | nOpenMessageStatus : _CONST_OPEN_MESSAGE_STATUS_EMPTY,
37 | sPasswordHint : '没有提示文字',
38 | sMessage : '',
39 |
40 | bFocussPassword : false,
41 | bDisabledSubmit : false
42 | },
43 |
44 | onReady: function ()
45 | {
46 | // 获得 dialog组件
47 | m_oTopToast = this.selectComponent( "#id-top-toast" );
48 | m_oHappyLoading = this.selectComponent( "#id-happy-loading" );
49 |
50 | console.log("onReady / wurl.getCurrentPageArgs() = ", wurl.getCurrentPageArgs());
51 | },
52 |
53 | onLoad: function ( oOptions )
54 | {
55 | // ...
56 | console.log( "onLoad / wurl.getCurrentPageArgs() = ", wurl.getCurrentPageArgs() );
57 |
58 | // ...
59 | console.log("nOpenMessageStatus = ", this.data.nOpenMessageStatus);
60 | this._initPage();
61 | console.log("nOpenMessageStatus = ", this.data.nOpenMessageStatus);
62 | },
63 |
64 | onFormOpenSubmit : function( oEvent )
65 | {
66 | var sPassword;
67 | var sDecryptedMessage;
68 |
69 | // ...
70 | console.log( "onFormOpenSubmit", oEvent );
71 |
72 | if ( ! wlib.isObjectWithKeys( oEvent, 'detail' ) ||
73 | ! wlib.isObjectWithKeys(oEvent.detail, 'value') ||
74 | ! wlib.isObjectWithKeys(oEvent.detail.value, [ 'password' ] ) )
75 | {
76 | m_oTopToast.showTopToast('err', '参数错误,无法继续');
77 | return false;
78 | }
79 |
80 | // ...
81 | sPassword = oEvent.detail.value.password;
82 |
83 | if ( 0 == wlib.getStrLen( sPassword, true ) )
84 | {
85 | this.setData({
86 | bFocussPassword: true,
87 | });
88 | m_oTopToast.showTopToast('err', '请输入密码');
89 | return false;
90 | }
91 |
92 | // show loading
93 | m_oHappyLoading.showLoading();
94 | this.setData({
95 | bDisabledSubmit : true
96 | });
97 |
98 | // ...
99 | sDecryptedMessage = this._decryptMessage( sPassword );
100 | setTimeout( () =>
101 | {
102 | // hide loading
103 | m_oHappyLoading.hideLoading();
104 | this.setData({
105 | bDisabledSubmit: false
106 | });
107 |
108 | if ( wlib.getStrLen( sDecryptedMessage ) > 0 )
109 | {
110 | this.setData({
111 | nOpenMessageStatus: this.data.OPEN_MESSAGE_STATUS_READ,
112 | sMessage: sDecryptedMessage
113 | });
114 | }
115 | else
116 | {
117 | m_oTopToast.showTopToast( 'err', '密码不正确,解密失败' );
118 | }
119 | },
120 | wlib.getRandomNumber( 100, 1000 ) );
121 | },
122 |
123 |
124 | /**
125 | * initalize page
126 | */
127 | _initPage : function ()
128 | {
129 | var oMHint;
130 | var oPageArgs;
131 |
132 | // ...
133 | oMHint = new mhint.CEncryptHint();
134 | oPageArgs = wurl.getCurrentPageArgs();
135 |
136 | if ( wlib.isObjectWithKeys( oPageArgs, 'h' ) )
137 | {
138 | this.setData({
139 | nOpenMessageStatus : this.data.OPEN_MESSAGE_STATUS_DECRYPT,
140 | sPasswordHint: oMHint.decryptSecret( oPageArgs.h )
141 | });
142 | }
143 | else
144 | {
145 | this.setData({
146 | nOpenMessageStatus: this.data.OPEN_MESSAGE_STATUS_EMPTY
147 | });
148 | }
149 |
150 | },
151 |
152 |
153 | /**
154 | * @private
155 | * @return string decrypted message
156 | */
157 | _decryptMessage: function ( sPassword )
158 | {
159 | var sRet;
160 | let oMSecret;
161 | let oMSign;
162 |
163 | let oPageArgs;
164 | let nVersion;
165 | let nSecretId;
166 | let sEncryptedHex;
167 | let sSignature;
168 | let nTimestampStart;
169 | let nExpireInSeconds;
170 | let sSignatureCalc;
171 | let sMessage;
172 |
173 | //
174 | // ...
175 | //
176 | sRet = null;
177 | oMSecret = new msecret.CSecretEnds();
178 | oMSign = new msign.CSignature();
179 | oPageArgs = wurl.getCurrentPageArgs();
180 |
181 | if ( ! wlib.isObjectWithKeys( oPageArgs, [ 'v', 'i', 'm', 's', 'h', 'ts', 'te', '_' ] ) )
182 | {
183 | m_oTopToast.showTopToast( 'err', '参数错误,无法解密,请联系软件作者' );
184 | return null;
185 | }
186 |
187 | // ...
188 | nVersion = parseInt( oPageArgs.v );
189 | nSecretId = parseInt( oPageArgs.i );
190 | sEncryptedHex = oPageArgs.m;
191 | sSignature = oPageArgs.s;
192 | nTimestampStart = parseInt( oPageArgs.ts );
193 | nExpireInSeconds = parseInt( oPageArgs.te );
194 |
195 | oMSecret.version = nVersion;
196 | sMessage = oMSecret.decryptSecret(
197 | nSecretId, sEncryptedHex, sPassword, nTimestampStart, nExpireInSeconds
198 | );
199 | sSignatureCalc = oMSign.createSignature([
200 | nSecretId, sMessage, sPassword, nTimestampStart, nExpireInSeconds
201 | ]);
202 |
203 | if ( sSignature === sSignatureCalc )
204 | {
205 | sRet = sMessage;
206 | }
207 |
208 | console.log( "_decryptMessage = ", sRet, "lastErrorId = ", oMSecret.lastErrorId );
209 |
210 | // ...
211 | return sRet;
212 | }
213 |
214 | })
--------------------------------------------------------------------------------
/src/pages/create/create.js:
--------------------------------------------------------------------------------
1 | //
2 | // create.js
3 | //
4 | var wurl = require( '../../libs/wurl.js' );
5 | var wlib = require( '../../libs/wlib.js' );
6 | var wchar = require( '../../libs/wchar.js' );
7 | var wdatetime = require( '../../libs/wdatetime.js' );
8 | var msecret = require( '../../models/secret/CSecretEnds.js' );
9 | var mhint = require( '../../models/secret/CEncryptHint.js' );
10 | var msign = require( '../../models/secret/CSignature.js' );
11 |
12 | const app = getApp();
13 | var m_oTopToast = null;
14 |
15 |
16 |
17 | /**
18 | * Page
19 | */
20 | Page({
21 |
22 | data:
23 | {
24 | bFocusMessage : true,
25 | bFocussPassword : false,
26 | bFocussPasswordHint : false,
27 |
28 | sPasswordHint : '',
29 |
30 | bPasswordHintDlgShow : false,
31 | arrPasswordHintList : [
32 | "密码排行榜上排名第一的密码",
33 | "我们第一次遇见的城市名",
34 | "我们第一次看的电影名",
35 | "我们第一次阅读的书名",
36 | "我身上的纹身图案什么含义",
37 | "最难忘,爱你的那首歌",
38 | "挖掘机技术哪家强",
39 | "一棵藤上七个瓜,风吹雨打都不怕",
40 | "啊…… 啊啊啊 ……,电影名",
41 | "长江长江!我是黄河!",
42 | "空气在颤抖,天空在燃烧,是啊",
43 | "鸳鸯茶,鸳鸯茶,你爱我……",
44 | "天王盖地虎,宝塔镇河妖",
45 | "坦白从宽,抗拒从严"
46 | ],
47 | },
48 |
49 | onReady: function ()
50 | {
51 | // 获得 dialog组件
52 | m_oTopToast = this.selectComponent( "#id-top-toast" );
53 | },
54 | onLoad: function ( oOptions )
55 | {
56 | },
57 |
58 |
59 | onTopToastCancel: function( oEvent )
60 | {
61 | //console.log( "onTopToastCancel", oEvent );
62 | m_oTopToast.hideTopToast();
63 | },
64 | onMessageInput: function( oEvent )
65 | {
66 | //console.log("onMessageInput", oEvent);
67 | },
68 |
69 | /**
70 | * show password hint
71 | */
72 | onTapShowPasswordHintDlg: function( oEvent )
73 | {
74 | this.setData({
75 | bPasswordHintDlgShow: true,
76 | });
77 | },
78 | onTapHidePasswordHintDlg: function( oEvent )
79 | {
80 | this.setData({
81 | bPasswordHintDlgShow: false
82 | });
83 | },
84 | onTapPasswordHintItem: function( oEvent )
85 | {
86 | let nIndex;
87 |
88 | // ...
89 | nIndex = parseInt( oEvent.currentTarget.dataset.index );
90 |
91 | if ( nIndex >= 0 && nIndex < this.data.arrPasswordHintList.length )
92 | {
93 | this.setData({
94 | sPasswordHint: this.data.arrPasswordHintList[ nIndex ],
95 | });
96 | }
97 |
98 | this.setData({
99 | bPasswordHintDlgShow: false
100 | });
101 |
102 | // ...
103 | //console.log( "onTapPasswordHintItem", oEvent );
104 | },
105 |
106 |
107 | onFormCreateSubmit: function( oEvent )
108 | {
109 | var sMessage;
110 | var sPassword;
111 | var sPasswordHint;
112 |
113 | // ...
114 | //console.log( "onFormCreateSubmit", oEvent );
115 |
116 | if ( ! wlib.isObjectWithKeys( oEvent, 'detail' ) ||
117 | ! wlib.isObjectWithKeys( oEvent.detail, 'value' ) ||
118 | ! wlib.isObjectWithKeys( oEvent.detail.value, [ 'message', 'password', 'password_hint' ] ) )
119 | {
120 | m_oTopToast.showTopToast( 'err', '参数错误,无法继续' );
121 | return false;
122 | }
123 |
124 | // ...
125 | sMessage = oEvent.detail.value.message;
126 | sPassword = oEvent.detail.value.password;
127 | sPasswordHint = oEvent.detail.value.password_hint;
128 |
129 | if ( 0 == wlib.getStrLen( sMessage, true ) )
130 | {
131 | this.setData({
132 | bFocusMessage: true,
133 | bFocussPassword: false,
134 | bFocussPasswordHint: false
135 | });
136 | m_oTopToast.showTopToast( 'err', '请输入纸条内容,最多 128 个字符' );
137 | return false;
138 | }
139 | if ( ! wchar.isChineseChars( sMessage ) )
140 | {
141 | this.setData({
142 | bFocusMessage: true,
143 | bFocussPassword: false,
144 | bFocussPasswordHint: false
145 | });
146 | m_oTopToast.showTopToast( 'err', '纸条内容不能含有表情符等其他特殊字符');
147 | return false;
148 | }
149 |
150 | if ( 0 == wlib.getStrLen( sPassword, true ) )
151 | {
152 | this.setData({
153 | bFocusMessage: false,
154 | bFocussPassword: true,
155 | bFocussPasswordHint: false
156 | });
157 | m_oTopToast.showTopToast( 'err', '请输入密码,最多 32 个字符' );
158 | return false;
159 | }
160 | if ( ! wchar.isChineseChars( sPassword ) )
161 | {
162 | this.setData({
163 | bFocusMessage: false,
164 | bFocussPassword: true,
165 | bFocussPasswordHint: false
166 | });
167 | m_oTopToast.showTopToast( 'err', '密码不能含有表情符等其他特殊字符' );
168 | return false;
169 | }
170 |
171 | if ( 0 == wlib.getStrLen( sPasswordHint, true ) )
172 | {
173 | this.setData({
174 | bFocusMessage: false,
175 | bFocussPassword: false,
176 | bFocussPasswordHint: true
177 | });
178 | m_oTopToast.showTopToast( 'err', '请输入解密提示文字,最多 64 个字符' );
179 | return false;
180 | }
181 | if ( ! wchar.isChineseChars( sPasswordHint ) )
182 | {
183 | this.setData({
184 | bFocusMessage: false,
185 | bFocussPassword: false,
186 | bFocussPasswordHint: true
187 | });
188 | m_oTopToast.showTopToast( 'err', '密码提示文字不能含有表情符等其他特殊字符');
189 | return false;
190 | }
191 |
192 | //
193 | // begin the encryption
194 | //
195 | wx.navigateTo({
196 | url: '/pages/done/done?' + this._encryptMessage( sMessage, sPassword, sPasswordHint )
197 | });
198 | },
199 |
200 |
201 |
202 |
203 | /**
204 | * @private
205 | */
206 | _encryptMessage: function( sMessage, sPassword, sPasswordHint )
207 | {
208 | var sRet;
209 | let oMSecret;
210 | let oMHint;
211 | let oMSign;
212 |
213 | let nSecretId;
214 | let nTimestampStart;
215 | let nExpireInSeconds;
216 | let sEncryptedHex;
217 | let sSignature;
218 |
219 | //
220 | // todo
221 | // 1, AES password hint
222 | //
223 | oMSecret = new msecret.CSecretEnds();
224 | oMHint = new mhint.CEncryptHint();
225 | oMSign = new msign.CSignature();
226 |
227 | nSecretId = wdatetime.getCurrentTimestamp();
228 | nTimestampStart = wdatetime.getCurrentTimestamp();
229 | nExpireInSeconds = 0;
230 | sEncryptedHex = oMSecret.encryptSecret(
231 | nSecretId, sMessage, sPassword, nTimestampStart, nExpireInSeconds
232 | );
233 | sSignature = oMSign.createSignature([
234 | nSecretId, sMessage, sPassword, nTimestampStart, nExpireInSeconds
235 | ]);
236 |
237 | // ...
238 | sRet = ""
239 | + "v=" + new String( oMSecret.version ) + "&"
240 | + "i=" + new String( nSecretId ) + "&"
241 | + "m=" + new String( sEncryptedHex ) + "&"
242 | + "s=" + new String( sSignature ) + "&"
243 | + "h=" + new String( oMHint.encryptHint( sPasswordHint ) ) + "&"
244 | + "ts=" + new String( nTimestampStart ) + "&"
245 | + "te=" + new String( nExpireInSeconds ) + "&"
246 | + "_=" + new String( wdatetime.getCurrentTimestamp() )
247 | ;
248 |
249 | return sRet;
250 | }
251 |
252 | })
--------------------------------------------------------------------------------
/src/models/secret/CSecretEnds.js:
--------------------------------------------------------------------------------
1 | var wlib = require( '../../libs/wlib.js' );
2 | var wdatetime = require( '../../libs/wdatetime.js' );
3 | var waes = require( '../../libs/cipher/waes.js' );
4 | var wsha256 = require( '../../libs/cipher/wsha256.js' );
5 |
6 |
7 | /**
8 | * secret ends errors
9 | */
10 | class CSecretEndsErrors {
11 | }
12 | CSecretEndsErrors.ERROR_SUCCESS = 0;
13 | CSecretEndsErrors.ERROR_UNKNOWN = -1;
14 |
15 | CSecretEndsErrors.ERROR_ENCRYPTSECRET_PARAM_SECRET_ID = 1000;
16 | CSecretEndsErrors.ERROR_ENCRYPTSECRET_PARAM_MESSAGE = 1001;
17 | CSecretEndsErrors.ERROR_ENCRYPTSECRET_CREATEKEY = 1010;
18 | CSecretEndsErrors.ERROR_ENCRYPTSECRET_CONVERT_MESSAGE_TO_BYTES = 1011;
19 | CSecretEndsErrors.ERROR_ENCRYPTSECRET_AES_CTR_MODE_ENCRYPT = 1012;
20 | CSecretEndsErrors.ERROR_ENCRYPTSECRET_CONVERT_ENCRYPTED_BYTES_TO_HEX = 1013;
21 |
22 | CSecretEndsErrors.ERROR_DECRYPTSECRET_PARAM_SECRET_ID = 2000;
23 | CSecretEndsErrors.ERROR_DECRYPTSECRET_PARAM_ENCRYPTED_HEX = 2001;
24 | CSecretEndsErrors.ERROR_DECRYPTSECRET_CREATEKEY = 2010;
25 | CSecretEndsErrors.ERROR_ENCRYPTSECRET_CONVERT_ENCRYPTED_HEX_TO_BYTES = 1011;
26 | CSecretEndsErrors.ERROR_DECRYPTSECRET_AES_CTR_MODE_DECRYPT = 2012;
27 | CSecretEndsErrors.ERROR_DECRYPTSECRET_CONVERT_DECRYPTED_BYTES_TO_TEXT = 2013;
28 |
29 |
30 |
31 | /**
32 | * secret ends core model
33 | */
34 | class CSecretEnds
35 | {
36 | // version
37 | m_nVersion = 1;
38 | m_arrVersionList = { 1 : 1 };
39 |
40 | // last error id
41 | m_nLastErrorId = -1;
42 |
43 |
44 | constructor( nVersion )
45 | {
46 | this._initVersion( nVersion );
47 | }
48 |
49 |
50 | /**
51 | * get/set version
52 | */
53 | get version()
54 | {
55 | return this.m_nVersion;
56 | }
57 | set version( nVersion )
58 | {
59 | this._initVersion( nVersion );
60 | }
61 |
62 |
63 | /**
64 | * get last error id
65 | */
66 | get lastErrorId()
67 | {
68 | return this.m_nLastErrorId;
69 | }
70 | set lastErrorId( nErrorId )
71 | {
72 | this.m_nLastErrorId = nErrorId;
73 | }
74 |
75 |
76 | /**
77 | * @ public
78 | *
79 | * @param int nSecretId
80 | * @param string sMessage
81 | * @param string sPassword
82 | * @param int nTimestampStart
83 | * @param int nExpireInSeconds
84 | * @return string encrypted hex string
85 | */
86 | encryptSecret( nSecretId, sMessage, sPassword, nTimestampStart, nExpireInSeconds )
87 | {
88 | var sRet;
89 | let arrKey;
90 | let arrMessageBytes;
91 | let oAesCtrMode;
92 | let arrEncryptedBytes;
93 | let sEncryptedHex;
94 |
95 | if ( ! wlib.isNumeric( nSecretId ) || nSecretId <= 0 )
96 | {
97 | this.lastErrorId = CSecretEndsErrors.ERROR_ENCRYPTSECRET_PARAM_SECRET_ID;
98 | return null;
99 | }
100 | if ( 0 === wlib.getStrLen( sMessage ) )
101 | {
102 | this.lastErrorId = CSecretEndsErrors.ERROR_ENCRYPTSECRET_PARAM_MESSAGE;
103 | return null;
104 | }
105 |
106 | // ...
107 | sRet = null;
108 | arrKey = this._createKey( nSecretId, sPassword, nTimestampStart, nExpireInSeconds );
109 | if ( wlib.isArray( arrKey ) && 32 === arrKey.length )
110 | {
111 | // Convert sMessage to bytes
112 | arrMessageBytes = waes.utils.utf8.toBytes( sMessage );
113 | if ( wlib.isArray( arrMessageBytes ) )
114 | {
115 | // The counter is optional, and if omitted will begin at 1
116 | oAesCtrMode = new waes.ModeOfOperation.ctr( arrKey, new waes.Counter( 1 ) );
117 | arrEncryptedBytes = oAesCtrMode.encrypt( arrMessageBytes );
118 | if ( wlib.isArray( arrEncryptedBytes ) )
119 | {
120 | // To print or store the binary data, you may convert arrEncryptedBytes to hex
121 | sEncryptedHex = waes.utils.hex.fromBytes( arrEncryptedBytes );
122 | if ( wlib.getStrLen( sEncryptedHex ) > 0 )
123 | {
124 | // ...
125 | sRet = sEncryptedHex;
126 |
127 | // ...
128 | this.lastErrorId = CSecretEndsErrors.ERROR_SUCCESS;
129 | }
130 | else
131 | {
132 | this.lastErrorId = CSecretEndsErrors.ERROR_ENCRYPTSECRET_CONVERT_ENCRYPTED_BYTES_TO_HEX;
133 | }
134 | }
135 | else
136 | {
137 | this.lastErrorId = CSecretEndsErrors.ERROR_ENCRYPTSECRET_AES_CTR_MODE_ENCRYPT;
138 | }
139 | }
140 | else
141 | {
142 | this.lastErrorId = CSecretEndsErrors.ERROR_ENCRYPTSECRET_CONVERT_MESSAGE_TO_BYTES;
143 | }
144 | }
145 | else
146 | {
147 | this.lastErrorId = CSecretEndsErrors.ERROR_ENCRYPTSECRET_CREATEKEY;
148 | }
149 |
150 | return sRet;
151 | }
152 |
153 |
154 | /**
155 | * @ public
156 | *
157 | * @param int nSecretId
158 | * @param string sEncryptedHex
159 | * @param string sPassword
160 | * @param int nTimestampStart
161 | * @param int nExpireInSeconds
162 | * @return string decrypted message
163 | */
164 | decryptSecret( nSecretId, sEncryptedHex, sPassword, nTimestampStart, nExpireInSeconds )
165 | {
166 | var sRet;
167 | let arrKey;
168 | let oAesCtrMode;
169 | let arrEncryptedBytes;
170 | let arrDecryptedBytes;
171 | let sDecryptedText;
172 |
173 | if ( ! wlib.isNumeric( nSecretId ) || nSecretId <= 0 )
174 | {
175 | this.lastErrorId = CSecretEndsErrors.ERROR_DECRYPTSECRET_PARAM_SECRET_ID;
176 | return null;
177 | }
178 | if ( 0 === wlib.getStrLen( sEncryptedHex ) )
179 | {
180 | this.lastErrorId = CSecretEndsErrors.ERROR_DECRYPTSECRET_PARAM_ENCRYPTED_HEX;
181 | return null;
182 | }
183 |
184 | // ...
185 | sRet = null;
186 | arrKey = this._createKey( nSecretId, sPassword, nTimestampStart, nExpireInSeconds );
187 | if ( wlib.isArray( arrKey ) && 32 === arrKey.length )
188 | {
189 | // When ready to decrypt the hex string, convert it back to bytes
190 | arrEncryptedBytes = waes.utils.hex.toBytes( sEncryptedHex );
191 | if ( wlib.isArray( arrEncryptedBytes ) )
192 | {
193 | //
194 | // The counter mode of operation maintains internal state, so to
195 | // decrypt a new instance must be instantiated.
196 | //
197 | oAesCtrMode = new waes.ModeOfOperation.ctr( arrKey, new waes.Counter( 1 ) );
198 | arrDecryptedBytes = oAesCtrMode.decrypt( arrEncryptedBytes );
199 | if ( wlib.isArray( arrDecryptedBytes ) )
200 | {
201 | // Convert our arrDecryptedBytes back into text
202 | sDecryptedText = waes.utils.utf8.fromBytes( arrDecryptedBytes );
203 | if ( wlib.getStrLen( sDecryptedText ) > 0 )
204 | {
205 | // ...
206 | sRet = sDecryptedText;
207 |
208 | // ...
209 | this.lastErrorId = CSecretEndsErrors.ERROR_SUCCESS;
210 | }
211 | else
212 | {
213 | this.lastErrorId = CSecretEndsErrors.ERROR_DECRYPTSECRET_CONVERT_DECRYPTED_BYTES_TO_TEXT;
214 | }
215 | }
216 | else
217 | {
218 | this.lastErrorId = CSecretEndsErrors.ERROR_DECRYPTSECRET_AES_CTR_MODE_DECRYPT;
219 | }
220 | }
221 | else
222 | {
223 | this.lastErrorId = CSecretEndsErrors.ERROR_ENCRYPTSECRET_CONVERT_ENCRYPTED_HEX_TO_BYTES;
224 | }
225 | }
226 | else
227 | {
228 | this.lastErrorId = CSecretEndsErrors.ERROR_DECRYPTSECRET_CREATEKEY
229 | }
230 |
231 | return sRet;
232 | }
233 |
234 |
235 |
236 | /**
237 | * @ private
238 | * init version
239 | */
240 | _initVersion( nVersion )
241 | {
242 | //
243 | // set version
244 | //
245 | if ( wlib.isNumeric( nVersion ) &&
246 | wlib.isObjectWithKeys( this.m_arrVersionList, nVersion ) )
247 | {
248 | this.m_nVersion = parseInt( nVersion );
249 | }
250 | }
251 |
252 | /**
253 | * create a 256-bits key by sha256
254 | *
255 | * @param int nSecretId
256 | * @param string sPassword
257 | * @param int nTimestampStart
258 | * @param int nExpireInSeconds
259 | * @return array 256-bits key
260 | */
261 | _createKey( nSecretId, sPassword, nTimestampStart, nExpireInSeconds )
262 | {
263 | var arrRet;
264 | let sSource;
265 | let arrKey;
266 |
267 | if ( ! wlib.isNumeric( nSecretId ) || nSecretId <= 0 )
268 | {
269 | return null;
270 | }
271 | if ( 0 === wlib.getStrLen( sPassword ) )
272 | {
273 | return null;
274 | }
275 | if ( ! wlib.isNumeric( nTimestampStart ) || nTimestampStart <= 0 )
276 | {
277 | return null;
278 | }
279 | if ( ! wlib.isNumeric( nExpireInSeconds ) || nExpireInSeconds < 0 )
280 | {
281 | return null;
282 | }
283 |
284 | // ...
285 | arrRet = null;
286 | sSource = '';
287 |
288 | sSource += '..........,..........';
289 | sSource += new String( nSecretId );
290 | sSource += ',';
291 | sSource += new String( this.m_nVersion );
292 | sSource += ',';
293 | sSource += new String( sPassword );
294 | sSource += ',';
295 | sSource += new String( nTimestampStart );
296 | sSource += ',';
297 | sSource += new String( nExpireInSeconds );
298 | sSource += '..........,..........';
299 |
300 | // ...
301 | arrKey = wsha256.array( sSource );
302 | if ( wlib.isArray( arrKey ) && 32 === arrKey.length )
303 | {
304 | arrRet = arrKey;
305 | }
306 |
307 | return arrRet;
308 | }
309 |
310 |
311 | }
312 |
313 |
314 |
315 |
316 |
317 | /**
318 | * exports
319 | */
320 | module.exports =
321 | {
322 | Errors : CSecretEndsErrors,
323 | CSecretEnds : CSecretEnds
324 | };
--------------------------------------------------------------------------------
/src/resources/style/weui.wxss:
--------------------------------------------------------------------------------
1 | /*!
2 | * WeUI v1.1.1 (https://github.com/weui/weui-wxss)
3 | * Copyright 2017 Tencent, Inc.
4 | * Licensed under the MIT license
5 | */
6 | page{line-height:1.6;font-family:-apple-system-font,Helvetica Neue,sans-serif}icon{vertical-align:middle}.weui-cells{position:relative;margin-top:1.17647059em;background-color:#fff;line-height:1.41176471;font-size:17px}.weui-cells:before{top:0;border-top:1rpx solid #d9d9d9}.weui-cells:after,.weui-cells:before{content:" ";position:absolute;left:0;right:0;height:1px;color:#d9d9d9}.weui-cells:after{bottom:0;border-bottom:1rpx solid #d9d9d9}.weui-cells__title{margin-top:.77em;margin-bottom:.3em;padding-left:15px;padding-right:15px;color:#999;font-size:14px}.weui-cells_after-title{margin-top:0}.weui-cells__tips{margin-top:.3em;color:#999;padding-left:15px;padding-right:15px;font-size:14px}.weui-cell{padding:10px 15px;position:relative;display:-webkit-box;display:-webkit-flex;display:flex;-webkit-box-align:center;-webkit-align-items:center;align-items:center}.weui-cell:before{content:" ";position:absolute;left:0;top:0;right:0;height:1px;border-top:1rpx solid #d9d9d9;color:#d9d9d9;left:15px}.weui-cell:first-child:before{display:none}.weui-cell_active{background-color:#ececec}.weui-cell_primary{-webkit-box-align:start;-webkit-align-items:flex-start;align-items:flex-start}.weui-cell__bd{-webkit-box-flex:1;-webkit-flex:1;flex:1}.weui-cell__ft{text-align:right;color:#999}.weui-cell_access{color:inherit}.weui-cell__ft_in-access{padding-right:13px;position:relative}.weui-cell__ft_in-access:after{content:" ";display:inline-block;height:6px;width:6px;border-width:2px 2px 0 0;border-color:#c8c8cd;border-style:solid;-webkit-transform:matrix(.71,.71,-.71,.71,0,0);transform:matrix(.71,.71,-.71,.71,0,0);position:relative;top:-2px;position:absolute;top:50%;margin-top:-4px;right:2px}.weui-cell_link{color:#586c94;font-size:14px}.weui-cell_link:active{background-color:#ececec}.weui-cell_link:first-child:before{display:block}.weui-icon-radio{margin-left:3.2px;margin-right:3.2px}.weui-icon-checkbox_circle,.weui-icon-checkbox_success{margin-left:4.6px;margin-right:4.6px}.weui-check__label:active{background-color:#ececec}.weui-check{position:absolute;left:-9999px}.weui-check__hd_in-checkbox{padding-right:.35em}.weui-cell__ft_in-radio{padding-left:.35em}.weui-cell_input{padding-top:0;padding-bottom:0}.weui-label{width:105px;word-wrap:break-word;word-break:break-all}.weui-input{height:2.58823529em;min-height:2.58823529em;line-height:2.58823529em}.weui-toptips{position:fixed;-webkit-transform:translateZ(0);transform:translateZ(0);top:0;left:0;right:0;padding:5px;font-size:14px;text-align:center;color:#fff;z-index:5000;word-wrap:break-word;word-break:break-all}.weui-toptips_warn{background-color:#e64340}.weui-textarea{display:block;width:100%}.weui-textarea-counter{color:#b2b2b2;text-align:right}.weui-cell_warn,.weui-textarea-counter_warn{color:#e64340}.weui-form-preview{position:relative;background-color:#fff}.weui-form-preview:before{top:0;border-top:1rpx solid #d9d9d9}.weui-form-preview:after,.weui-form-preview:before{content:" ";position:absolute;left:0;right:0;height:1px;color:#d9d9d9}.weui-form-preview:after{bottom:0;border-bottom:1rpx solid #d9d9d9}.weui-form-preview__value{font-size:14px}.weui-form-preview__value_in-hd{font-size:26px}.weui-form-preview__hd{position:relative;padding:10px 15px;text-align:right;line-height:2.5em}.weui-form-preview__hd:after{content:" ";position:absolute;left:0;bottom:0;right:0;height:1px;border-bottom:1rpx solid #d9d9d9;color:#d9d9d9;left:15px}.weui-form-preview__bd{padding:10px 15px;font-size:.9em;text-align:right;color:#999;line-height:2}.weui-form-preview__ft{position:relative;line-height:50px;display:-webkit-box;display:-webkit-flex;display:flex}.weui-form-preview__ft:after{content:" ";position:absolute;left:0;top:0;right:0;height:1px;border-top:1rpx solid #d5d5d6;color:#d5d5d6}.weui-form-preview__item{overflow:hidden}.weui-form-preview__label{float:left;margin-right:1em;min-width:4em;color:#999;text-align:justify;text-align-last:justify}.weui-form-preview__value{display:block;overflow:hidden;word-break:normal;word-wrap:break-word}.weui-form-preview__btn{position:relative;display:block;-webkit-box-flex:1;-webkit-flex:1;flex:1;color:#3cc51f;text-align:center}.weui-form-preview__btn:after{content:" ";position:absolute;left:0;top:0;width:1px;bottom:0;border-left:1rpx solid #d5d5d6;color:#d5d5d6}.weui-form-preview__btn:first-child:after{display:none}.weui-form-preview__btn_active{background-color:#eee}.weui-form-preview__btn_default{color:#999}.weui-form-preview__btn_primary{color:#0bb20c}.weui-cell_select{padding:0}.weui-select{position:relative;padding-left:15px;padding-right:30px;height:2.58823529em;min-height:2.58823529em;line-height:2.58823529em;border-right:1rpx solid #d9d9d9}.weui-select:before{content:" ";display:inline-block;height:6px;width:6px;border-width:2px 2px 0 0;border-color:#c8c8cd;border-style:solid;-webkit-transform:matrix(.71,.71,-.71,.71,0,0);transform:matrix(.71,.71,-.71,.71,0,0);position:relative;top:-2px;position:absolute;top:50%;right:15px;margin-top:-4px}.weui-select_in-select-after{padding-left:0}.weui-cell__bd_in-select-before,.weui-cell__hd_in-select-after{padding-left:15px}.weui-cell_vcode{padding-right:0}.weui-vcode-btn,.weui-vcode-img{margin-left:5px;height:2.58823529em;vertical-align:middle}.weui-vcode-btn{display:inline-block;padding:0 .6em 0 .7em;border-left:1px solid #e5e5e5;line-height:2.58823529em;font-size:17px;color:#3cc51f;white-space:nowrap}.weui-vcode-btn:active{color:#52a341}.weui-cell_switch{padding-top:6px;padding-bottom:6px}.weui-uploader__hd{display:-webkit-box;display:-webkit-flex;display:flex;padding-bottom:10px;-webkit-box-align:center;-webkit-align-items:center;align-items:center}.weui-uploader__title{-webkit-box-flex:1;-webkit-flex:1;flex:1}.weui-uploader__info{color:#b2b2b2}.weui-uploader__bd{margin-bottom:-4px;margin-right:-9px;overflow:hidden}.weui-uploader__file{float:left;margin-right:9px;margin-bottom:9px}.weui-uploader__img{display:block;width:79px;height:79px}.weui-uploader__file_status{position:relative}.weui-uploader__file_status:before{content:" ";position:absolute;top:0;right:0;bottom:0;left:0;background-color:rgba(0,0,0,.5)}.weui-uploader__file-content{position:absolute;top:50%;left:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);color:#fff}.weui-uploader__input-box{float:left;position:relative;margin-right:9px;margin-bottom:9px;width:77px;height:77px;border:1px solid #d9d9d9}.weui-uploader__input-box:after,.weui-uploader__input-box:before{content:" ";position:absolute;top:50%;left:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);background-color:#d9d9d9}.weui-uploader__input-box:before{width:2px;height:39.5px}.weui-uploader__input-box:after{width:39.5px;height:2px}.weui-uploader__input-box:active{border-color:#999}.weui-uploader__input-box:active:after,.weui-uploader__input-box:active:before{background-color:#999}.weui-uploader__input{position:absolute;z-index:1;top:0;left:0;width:100%;height:100%;opacity:0}.weui-article{padding:20px 15px;font-size:15px}.weui-article__section{margin-bottom:1.5em}.weui-article__h1{font-size:18px;font-weight:400;margin-bottom:.9em}.weui-article__h2{font-size:16px;font-weight:400;margin-bottom:.34em}.weui-article__h3{font-weight:400;font-size:15px;margin-bottom:.34em}.weui-article__p{margin:0 0 .8em}.weui-msg{padding-top:36px;text-align:center}.weui-msg__link{display:inline;color:#586c94}.weui-msg__icon-area{margin-bottom:30px}.weui-msg__text-area{margin-bottom:25px;padding:0 20px}.weui-msg__title{margin-bottom:5px;font-weight:400;font-size:20px}.weui-msg__desc{font-size:14px;color:#999}.weui-msg__opr-area{margin-bottom:25px}.weui-msg__extra-area{margin-bottom:15px;font-size:14px;color:#999}@media screen and (min-height:438px){.weui-msg__extra-area{position:fixed;left:0;bottom:0;width:100%;text-align:center}}.weui-flex{display:-webkit-box;display:-webkit-flex;display:flex}.weui-flex__item{-webkit-box-flex:1;-webkit-flex:1;flex:1}.weui-btn{margin-top:15px}.weui-btn:first-child{margin-top:0}.weui-btn-area{margin:1.17647059em 15px .3em}.weui-agree{display:block;padding:.5em 15px;font-size:13px}.weui-agree__text{color:#999}.weui-agree__link{display:inline;color:#586c94}.weui-agree__checkbox{position:absolute;left:-9999px}.weui-agree__checkbox-icon{position:relative;top:2px;display:inline-block;border:1px solid #d1d1d1;background-color:#fff;border-radius:3px;width:11px;height:11px}.weui-agree__checkbox-icon-check{position:absolute;top:1px;left:1px}.weui-footer{color:#999;font-size:14px;text-align:center}.weui-footer_fixed-bottom{position:fixed;bottom:.52em;left:0;right:0}.weui-footer__links{font-size:0}.weui-footer__link{display:inline-block;vertical-align:top;margin:0 .62em;position:relative;font-size:14px;color:#586c94}.weui-footer__link:before{content:" ";position:absolute;left:0;top:0;width:1px;bottom:0;border-left:1rpx solid #c7c7c7;color:#c7c7c7;left:-.65em;top:.36em;bottom:.36em}.weui-footer__link:first-child:before{display:none}.weui-footer__text{padding:0 .34em;font-size:12px}.weui-grids{border-top:1rpx solid #d9d9d9;border-left:1rpx solid #d9d9d9;overflow:hidden}.weui-grid{position:relative;float:left;padding:20px 10px;width:33.33333333%;box-sizing:border-box;border-right:1rpx solid #d9d9d9;border-bottom:1rpx solid #d9d9d9}.weui-grid_active{background-color:#ececec}.weui-grid__icon{display:block;width:28px;height:28px;margin:0 auto}.weui-grid__label{margin-top:5px;display:block;text-align:center;color:#000;font-size:14px;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.weui-loading{margin:0 5px;width:20px;height:20px;display:inline-block;vertical-align:middle;-webkit-animation:a 1s steps(12) infinite;animation:a 1s steps(12) infinite;background:transparent url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAiIGhlaWdodD0iMTIwIiB2aWV3Qm94PSIwIDAgMTAwIDEwMCI+PHBhdGggZmlsbD0ibm9uZSIgZD0iTTAgMGgxMDB2MTAwSDB6Ii8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjRTlFOUU5IiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAgLTMwKSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iIzk4OTY5NyIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSgzMCAxMDUuOTggNjUpIi8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjOUI5OTlBIiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0icm90YXRlKDYwIDc1Ljk4IDY1KSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iI0EzQTFBMiIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSg5MCA2NSA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNBQkE5QUEiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoMTIwIDU4LjY2IDY1KSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iI0IyQjJCMiIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSgxNTAgNTQuMDIgNjUpIi8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjQkFCOEI5IiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0icm90YXRlKDE4MCA1MCA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNDMkMwQzEiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoLTE1MCA0NS45OCA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNDQkNCQ0IiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoLTEyMCA0MS4zNCA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNEMkQyRDIiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoLTkwIDM1IDY1KSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iI0RBREFEQSIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSgtNjAgMjQuMDIgNjUpIi8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjRTJFMkUyIiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0icm90YXRlKC0zMCAtNS45OCA2NSkiLz48L3N2Zz4=) no-repeat;background-size:100%}.weui-loading.weui-loading_transparent{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120' viewBox='0 0 100 100'%3E%3Cpath fill='none' d='M0 0h100v100H0z'/%3E%3Crect xmlns='http://www.w3.org/2000/svg' width='7' height='20' x='46.5' y='40' fill='rgba(255,255,255,.56)' rx='5' ry='5' transform='translate(0 -30)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='rgba(255,255,255,.5)' rx='5' ry='5' transform='rotate(30 105.98 65)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='rgba(255,255,255,.43)' rx='5' ry='5' transform='rotate(60 75.98 65)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='rgba(255,255,255,.38)' rx='5' ry='5' transform='rotate(90 65 65)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='rgba(255,255,255,.32)' rx='5' ry='5' transform='rotate(120 58.66 65)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='rgba(255,255,255,.28)' rx='5' ry='5' transform='rotate(150 54.02 65)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='rgba(255,255,255,.25)' rx='5' ry='5' transform='rotate(180 50 65)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='rgba(255,255,255,.2)' rx='5' ry='5' transform='rotate(-150 45.98 65)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='rgba(255,255,255,.17)' rx='5' ry='5' transform='rotate(-120 41.34 65)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='rgba(255,255,255,.14)' rx='5' ry='5' transform='rotate(-90 35 65)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='rgba(255,255,255,.1)' rx='5' ry='5' transform='rotate(-60 24.02 65)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='rgba(255,255,255,.03)' rx='5' ry='5' transform='rotate(-30 -5.98 65)'/%3E%3C/svg%3E")}@-webkit-keyframes a{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes a{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}.weui-badge{display:inline-block;padding:.15em .4em;min-width:8px;border-radius:18px;background-color:#e64340;color:#fff;line-height:1.2;text-align:center;font-size:12px;vertical-align:middle}.weui-badge_dot{padding:.4em;min-width:0}.weui-loadmore{width:65%;margin:1.5em auto;line-height:1.6em;font-size:14px;text-align:center}.weui-loadmore__tips{display:inline-block;vertical-align:middle}.weui-loadmore_line{border-top:1px solid #e5e5e5;margin-top:2.4em}.weui-loadmore__tips_in-line{position:relative;top:-.9em;padding:0 .55em;background-color:#fff;color:#999}.weui-loadmore__tips_in-dot{position:relative;padding:0 .16em;width:4px;height:1.6em}.weui-loadmore__tips_in-dot:before{content:" ";position:absolute;top:50%;left:50%;margin-top:-1px;margin-left:-2px;width:4px;height:4px;border-radius:50%;background-color:#e5e5e5}.weui-panel{background-color:#fff;margin-top:10px;position:relative;overflow:hidden}.weui-panel:first-child{margin-top:0}.weui-panel:before{top:0;border-top:1rpx solid #e5e5e5}.weui-panel:after,.weui-panel:before{content:" ";position:absolute;left:0;right:0;height:1px;color:#e5e5e5}.weui-panel:after{bottom:0;border-bottom:1rpx solid #e5e5e5}.weui-panel__hd{padding:14px 15px 10px;color:#999;font-size:13px;position:relative}.weui-panel__hd:after{content:" ";position:absolute;left:0;bottom:0;right:0;height:1px;border-bottom:1rpx solid #e5e5e5;color:#e5e5e5;left:15px}.weui-media-box{padding:15px;position:relative}.weui-media-box:before{content:" ";position:absolute;left:0;top:0;right:0;height:1px;border-top:1rpx solid #e5e5e5;color:#e5e5e5;left:15px}.weui-media-box:first-child:before{display:none}.weui-media-box__title{font-weight:400;font-size:17px;width:auto;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;word-wrap:normal;word-wrap:break-word;word-break:break-all}.weui-media-box__desc{color:#999;font-size:13px;line-height:1.2;overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2}.weui-media-box__info{margin-top:15px;padding-bottom:5px;font-size:13px;color:#cecece;line-height:1em;list-style:none;overflow:hidden}.weui-media-box__info__meta{float:left;padding-right:1em}.weui-media-box__info__meta_extra{padding-left:1em;border-left:1px solid #cecece}.weui-media-box__title_in-text{margin-bottom:8px}.weui-media-box_appmsg{display:-webkit-box;display:-webkit-flex;display:flex;-webkit-box-align:center;-webkit-align-items:center;align-items:center}.weui-media-box__thumb{width:100%;height:100%;vertical-align:top}.weui-media-box__hd_in-appmsg{margin-right:.8em;width:60px;height:60px;line-height:60px;text-align:center}.weui-media-box__bd_in-appmsg{-webkit-box-flex:1;-webkit-flex:1;flex:1;min-width:0}.weui-media-box_small-appmsg{padding:0}.weui-cells_in-small-appmsg{margin-top:0}.weui-cells_in-small-appmsg:before{display:none}.weui-progress{display:-webkit-box;display:-webkit-flex;display:flex;-webkit-box-align:center;-webkit-align-items:center;align-items:center}.weui-progress__bar{-webkit-box-flex:1;-webkit-flex:1;flex:1}.weui-progress__opr{margin-left:15px;font-size:0}.weui-navbar{display:-webkit-box;display:-webkit-flex;display:flex;position:absolute;z-index:500;top:0;width:100%;border-bottom:1rpx solid #ccc}.weui-navbar__item{position:relative;display:block;-webkit-box-flex:1;-webkit-flex:1;flex:1;padding:13px 0;text-align:center;font-size:0}.weui-navbar__item.weui-bar__item_on{color:#1aad19}.weui-navbar__slider{position:absolute;content:" ";left:0;bottom:0;width:6em;height:3px;background-color:#1aad19;-webkit-transition:-webkit-transform .3s;transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s,-webkit-transform .3s}.weui-navbar__title{display:inline-block;font-size:15px;max-width:8em;width:auto;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;word-wrap:normal}.weui-tab{position:relative;height:100%}.weui-tab__panel{box-sizing:border-box;height:100%;padding-top:50px;overflow:auto;-webkit-overflow-scrolling:touch}.weui-search-bar{position:relative;padding:8px 10px;display:-webkit-box;display:-webkit-flex;display:flex;box-sizing:border-box;background-color:#efeff4;border-top:1rpx solid #d7d6dc;border-bottom:1rpx solid #d7d6dc}.weui-icon-search{margin-right:8px;font-size:inherit}.weui-icon-search_in-box{position:absolute;left:10px;top:7px}.weui-search-bar__text{display:inline-block;font-size:14px;vertical-align:middle}.weui-search-bar__form{position:relative;-webkit-box-flex:1;-webkit-flex:auto;flex:auto;border-radius:5px;background:#fff;border:1rpx solid #e6e6ea}.weui-search-bar__box{position:relative;padding-left:30px;padding-right:30px;width:100%;box-sizing:border-box;z-index:1}.weui-search-bar__input{height:28px;line-height:28px;font-size:14px}.weui-icon-clear{position:absolute;top:0;right:0;padding:7px 8px;font-size:0}.weui-search-bar__label{position:absolute;top:0;right:0;bottom:0;left:0;z-index:2;border-radius:3px;text-align:center;color:#9b9b9b;background:#fff;line-height:28px}.weui-search-bar__cancel-btn{margin-left:10px;line-height:28px;color:#09bb07;white-space:nowrap}
--------------------------------------------------------------------------------
/src/libs/cipher/wsha256.js:
--------------------------------------------------------------------------------
1 | /**
2 | * [js-sha256]{@link https://github.com/emn178/js-sha256}
3 | *
4 | * @version 0.9.0
5 | * @author Chen, Yi-Cyuan [emn178@gmail.com]
6 | * @copyright Chen, Yi-Cyuan 2014-2017
7 | * @license MIT
8 | */
9 | /*jslint bitwise: true */
10 | 'use strict';
11 |
12 | var ERROR = 'input is invalid type';
13 | var WINDOW = typeof window === 'object';
14 | var root = WINDOW ? window : {};
15 | if (root.JS_SHA256_NO_WINDOW) {
16 | WINDOW = false;
17 | }
18 | var WEB_WORKER = !WINDOW && typeof self === 'object';
19 | var NODE_JS = !root.JS_SHA256_NO_NODE_JS && typeof process === 'object' && process.versions && process.versions.node;
20 | if (NODE_JS) {
21 | root = global;
22 | } else if (WEB_WORKER) {
23 | root = self;
24 | }
25 | var COMMON_JS = !root.JS_SHA256_NO_COMMON_JS && typeof module === 'object' && module.exports;
26 | var AMD = typeof define === 'function' && define.amd;
27 | var ARRAY_BUFFER = !root.JS_SHA256_NO_ARRAY_BUFFER && typeof ArrayBuffer !== 'undefined';
28 | var HEX_CHARS = '0123456789abcdef'.split('');
29 | var EXTRA = [-2147483648, 8388608, 32768, 128];
30 | var SHIFT = [24, 16, 8, 0];
31 | var K = [
32 | 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
33 | 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
34 | 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
35 | 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
36 | 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
37 | 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
38 | 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
39 | 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
40 | ];
41 | var OUTPUT_TYPES = ['hex', 'array', 'digest', 'arrayBuffer'];
42 |
43 | var blocks = [];
44 |
45 | if (root.JS_SHA256_NO_NODE_JS || !Array.isArray) {
46 | Array.isArray = function (obj) {
47 | return Object.prototype.toString.call(obj) === '[object Array]';
48 | };
49 | }
50 |
51 | if (ARRAY_BUFFER && (root.JS_SHA256_NO_ARRAY_BUFFER_IS_VIEW || !ArrayBuffer.isView)) {
52 | ArrayBuffer.isView = function (obj) {
53 | return typeof obj === 'object' && obj.buffer && obj.buffer.constructor === ArrayBuffer;
54 | };
55 | }
56 |
57 | var createOutputMethod = function (outputType, is224) {
58 | return function (message) {
59 | return new Sha256(is224, true).update(message)[outputType]();
60 | };
61 | };
62 |
63 | var createMethod = function (is224) {
64 | var method = createOutputMethod('hex', is224);
65 | if (NODE_JS) {
66 | method = nodeWrap(method, is224);
67 | }
68 | method.create = function () {
69 | return new Sha256(is224);
70 | };
71 | method.update = function (message) {
72 | return method.create().update(message);
73 | };
74 | for (var i = 0; i < OUTPUT_TYPES.length; ++i) {
75 | var type = OUTPUT_TYPES[i];
76 | method[type] = createOutputMethod(type, is224);
77 | }
78 | return method;
79 | };
80 |
81 | var nodeWrap = function (method, is224) {
82 | var crypto = eval("require('crypto')");
83 | var Buffer = eval("require('buffer').Buffer");
84 | var algorithm = is224 ? 'sha224' : 'sha256';
85 | var nodeMethod = function (message) {
86 | if (typeof message === 'string') {
87 | return crypto.createHash(algorithm).update(message, 'utf8').digest('hex');
88 | } else {
89 | if (message === null || message === undefined) {
90 | throw new Error(ERROR);
91 | } else if (message.constructor === ArrayBuffer) {
92 | message = new Uint8Array(message);
93 | }
94 | }
95 | if (Array.isArray(message) || ArrayBuffer.isView(message) ||
96 | message.constructor === Buffer) {
97 | return crypto.createHash(algorithm).update(new Buffer(message)).digest('hex');
98 | } else {
99 | return method(message);
100 | }
101 | };
102 | return nodeMethod;
103 | };
104 |
105 | var createHmacOutputMethod = function (outputType, is224) {
106 | return function (key, message) {
107 | return new HmacSha256(key, is224, true).update(message)[outputType]();
108 | };
109 | };
110 |
111 | var createHmacMethod = function (is224) {
112 | var method = createHmacOutputMethod('hex', is224);
113 | method.create = function (key) {
114 | return new HmacSha256(key, is224);
115 | };
116 | method.update = function (key, message) {
117 | return method.create(key).update(message);
118 | };
119 | for (var i = 0; i < OUTPUT_TYPES.length; ++i) {
120 | var type = OUTPUT_TYPES[i];
121 | method[type] = createHmacOutputMethod(type, is224);
122 | }
123 | return method;
124 | };
125 |
126 | function Sha256(is224, sharedMemory) {
127 | if (sharedMemory) {
128 | blocks[0] = blocks[16] = blocks[1] = blocks[2] = blocks[3] =
129 | blocks[4] = blocks[5] = blocks[6] = blocks[7] =
130 | blocks[8] = blocks[9] = blocks[10] = blocks[11] =
131 | blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;
132 | this.blocks = blocks;
133 | } else {
134 | this.blocks = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
135 | }
136 |
137 | if (is224) {
138 | this.h0 = 0xc1059ed8;
139 | this.h1 = 0x367cd507;
140 | this.h2 = 0x3070dd17;
141 | this.h3 = 0xf70e5939;
142 | this.h4 = 0xffc00b31;
143 | this.h5 = 0x68581511;
144 | this.h6 = 0x64f98fa7;
145 | this.h7 = 0xbefa4fa4;
146 | } else { // 256
147 | this.h0 = 0x6a09e667;
148 | this.h1 = 0xbb67ae85;
149 | this.h2 = 0x3c6ef372;
150 | this.h3 = 0xa54ff53a;
151 | this.h4 = 0x510e527f;
152 | this.h5 = 0x9b05688c;
153 | this.h6 = 0x1f83d9ab;
154 | this.h7 = 0x5be0cd19;
155 | }
156 |
157 | this.block = this.start = this.bytes = this.hBytes = 0;
158 | this.finalized = this.hashed = false;
159 | this.first = true;
160 | this.is224 = is224;
161 | }
162 |
163 | Sha256.prototype.update = function (message) {
164 | if (this.finalized) {
165 | return;
166 | }
167 | var notString, type = typeof message;
168 | if (type !== 'string') {
169 | if (type === 'object') {
170 | if (message === null) {
171 | throw new Error(ERROR);
172 | } else if (ARRAY_BUFFER && message.constructor === ArrayBuffer) {
173 | message = new Uint8Array(message);
174 | } else if (!Array.isArray(message)) {
175 | if (!ARRAY_BUFFER || !ArrayBuffer.isView(message)) {
176 | throw new Error(ERROR);
177 | }
178 | }
179 | } else {
180 | throw new Error(ERROR);
181 | }
182 | notString = true;
183 | }
184 | var code, index = 0, i, length = message.length, blocks = this.blocks;
185 |
186 | while (index < length) {
187 | if (this.hashed) {
188 | this.hashed = false;
189 | blocks[0] = this.block;
190 | blocks[16] = blocks[1] = blocks[2] = blocks[3] =
191 | blocks[4] = blocks[5] = blocks[6] = blocks[7] =
192 | blocks[8] = blocks[9] = blocks[10] = blocks[11] =
193 | blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;
194 | }
195 |
196 | if (notString) {
197 | for (i = this.start; index < length && i < 64; ++index) {
198 | blocks[i >> 2] |= message[index] << SHIFT[i++ & 3];
199 | }
200 | } else {
201 | for (i = this.start; index < length && i < 64; ++index) {
202 | code = message.charCodeAt(index);
203 | if (code < 0x80) {
204 | blocks[i >> 2] |= code << SHIFT[i++ & 3];
205 | } else if (code < 0x800) {
206 | blocks[i >> 2] |= (0xc0 | (code >> 6)) << SHIFT[i++ & 3];
207 | blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
208 | } else if (code < 0xd800 || code >= 0xe000) {
209 | blocks[i >> 2] |= (0xe0 | (code >> 12)) << SHIFT[i++ & 3];
210 | blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3];
211 | blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
212 | } else {
213 | code = 0x10000 + (((code & 0x3ff) << 10) | (message.charCodeAt(++index) & 0x3ff));
214 | blocks[i >> 2] |= (0xf0 | (code >> 18)) << SHIFT[i++ & 3];
215 | blocks[i >> 2] |= (0x80 | ((code >> 12) & 0x3f)) << SHIFT[i++ & 3];
216 | blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3];
217 | blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
218 | }
219 | }
220 | }
221 |
222 | this.lastByteIndex = i;
223 | this.bytes += i - this.start;
224 | if (i >= 64) {
225 | this.block = blocks[16];
226 | this.start = i - 64;
227 | this.hash();
228 | this.hashed = true;
229 | } else {
230 | this.start = i;
231 | }
232 | }
233 | if (this.bytes > 4294967295) {
234 | this.hBytes += this.bytes / 4294967296 << 0;
235 | this.bytes = this.bytes % 4294967296;
236 | }
237 | return this;
238 | };
239 |
240 | Sha256.prototype.finalize = function () {
241 | if (this.finalized) {
242 | return;
243 | }
244 | this.finalized = true;
245 | var blocks = this.blocks, i = this.lastByteIndex;
246 | blocks[16] = this.block;
247 | blocks[i >> 2] |= EXTRA[i & 3];
248 | this.block = blocks[16];
249 | if (i >= 56) {
250 | if (!this.hashed) {
251 | this.hash();
252 | }
253 | blocks[0] = this.block;
254 | blocks[16] = blocks[1] = blocks[2] = blocks[3] =
255 | blocks[4] = blocks[5] = blocks[6] = blocks[7] =
256 | blocks[8] = blocks[9] = blocks[10] = blocks[11] =
257 | blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;
258 | }
259 | blocks[14] = this.hBytes << 3 | this.bytes >>> 29;
260 | blocks[15] = this.bytes << 3;
261 | this.hash();
262 | };
263 |
264 | Sha256.prototype.hash = function () {
265 | var a = this.h0, b = this.h1, c = this.h2, d = this.h3, e = this.h4, f = this.h5, g = this.h6,
266 | h = this.h7, blocks = this.blocks, j, s0, s1, maj, t1, t2, ch, ab, da, cd, bc;
267 |
268 | for (j = 16; j < 64; ++j) {
269 | // rightrotate
270 | t1 = blocks[j - 15];
271 | s0 = ((t1 >>> 7) | (t1 << 25)) ^ ((t1 >>> 18) | (t1 << 14)) ^ (t1 >>> 3);
272 | t1 = blocks[j - 2];
273 | s1 = ((t1 >>> 17) | (t1 << 15)) ^ ((t1 >>> 19) | (t1 << 13)) ^ (t1 >>> 10);
274 | blocks[j] = blocks[j - 16] + s0 + blocks[j - 7] + s1 << 0;
275 | }
276 |
277 | bc = b & c;
278 | for (j = 0; j < 64; j += 4) {
279 | if (this.first) {
280 | if (this.is224) {
281 | ab = 300032;
282 | t1 = blocks[0] - 1413257819;
283 | h = t1 - 150054599 << 0;
284 | d = t1 + 24177077 << 0;
285 | } else {
286 | ab = 704751109;
287 | t1 = blocks[0] - 210244248;
288 | h = t1 - 1521486534 << 0;
289 | d = t1 + 143694565 << 0;
290 | }
291 | this.first = false;
292 | } else {
293 | s0 = ((a >>> 2) | (a << 30)) ^ ((a >>> 13) | (a << 19)) ^ ((a >>> 22) | (a << 10));
294 | s1 = ((e >>> 6) | (e << 26)) ^ ((e >>> 11) | (e << 21)) ^ ((e >>> 25) | (e << 7));
295 | ab = a & b;
296 | maj = ab ^ (a & c) ^ bc;
297 | ch = (e & f) ^ (~e & g);
298 | t1 = h + s1 + ch + K[j] + blocks[j];
299 | t2 = s0 + maj;
300 | h = d + t1 << 0;
301 | d = t1 + t2 << 0;
302 | }
303 | s0 = ((d >>> 2) | (d << 30)) ^ ((d >>> 13) | (d << 19)) ^ ((d >>> 22) | (d << 10));
304 | s1 = ((h >>> 6) | (h << 26)) ^ ((h >>> 11) | (h << 21)) ^ ((h >>> 25) | (h << 7));
305 | da = d & a;
306 | maj = da ^ (d & b) ^ ab;
307 | ch = (h & e) ^ (~h & f);
308 | t1 = g + s1 + ch + K[j + 1] + blocks[j + 1];
309 | t2 = s0 + maj;
310 | g = c + t1 << 0;
311 | c = t1 + t2 << 0;
312 | s0 = ((c >>> 2) | (c << 30)) ^ ((c >>> 13) | (c << 19)) ^ ((c >>> 22) | (c << 10));
313 | s1 = ((g >>> 6) | (g << 26)) ^ ((g >>> 11) | (g << 21)) ^ ((g >>> 25) | (g << 7));
314 | cd = c & d;
315 | maj = cd ^ (c & a) ^ da;
316 | ch = (g & h) ^ (~g & e);
317 | t1 = f + s1 + ch + K[j + 2] + blocks[j + 2];
318 | t2 = s0 + maj;
319 | f = b + t1 << 0;
320 | b = t1 + t2 << 0;
321 | s0 = ((b >>> 2) | (b << 30)) ^ ((b >>> 13) | (b << 19)) ^ ((b >>> 22) | (b << 10));
322 | s1 = ((f >>> 6) | (f << 26)) ^ ((f >>> 11) | (f << 21)) ^ ((f >>> 25) | (f << 7));
323 | bc = b & c;
324 | maj = bc ^ (b & d) ^ cd;
325 | ch = (f & g) ^ (~f & h);
326 | t1 = e + s1 + ch + K[j + 3] + blocks[j + 3];
327 | t2 = s0 + maj;
328 | e = a + t1 << 0;
329 | a = t1 + t2 << 0;
330 | }
331 |
332 | this.h0 = this.h0 + a << 0;
333 | this.h1 = this.h1 + b << 0;
334 | this.h2 = this.h2 + c << 0;
335 | this.h3 = this.h3 + d << 0;
336 | this.h4 = this.h4 + e << 0;
337 | this.h5 = this.h5 + f << 0;
338 | this.h6 = this.h6 + g << 0;
339 | this.h7 = this.h7 + h << 0;
340 | };
341 |
342 | Sha256.prototype.hex = function () {
343 | this.finalize();
344 |
345 | var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3, h4 = this.h4, h5 = this.h5,
346 | h6 = this.h6, h7 = this.h7;
347 |
348 | var hex = HEX_CHARS[(h0 >> 28) & 0x0F] + HEX_CHARS[(h0 >> 24) & 0x0F] +
349 | HEX_CHARS[(h0 >> 20) & 0x0F] + HEX_CHARS[(h0 >> 16) & 0x0F] +
350 | HEX_CHARS[(h0 >> 12) & 0x0F] + HEX_CHARS[(h0 >> 8) & 0x0F] +
351 | HEX_CHARS[(h0 >> 4) & 0x0F] + HEX_CHARS[h0 & 0x0F] +
352 | HEX_CHARS[(h1 >> 28) & 0x0F] + HEX_CHARS[(h1 >> 24) & 0x0F] +
353 | HEX_CHARS[(h1 >> 20) & 0x0F] + HEX_CHARS[(h1 >> 16) & 0x0F] +
354 | HEX_CHARS[(h1 >> 12) & 0x0F] + HEX_CHARS[(h1 >> 8) & 0x0F] +
355 | HEX_CHARS[(h1 >> 4) & 0x0F] + HEX_CHARS[h1 & 0x0F] +
356 | HEX_CHARS[(h2 >> 28) & 0x0F] + HEX_CHARS[(h2 >> 24) & 0x0F] +
357 | HEX_CHARS[(h2 >> 20) & 0x0F] + HEX_CHARS[(h2 >> 16) & 0x0F] +
358 | HEX_CHARS[(h2 >> 12) & 0x0F] + HEX_CHARS[(h2 >> 8) & 0x0F] +
359 | HEX_CHARS[(h2 >> 4) & 0x0F] + HEX_CHARS[h2 & 0x0F] +
360 | HEX_CHARS[(h3 >> 28) & 0x0F] + HEX_CHARS[(h3 >> 24) & 0x0F] +
361 | HEX_CHARS[(h3 >> 20) & 0x0F] + HEX_CHARS[(h3 >> 16) & 0x0F] +
362 | HEX_CHARS[(h3 >> 12) & 0x0F] + HEX_CHARS[(h3 >> 8) & 0x0F] +
363 | HEX_CHARS[(h3 >> 4) & 0x0F] + HEX_CHARS[h3 & 0x0F] +
364 | HEX_CHARS[(h4 >> 28) & 0x0F] + HEX_CHARS[(h4 >> 24) & 0x0F] +
365 | HEX_CHARS[(h4 >> 20) & 0x0F] + HEX_CHARS[(h4 >> 16) & 0x0F] +
366 | HEX_CHARS[(h4 >> 12) & 0x0F] + HEX_CHARS[(h4 >> 8) & 0x0F] +
367 | HEX_CHARS[(h4 >> 4) & 0x0F] + HEX_CHARS[h4 & 0x0F] +
368 | HEX_CHARS[(h5 >> 28) & 0x0F] + HEX_CHARS[(h5 >> 24) & 0x0F] +
369 | HEX_CHARS[(h5 >> 20) & 0x0F] + HEX_CHARS[(h5 >> 16) & 0x0F] +
370 | HEX_CHARS[(h5 >> 12) & 0x0F] + HEX_CHARS[(h5 >> 8) & 0x0F] +
371 | HEX_CHARS[(h5 >> 4) & 0x0F] + HEX_CHARS[h5 & 0x0F] +
372 | HEX_CHARS[(h6 >> 28) & 0x0F] + HEX_CHARS[(h6 >> 24) & 0x0F] +
373 | HEX_CHARS[(h6 >> 20) & 0x0F] + HEX_CHARS[(h6 >> 16) & 0x0F] +
374 | HEX_CHARS[(h6 >> 12) & 0x0F] + HEX_CHARS[(h6 >> 8) & 0x0F] +
375 | HEX_CHARS[(h6 >> 4) & 0x0F] + HEX_CHARS[h6 & 0x0F];
376 | if (!this.is224) {
377 | hex += HEX_CHARS[(h7 >> 28) & 0x0F] + HEX_CHARS[(h7 >> 24) & 0x0F] +
378 | HEX_CHARS[(h7 >> 20) & 0x0F] + HEX_CHARS[(h7 >> 16) & 0x0F] +
379 | HEX_CHARS[(h7 >> 12) & 0x0F] + HEX_CHARS[(h7 >> 8) & 0x0F] +
380 | HEX_CHARS[(h7 >> 4) & 0x0F] + HEX_CHARS[h7 & 0x0F];
381 | }
382 | return hex;
383 | };
384 |
385 | Sha256.prototype.toString = Sha256.prototype.hex;
386 |
387 | Sha256.prototype.digest = function () {
388 | this.finalize();
389 |
390 | var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3, h4 = this.h4, h5 = this.h5,
391 | h6 = this.h6, h7 = this.h7;
392 |
393 | var arr = [
394 | (h0 >> 24) & 0xFF, (h0 >> 16) & 0xFF, (h0 >> 8) & 0xFF, h0 & 0xFF,
395 | (h1 >> 24) & 0xFF, (h1 >> 16) & 0xFF, (h1 >> 8) & 0xFF, h1 & 0xFF,
396 | (h2 >> 24) & 0xFF, (h2 >> 16) & 0xFF, (h2 >> 8) & 0xFF, h2 & 0xFF,
397 | (h3 >> 24) & 0xFF, (h3 >> 16) & 0xFF, (h3 >> 8) & 0xFF, h3 & 0xFF,
398 | (h4 >> 24) & 0xFF, (h4 >> 16) & 0xFF, (h4 >> 8) & 0xFF, h4 & 0xFF,
399 | (h5 >> 24) & 0xFF, (h5 >> 16) & 0xFF, (h5 >> 8) & 0xFF, h5 & 0xFF,
400 | (h6 >> 24) & 0xFF, (h6 >> 16) & 0xFF, (h6 >> 8) & 0xFF, h6 & 0xFF
401 | ];
402 | if (!this.is224) {
403 | arr.push((h7 >> 24) & 0xFF, (h7 >> 16) & 0xFF, (h7 >> 8) & 0xFF, h7 & 0xFF);
404 | }
405 | return arr;
406 | };
407 |
408 | Sha256.prototype.array = Sha256.prototype.digest;
409 |
410 | Sha256.prototype.arrayBuffer = function () {
411 | this.finalize();
412 |
413 | var buffer = new ArrayBuffer(this.is224 ? 28 : 32);
414 | var dataView = new DataView(buffer);
415 | dataView.setUint32(0, this.h0);
416 | dataView.setUint32(4, this.h1);
417 | dataView.setUint32(8, this.h2);
418 | dataView.setUint32(12, this.h3);
419 | dataView.setUint32(16, this.h4);
420 | dataView.setUint32(20, this.h5);
421 | dataView.setUint32(24, this.h6);
422 | if (!this.is224) {
423 | dataView.setUint32(28, this.h7);
424 | }
425 | return buffer;
426 | };
427 |
428 | function HmacSha256(key, is224, sharedMemory) {
429 | var i, type = typeof key;
430 | if (type === 'string') {
431 | var bytes = [], length = key.length, index = 0, code;
432 | for (i = 0; i < length; ++i) {
433 | code = key.charCodeAt(i);
434 | if (code < 0x80) {
435 | bytes[index++] = code;
436 | } else if (code < 0x800) {
437 | bytes[index++] = (0xc0 | (code >> 6));
438 | bytes[index++] = (0x80 | (code & 0x3f));
439 | } else if (code < 0xd800 || code >= 0xe000) {
440 | bytes[index++] = (0xe0 | (code >> 12));
441 | bytes[index++] = (0x80 | ((code >> 6) & 0x3f));
442 | bytes[index++] = (0x80 | (code & 0x3f));
443 | } else {
444 | code = 0x10000 + (((code & 0x3ff) << 10) | (key.charCodeAt(++i) & 0x3ff));
445 | bytes[index++] = (0xf0 | (code >> 18));
446 | bytes[index++] = (0x80 | ((code >> 12) & 0x3f));
447 | bytes[index++] = (0x80 | ((code >> 6) & 0x3f));
448 | bytes[index++] = (0x80 | (code & 0x3f));
449 | }
450 | }
451 | key = bytes;
452 | } else {
453 | if (type === 'object') {
454 | if (key === null) {
455 | throw new Error(ERROR);
456 | } else if (ARRAY_BUFFER && key.constructor === ArrayBuffer) {
457 | key = new Uint8Array(key);
458 | } else if (!Array.isArray(key)) {
459 | if (!ARRAY_BUFFER || !ArrayBuffer.isView(key)) {
460 | throw new Error(ERROR);
461 | }
462 | }
463 | } else {
464 | throw new Error(ERROR);
465 | }
466 | }
467 |
468 | if (key.length > 64) {
469 | key = (new Sha256(is224, true)).update(key).array();
470 | }
471 |
472 | var oKeyPad = [], iKeyPad = [];
473 | for (i = 0; i < 64; ++i) {
474 | var b = key[i] || 0;
475 | oKeyPad[i] = 0x5c ^ b;
476 | iKeyPad[i] = 0x36 ^ b;
477 | }
478 |
479 | Sha256.call(this, is224, sharedMemory);
480 |
481 | this.update(iKeyPad);
482 | this.oKeyPad = oKeyPad;
483 | this.inner = true;
484 | this.sharedMemory = sharedMemory;
485 | }
486 | HmacSha256.prototype = new Sha256();
487 |
488 | HmacSha256.prototype.finalize = function () {
489 | Sha256.prototype.finalize.call(this);
490 | if (this.inner) {
491 | this.inner = false;
492 | var innerHash = this.array();
493 | Sha256.call(this, this.is224, this.sharedMemory);
494 | this.update(this.oKeyPad);
495 | this.update(innerHash);
496 | Sha256.prototype.finalize.call(this);
497 | }
498 | };
499 |
500 | var exports = createMethod();
501 | exports.sha256 = exports;
502 | exports.sha224 = createMethod(true);
503 | exports.sha256.hmac = createHmacMethod();
504 | exports.sha224.hmac = createHmacMethod(true);
505 |
506 |
507 |
508 |
509 | /**
510 | * exports
511 | */
512 | module.exports = exports;
--------------------------------------------------------------------------------
/src/libs/cipher/waes.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | function checkInt( value )
4 | {
5 | return ( parseInt( value ) === value );
6 | }
7 |
8 |
9 | function checkInts( arrayish )
10 | {
11 | if ( ! checkInt( arrayish.length ) )
12 | {
13 | return false;
14 | }
15 |
16 | for ( var i = 0; i < arrayish.length; i++ )
17 | {
18 | if ( ! checkInt( arrayish[i]) || arrayish[i] < 0 || arrayish[i] > 255)
19 | {
20 | return false;
21 | }
22 | }
23 |
24 | return true;
25 | }
26 |
27 |
28 | function coerceArray( arg, copy )
29 | {
30 |
31 | // ArrayBuffer view
32 | if (arg.buffer && ArrayBuffer.isView(arg) && arg.name === 'Uint8Array') {
33 |
34 | if (copy) {
35 | if (arg.slice) {
36 | arg = arg.slice();
37 | } else {
38 | arg = Array.prototype.slice.call(arg);
39 | }
40 | }
41 |
42 | return arg;
43 | }
44 |
45 | // It's an array; check it is a valid representation of a byte
46 | if (Array.isArray(arg)) {
47 | if (!checkInts(arg)) {
48 | throw new Error('Array contains invalid value: ' + arg);
49 | }
50 |
51 | return new Uint8Array(arg);
52 | }
53 |
54 | // Something else, but behaves like an array (maybe a Buffer? Arguments?)
55 | if (checkInt(arg.length) && checkInts(arg)) {
56 | return new Uint8Array(arg);
57 | }
58 |
59 | throw new Error('unsupported array-like object');
60 | }
61 |
62 | function createArray(length) {
63 | return new Uint8Array(length);
64 | }
65 |
66 | function copyArray(sourceArray, targetArray, targetStart, sourceStart, sourceEnd) {
67 | if (sourceStart != null || sourceEnd != null) {
68 | if (sourceArray.slice) {
69 | sourceArray = sourceArray.slice(sourceStart, sourceEnd);
70 | } else {
71 | sourceArray = Array.prototype.slice.call(sourceArray, sourceStart, sourceEnd);
72 | }
73 | }
74 | targetArray.set(sourceArray, targetStart);
75 | }
76 |
77 |
78 |
79 | var convertUtf8 = (function () {
80 | function toBytes(text) {
81 | var result = [], i = 0;
82 | text = encodeURI(text);
83 | while (i < text.length) {
84 | var c = text.charCodeAt(i++);
85 |
86 | // if it is a % sign, encode the following 2 bytes as a hex value
87 | if (c === 37) {
88 | result.push(parseInt(text.substr(i, 2), 16))
89 | i += 2;
90 |
91 | // otherwise, just the actual byte
92 | } else {
93 | result.push(c)
94 | }
95 | }
96 |
97 | return coerceArray(result);
98 | }
99 |
100 | function fromBytes(bytes) {
101 | var result = [], i = 0;
102 |
103 | while (i < bytes.length) {
104 | var c = bytes[i];
105 |
106 | if (c < 128) {
107 | result.push(String.fromCharCode(c));
108 | i++;
109 | } else if (c > 191 && c < 224) {
110 | result.push(String.fromCharCode(((c & 0x1f) << 6) | (bytes[i + 1] & 0x3f)));
111 | i += 2;
112 | } else {
113 | result.push(String.fromCharCode(((c & 0x0f) << 12) | ((bytes[i + 1] & 0x3f) << 6) | (bytes[i + 2] & 0x3f)));
114 | i += 3;
115 | }
116 | }
117 |
118 | return result.join('');
119 | }
120 |
121 | return {
122 | toBytes: toBytes,
123 | fromBytes: fromBytes,
124 | }
125 | })();
126 |
127 | var convertHex = (function () {
128 | function toBytes(text) {
129 | var result = [];
130 | for (var i = 0; i < text.length; i += 2) {
131 | result.push(parseInt(text.substr(i, 2), 16));
132 | }
133 |
134 | return result;
135 | }
136 |
137 | // http://ixti.net/development/javascript/2011/11/11/base64-encodedecode-of-utf8-in-browser-with-js.html
138 | var Hex = '0123456789abcdef';
139 |
140 | function fromBytes(bytes) {
141 | var result = [];
142 | for (var i = 0; i < bytes.length; i++) {
143 | var v = bytes[i];
144 | result.push(Hex[(v & 0xf0) >> 4] + Hex[v & 0x0f]);
145 | }
146 | return result.join('');
147 | }
148 |
149 | return {
150 | toBytes: toBytes,
151 | fromBytes: fromBytes,
152 | }
153 | })();
154 |
155 |
156 | // Number of rounds by keysize
157 | var numberOfRounds = { 16: 10, 24: 12, 32: 14 }
158 |
159 | // Round constant words
160 | var rcon = [0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91];
161 |
162 | // S-box and Inverse S-box (S is for Substitution)
163 | var S = [0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16];
164 | var Si = [0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d];
165 |
166 | // Transformations for encryption
167 | var T1 = [0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d, 0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554, 0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d, 0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a, 0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87, 0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b, 0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea, 0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b, 0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a, 0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f, 0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108, 0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f, 0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e, 0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5, 0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d, 0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f, 0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e, 0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb, 0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce, 0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497, 0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c, 0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed, 0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b, 0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a, 0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16, 0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594, 0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81, 0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3, 0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a, 0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504, 0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163, 0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d, 0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f, 0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739, 0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47, 0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395, 0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f, 0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883, 0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c, 0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76, 0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e, 0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4, 0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6, 0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b, 0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7, 0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0, 0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25, 0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818, 0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72, 0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651, 0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21, 0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85, 0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa, 0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12, 0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0, 0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9, 0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133, 0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7, 0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920, 0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a, 0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17, 0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8, 0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11, 0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a];
168 | var T2 = [0xa5c66363, 0x84f87c7c, 0x99ee7777, 0x8df67b7b, 0x0dfff2f2, 0xbdd66b6b, 0xb1de6f6f, 0x5491c5c5, 0x50603030, 0x03020101, 0xa9ce6767, 0x7d562b2b, 0x19e7fefe, 0x62b5d7d7, 0xe64dabab, 0x9aec7676, 0x458fcaca, 0x9d1f8282, 0x4089c9c9, 0x87fa7d7d, 0x15effafa, 0xebb25959, 0xc98e4747, 0x0bfbf0f0, 0xec41adad, 0x67b3d4d4, 0xfd5fa2a2, 0xea45afaf, 0xbf239c9c, 0xf753a4a4, 0x96e47272, 0x5b9bc0c0, 0xc275b7b7, 0x1ce1fdfd, 0xae3d9393, 0x6a4c2626, 0x5a6c3636, 0x417e3f3f, 0x02f5f7f7, 0x4f83cccc, 0x5c683434, 0xf451a5a5, 0x34d1e5e5, 0x08f9f1f1, 0x93e27171, 0x73abd8d8, 0x53623131, 0x3f2a1515, 0x0c080404, 0x5295c7c7, 0x65462323, 0x5e9dc3c3, 0x28301818, 0xa1379696, 0x0f0a0505, 0xb52f9a9a, 0x090e0707, 0x36241212, 0x9b1b8080, 0x3ddfe2e2, 0x26cdebeb, 0x694e2727, 0xcd7fb2b2, 0x9fea7575, 0x1b120909, 0x9e1d8383, 0x74582c2c, 0x2e341a1a, 0x2d361b1b, 0xb2dc6e6e, 0xeeb45a5a, 0xfb5ba0a0, 0xf6a45252, 0x4d763b3b, 0x61b7d6d6, 0xce7db3b3, 0x7b522929, 0x3edde3e3, 0x715e2f2f, 0x97138484, 0xf5a65353, 0x68b9d1d1, 0x00000000, 0x2cc1eded, 0x60402020, 0x1fe3fcfc, 0xc879b1b1, 0xedb65b5b, 0xbed46a6a, 0x468dcbcb, 0xd967bebe, 0x4b723939, 0xde944a4a, 0xd4984c4c, 0xe8b05858, 0x4a85cfcf, 0x6bbbd0d0, 0x2ac5efef, 0xe54faaaa, 0x16edfbfb, 0xc5864343, 0xd79a4d4d, 0x55663333, 0x94118585, 0xcf8a4545, 0x10e9f9f9, 0x06040202, 0x81fe7f7f, 0xf0a05050, 0x44783c3c, 0xba259f9f, 0xe34ba8a8, 0xf3a25151, 0xfe5da3a3, 0xc0804040, 0x8a058f8f, 0xad3f9292, 0xbc219d9d, 0x48703838, 0x04f1f5f5, 0xdf63bcbc, 0xc177b6b6, 0x75afdada, 0x63422121, 0x30201010, 0x1ae5ffff, 0x0efdf3f3, 0x6dbfd2d2, 0x4c81cdcd, 0x14180c0c, 0x35261313, 0x2fc3ecec, 0xe1be5f5f, 0xa2359797, 0xcc884444, 0x392e1717, 0x5793c4c4, 0xf255a7a7, 0x82fc7e7e, 0x477a3d3d, 0xacc86464, 0xe7ba5d5d, 0x2b321919, 0x95e67373, 0xa0c06060, 0x98198181, 0xd19e4f4f, 0x7fa3dcdc, 0x66442222, 0x7e542a2a, 0xab3b9090, 0x830b8888, 0xca8c4646, 0x29c7eeee, 0xd36bb8b8, 0x3c281414, 0x79a7dede, 0xe2bc5e5e, 0x1d160b0b, 0x76addbdb, 0x3bdbe0e0, 0x56643232, 0x4e743a3a, 0x1e140a0a, 0xdb924949, 0x0a0c0606, 0x6c482424, 0xe4b85c5c, 0x5d9fc2c2, 0x6ebdd3d3, 0xef43acac, 0xa6c46262, 0xa8399191, 0xa4319595, 0x37d3e4e4, 0x8bf27979, 0x32d5e7e7, 0x438bc8c8, 0x596e3737, 0xb7da6d6d, 0x8c018d8d, 0x64b1d5d5, 0xd29c4e4e, 0xe049a9a9, 0xb4d86c6c, 0xfaac5656, 0x07f3f4f4, 0x25cfeaea, 0xafca6565, 0x8ef47a7a, 0xe947aeae, 0x18100808, 0xd56fbaba, 0x88f07878, 0x6f4a2525, 0x725c2e2e, 0x24381c1c, 0xf157a6a6, 0xc773b4b4, 0x5197c6c6, 0x23cbe8e8, 0x7ca1dddd, 0x9ce87474, 0x213e1f1f, 0xdd964b4b, 0xdc61bdbd, 0x860d8b8b, 0x850f8a8a, 0x90e07070, 0x427c3e3e, 0xc471b5b5, 0xaacc6666, 0xd8904848, 0x05060303, 0x01f7f6f6, 0x121c0e0e, 0xa3c26161, 0x5f6a3535, 0xf9ae5757, 0xd069b9b9, 0x91178686, 0x5899c1c1, 0x273a1d1d, 0xb9279e9e, 0x38d9e1e1, 0x13ebf8f8, 0xb32b9898, 0x33221111, 0xbbd26969, 0x70a9d9d9, 0x89078e8e, 0xa7339494, 0xb62d9b9b, 0x223c1e1e, 0x92158787, 0x20c9e9e9, 0x4987cece, 0xffaa5555, 0x78502828, 0x7aa5dfdf, 0x8f038c8c, 0xf859a1a1, 0x80098989, 0x171a0d0d, 0xda65bfbf, 0x31d7e6e6, 0xc6844242, 0xb8d06868, 0xc3824141, 0xb0299999, 0x775a2d2d, 0x111e0f0f, 0xcb7bb0b0, 0xfca85454, 0xd66dbbbb, 0x3a2c1616];
169 | var T3 = [0x63a5c663, 0x7c84f87c, 0x7799ee77, 0x7b8df67b, 0xf20dfff2, 0x6bbdd66b, 0x6fb1de6f, 0xc55491c5, 0x30506030, 0x01030201, 0x67a9ce67, 0x2b7d562b, 0xfe19e7fe, 0xd762b5d7, 0xabe64dab, 0x769aec76, 0xca458fca, 0x829d1f82, 0xc94089c9, 0x7d87fa7d, 0xfa15effa, 0x59ebb259, 0x47c98e47, 0xf00bfbf0, 0xadec41ad, 0xd467b3d4, 0xa2fd5fa2, 0xafea45af, 0x9cbf239c, 0xa4f753a4, 0x7296e472, 0xc05b9bc0, 0xb7c275b7, 0xfd1ce1fd, 0x93ae3d93, 0x266a4c26, 0x365a6c36, 0x3f417e3f, 0xf702f5f7, 0xcc4f83cc, 0x345c6834, 0xa5f451a5, 0xe534d1e5, 0xf108f9f1, 0x7193e271, 0xd873abd8, 0x31536231, 0x153f2a15, 0x040c0804, 0xc75295c7, 0x23654623, 0xc35e9dc3, 0x18283018, 0x96a13796, 0x050f0a05, 0x9ab52f9a, 0x07090e07, 0x12362412, 0x809b1b80, 0xe23ddfe2, 0xeb26cdeb, 0x27694e27, 0xb2cd7fb2, 0x759fea75, 0x091b1209, 0x839e1d83, 0x2c74582c, 0x1a2e341a, 0x1b2d361b, 0x6eb2dc6e, 0x5aeeb45a, 0xa0fb5ba0, 0x52f6a452, 0x3b4d763b, 0xd661b7d6, 0xb3ce7db3, 0x297b5229, 0xe33edde3, 0x2f715e2f, 0x84971384, 0x53f5a653, 0xd168b9d1, 0x00000000, 0xed2cc1ed, 0x20604020, 0xfc1fe3fc, 0xb1c879b1, 0x5bedb65b, 0x6abed46a, 0xcb468dcb, 0xbed967be, 0x394b7239, 0x4ade944a, 0x4cd4984c, 0x58e8b058, 0xcf4a85cf, 0xd06bbbd0, 0xef2ac5ef, 0xaae54faa, 0xfb16edfb, 0x43c58643, 0x4dd79a4d, 0x33556633, 0x85941185, 0x45cf8a45, 0xf910e9f9, 0x02060402, 0x7f81fe7f, 0x50f0a050, 0x3c44783c, 0x9fba259f, 0xa8e34ba8, 0x51f3a251, 0xa3fe5da3, 0x40c08040, 0x8f8a058f, 0x92ad3f92, 0x9dbc219d, 0x38487038, 0xf504f1f5, 0xbcdf63bc, 0xb6c177b6, 0xda75afda, 0x21634221, 0x10302010, 0xff1ae5ff, 0xf30efdf3, 0xd26dbfd2, 0xcd4c81cd, 0x0c14180c, 0x13352613, 0xec2fc3ec, 0x5fe1be5f, 0x97a23597, 0x44cc8844, 0x17392e17, 0xc45793c4, 0xa7f255a7, 0x7e82fc7e, 0x3d477a3d, 0x64acc864, 0x5de7ba5d, 0x192b3219, 0x7395e673, 0x60a0c060, 0x81981981, 0x4fd19e4f, 0xdc7fa3dc, 0x22664422, 0x2a7e542a, 0x90ab3b90, 0x88830b88, 0x46ca8c46, 0xee29c7ee, 0xb8d36bb8, 0x143c2814, 0xde79a7de, 0x5ee2bc5e, 0x0b1d160b, 0xdb76addb, 0xe03bdbe0, 0x32566432, 0x3a4e743a, 0x0a1e140a, 0x49db9249, 0x060a0c06, 0x246c4824, 0x5ce4b85c, 0xc25d9fc2, 0xd36ebdd3, 0xacef43ac, 0x62a6c462, 0x91a83991, 0x95a43195, 0xe437d3e4, 0x798bf279, 0xe732d5e7, 0xc8438bc8, 0x37596e37, 0x6db7da6d, 0x8d8c018d, 0xd564b1d5, 0x4ed29c4e, 0xa9e049a9, 0x6cb4d86c, 0x56faac56, 0xf407f3f4, 0xea25cfea, 0x65afca65, 0x7a8ef47a, 0xaee947ae, 0x08181008, 0xbad56fba, 0x7888f078, 0x256f4a25, 0x2e725c2e, 0x1c24381c, 0xa6f157a6, 0xb4c773b4, 0xc65197c6, 0xe823cbe8, 0xdd7ca1dd, 0x749ce874, 0x1f213e1f, 0x4bdd964b, 0xbddc61bd, 0x8b860d8b, 0x8a850f8a, 0x7090e070, 0x3e427c3e, 0xb5c471b5, 0x66aacc66, 0x48d89048, 0x03050603, 0xf601f7f6, 0x0e121c0e, 0x61a3c261, 0x355f6a35, 0x57f9ae57, 0xb9d069b9, 0x86911786, 0xc15899c1, 0x1d273a1d, 0x9eb9279e, 0xe138d9e1, 0xf813ebf8, 0x98b32b98, 0x11332211, 0x69bbd269, 0xd970a9d9, 0x8e89078e, 0x94a73394, 0x9bb62d9b, 0x1e223c1e, 0x87921587, 0xe920c9e9, 0xce4987ce, 0x55ffaa55, 0x28785028, 0xdf7aa5df, 0x8c8f038c, 0xa1f859a1, 0x89800989, 0x0d171a0d, 0xbfda65bf, 0xe631d7e6, 0x42c68442, 0x68b8d068, 0x41c38241, 0x99b02999, 0x2d775a2d, 0x0f111e0f, 0xb0cb7bb0, 0x54fca854, 0xbbd66dbb, 0x163a2c16];
170 | var T4 = [0x6363a5c6, 0x7c7c84f8, 0x777799ee, 0x7b7b8df6, 0xf2f20dff, 0x6b6bbdd6, 0x6f6fb1de, 0xc5c55491, 0x30305060, 0x01010302, 0x6767a9ce, 0x2b2b7d56, 0xfefe19e7, 0xd7d762b5, 0xababe64d, 0x76769aec, 0xcaca458f, 0x82829d1f, 0xc9c94089, 0x7d7d87fa, 0xfafa15ef, 0x5959ebb2, 0x4747c98e, 0xf0f00bfb, 0xadadec41, 0xd4d467b3, 0xa2a2fd5f, 0xafafea45, 0x9c9cbf23, 0xa4a4f753, 0x727296e4, 0xc0c05b9b, 0xb7b7c275, 0xfdfd1ce1, 0x9393ae3d, 0x26266a4c, 0x36365a6c, 0x3f3f417e, 0xf7f702f5, 0xcccc4f83, 0x34345c68, 0xa5a5f451, 0xe5e534d1, 0xf1f108f9, 0x717193e2, 0xd8d873ab, 0x31315362, 0x15153f2a, 0x04040c08, 0xc7c75295, 0x23236546, 0xc3c35e9d, 0x18182830, 0x9696a137, 0x05050f0a, 0x9a9ab52f, 0x0707090e, 0x12123624, 0x80809b1b, 0xe2e23ddf, 0xebeb26cd, 0x2727694e, 0xb2b2cd7f, 0x75759fea, 0x09091b12, 0x83839e1d, 0x2c2c7458, 0x1a1a2e34, 0x1b1b2d36, 0x6e6eb2dc, 0x5a5aeeb4, 0xa0a0fb5b, 0x5252f6a4, 0x3b3b4d76, 0xd6d661b7, 0xb3b3ce7d, 0x29297b52, 0xe3e33edd, 0x2f2f715e, 0x84849713, 0x5353f5a6, 0xd1d168b9, 0x00000000, 0xeded2cc1, 0x20206040, 0xfcfc1fe3, 0xb1b1c879, 0x5b5bedb6, 0x6a6abed4, 0xcbcb468d, 0xbebed967, 0x39394b72, 0x4a4ade94, 0x4c4cd498, 0x5858e8b0, 0xcfcf4a85, 0xd0d06bbb, 0xefef2ac5, 0xaaaae54f, 0xfbfb16ed, 0x4343c586, 0x4d4dd79a, 0x33335566, 0x85859411, 0x4545cf8a, 0xf9f910e9, 0x02020604, 0x7f7f81fe, 0x5050f0a0, 0x3c3c4478, 0x9f9fba25, 0xa8a8e34b, 0x5151f3a2, 0xa3a3fe5d, 0x4040c080, 0x8f8f8a05, 0x9292ad3f, 0x9d9dbc21, 0x38384870, 0xf5f504f1, 0xbcbcdf63, 0xb6b6c177, 0xdada75af, 0x21216342, 0x10103020, 0xffff1ae5, 0xf3f30efd, 0xd2d26dbf, 0xcdcd4c81, 0x0c0c1418, 0x13133526, 0xecec2fc3, 0x5f5fe1be, 0x9797a235, 0x4444cc88, 0x1717392e, 0xc4c45793, 0xa7a7f255, 0x7e7e82fc, 0x3d3d477a, 0x6464acc8, 0x5d5de7ba, 0x19192b32, 0x737395e6, 0x6060a0c0, 0x81819819, 0x4f4fd19e, 0xdcdc7fa3, 0x22226644, 0x2a2a7e54, 0x9090ab3b, 0x8888830b, 0x4646ca8c, 0xeeee29c7, 0xb8b8d36b, 0x14143c28, 0xdede79a7, 0x5e5ee2bc, 0x0b0b1d16, 0xdbdb76ad, 0xe0e03bdb, 0x32325664, 0x3a3a4e74, 0x0a0a1e14, 0x4949db92, 0x06060a0c, 0x24246c48, 0x5c5ce4b8, 0xc2c25d9f, 0xd3d36ebd, 0xacacef43, 0x6262a6c4, 0x9191a839, 0x9595a431, 0xe4e437d3, 0x79798bf2, 0xe7e732d5, 0xc8c8438b, 0x3737596e, 0x6d6db7da, 0x8d8d8c01, 0xd5d564b1, 0x4e4ed29c, 0xa9a9e049, 0x6c6cb4d8, 0x5656faac, 0xf4f407f3, 0xeaea25cf, 0x6565afca, 0x7a7a8ef4, 0xaeaee947, 0x08081810, 0xbabad56f, 0x787888f0, 0x25256f4a, 0x2e2e725c, 0x1c1c2438, 0xa6a6f157, 0xb4b4c773, 0xc6c65197, 0xe8e823cb, 0xdddd7ca1, 0x74749ce8, 0x1f1f213e, 0x4b4bdd96, 0xbdbddc61, 0x8b8b860d, 0x8a8a850f, 0x707090e0, 0x3e3e427c, 0xb5b5c471, 0x6666aacc, 0x4848d890, 0x03030506, 0xf6f601f7, 0x0e0e121c, 0x6161a3c2, 0x35355f6a, 0x5757f9ae, 0xb9b9d069, 0x86869117, 0xc1c15899, 0x1d1d273a, 0x9e9eb927, 0xe1e138d9, 0xf8f813eb, 0x9898b32b, 0x11113322, 0x6969bbd2, 0xd9d970a9, 0x8e8e8907, 0x9494a733, 0x9b9bb62d, 0x1e1e223c, 0x87879215, 0xe9e920c9, 0xcece4987, 0x5555ffaa, 0x28287850, 0xdfdf7aa5, 0x8c8c8f03, 0xa1a1f859, 0x89898009, 0x0d0d171a, 0xbfbfda65, 0xe6e631d7, 0x4242c684, 0x6868b8d0, 0x4141c382, 0x9999b029, 0x2d2d775a, 0x0f0f111e, 0xb0b0cb7b, 0x5454fca8, 0xbbbbd66d, 0x16163a2c];
171 |
172 | // Transformations for decryption
173 | var T5 = [0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96, 0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393, 0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25, 0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f, 0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1, 0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6, 0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da, 0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844, 0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd, 0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4, 0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45, 0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94, 0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7, 0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a, 0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5, 0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c, 0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1, 0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a, 0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75, 0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051, 0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46, 0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff, 0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77, 0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb, 0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000, 0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e, 0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927, 0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a, 0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e, 0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16, 0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d, 0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8, 0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd, 0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34, 0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163, 0xd731dcca, 0x42638510, 0x13972240, 0x84c61120, 0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d, 0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0, 0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422, 0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef, 0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36, 0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4, 0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662, 0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5, 0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3, 0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b, 0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8, 0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6, 0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6, 0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0, 0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815, 0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f, 0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df, 0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f, 0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e, 0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713, 0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89, 0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c, 0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf, 0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86, 0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f, 0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541, 0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190, 0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742];
174 | var T6 = [0x5051f4a7, 0x537e4165, 0xc31a17a4, 0x963a275e, 0xcb3bab6b, 0xf11f9d45, 0xabacfa58, 0x934be303, 0x552030fa, 0xf6ad766d, 0x9188cc76, 0x25f5024c, 0xfc4fe5d7, 0xd7c52acb, 0x80263544, 0x8fb562a3, 0x49deb15a, 0x6725ba1b, 0x9845ea0e, 0xe15dfec0, 0x02c32f75, 0x12814cf0, 0xa38d4697, 0xc66bd3f9, 0xe7038f5f, 0x9515929c, 0xebbf6d7a, 0xda955259, 0x2dd4be83, 0xd3587421, 0x2949e069, 0x448ec9c8, 0x6a75c289, 0x78f48e79, 0x6b99583e, 0xdd27b971, 0xb6bee14f, 0x17f088ad, 0x66c920ac, 0xb47dce3a, 0x1863df4a, 0x82e51a31, 0x60975133, 0x4562537f, 0xe0b16477, 0x84bb6bae, 0x1cfe81a0, 0x94f9082b, 0x58704868, 0x198f45fd, 0x8794de6c, 0xb7527bf8, 0x23ab73d3, 0xe2724b02, 0x57e31f8f, 0x2a6655ab, 0x07b2eb28, 0x032fb5c2, 0x9a86c57b, 0xa5d33708, 0xf2302887, 0xb223bfa5, 0xba02036a, 0x5ced1682, 0x2b8acf1c, 0x92a779b4, 0xf0f307f2, 0xa14e69e2, 0xcd65daf4, 0xd50605be, 0x1fd13462, 0x8ac4a6fe, 0x9d342e53, 0xa0a2f355, 0x32058ae1, 0x75a4f6eb, 0x390b83ec, 0xaa4060ef, 0x065e719f, 0x51bd6e10, 0xf93e218a, 0x3d96dd06, 0xaedd3e05, 0x464de6bd, 0xb591548d, 0x0571c45d, 0x6f0406d4, 0xff605015, 0x241998fb, 0x97d6bde9, 0xcc894043, 0x7767d99e, 0xbdb0e842, 0x8807898b, 0x38e7195b, 0xdb79c8ee, 0x47a17c0a, 0xe97c420f, 0xc9f8841e, 0x00000000, 0x83098086, 0x48322bed, 0xac1e1170, 0x4e6c5a72, 0xfbfd0eff, 0x560f8538, 0x1e3daed5, 0x27362d39, 0x640a0fd9, 0x21685ca6, 0xd19b5b54, 0x3a24362e, 0xb10c0a67, 0x0f9357e7, 0xd2b4ee96, 0x9e1b9b91, 0x4f80c0c5, 0xa261dc20, 0x695a774b, 0x161c121a, 0x0ae293ba, 0xe5c0a02a, 0x433c22e0, 0x1d121b17, 0x0b0e090d, 0xadf28bc7, 0xb92db6a8, 0xc8141ea9, 0x8557f119, 0x4caf7507, 0xbbee99dd, 0xfda37f60, 0x9ff70126, 0xbc5c72f5, 0xc544663b, 0x345bfb7e, 0x768b4329, 0xdccb23c6, 0x68b6edfc, 0x63b8e4f1, 0xcad731dc, 0x10426385, 0x40139722, 0x2084c611, 0x7d854a24, 0xf8d2bb3d, 0x11aef932, 0x6dc729a1, 0x4b1d9e2f, 0xf3dcb230, 0xec0d8652, 0xd077c1e3, 0x6c2bb316, 0x99a970b9, 0xfa119448, 0x2247e964, 0xc4a8fc8c, 0x1aa0f03f, 0xd8567d2c, 0xef223390, 0xc787494e, 0xc1d938d1, 0xfe8ccaa2, 0x3698d40b, 0xcfa6f581, 0x28a57ade, 0x26dab78e, 0xa43fadbf, 0xe42c3a9d, 0x0d507892, 0x9b6a5fcc, 0x62547e46, 0xc2f68d13, 0xe890d8b8, 0x5e2e39f7, 0xf582c3af, 0xbe9f5d80, 0x7c69d093, 0xa96fd52d, 0xb3cf2512, 0x3bc8ac99, 0xa710187d, 0x6ee89c63, 0x7bdb3bbb, 0x09cd2678, 0xf46e5918, 0x01ec9ab7, 0xa8834f9a, 0x65e6956e, 0x7eaaffe6, 0x0821bccf, 0xe6ef15e8, 0xd9bae79b, 0xce4a6f36, 0xd4ea9f09, 0xd629b07c, 0xaf31a4b2, 0x312a3f23, 0x30c6a594, 0xc035a266, 0x37744ebc, 0xa6fc82ca, 0xb0e090d0, 0x1533a7d8, 0x4af10498, 0xf741ecda, 0x0e7fcd50, 0x2f1791f6, 0x8d764dd6, 0x4d43efb0, 0x54ccaa4d, 0xdfe49604, 0xe39ed1b5, 0x1b4c6a88, 0xb8c12c1f, 0x7f466551, 0x049d5eea, 0x5d018c35, 0x73fa8774, 0x2efb0b41, 0x5ab3671d, 0x5292dbd2, 0x33e91056, 0x136dd647, 0x8c9ad761, 0x7a37a10c, 0x8e59f814, 0x89eb133c, 0xeecea927, 0x35b761c9, 0xede11ce5, 0x3c7a47b1, 0x599cd2df, 0x3f55f273, 0x791814ce, 0xbf73c737, 0xea53f7cd, 0x5b5ffdaa, 0x14df3d6f, 0x867844db, 0x81caaff3, 0x3eb968c4, 0x2c382434, 0x5fc2a340, 0x72161dc3, 0x0cbce225, 0x8b283c49, 0x41ff0d95, 0x7139a801, 0xde080cb3, 0x9cd8b4e4, 0x906456c1, 0x617bcb84, 0x70d532b6, 0x74486c5c, 0x42d0b857];
175 | var T7 = [0xa75051f4, 0x65537e41, 0xa4c31a17, 0x5e963a27, 0x6bcb3bab, 0x45f11f9d, 0x58abacfa, 0x03934be3, 0xfa552030, 0x6df6ad76, 0x769188cc, 0x4c25f502, 0xd7fc4fe5, 0xcbd7c52a, 0x44802635, 0xa38fb562, 0x5a49deb1, 0x1b6725ba, 0x0e9845ea, 0xc0e15dfe, 0x7502c32f, 0xf012814c, 0x97a38d46, 0xf9c66bd3, 0x5fe7038f, 0x9c951592, 0x7aebbf6d, 0x59da9552, 0x832dd4be, 0x21d35874, 0x692949e0, 0xc8448ec9, 0x896a75c2, 0x7978f48e, 0x3e6b9958, 0x71dd27b9, 0x4fb6bee1, 0xad17f088, 0xac66c920, 0x3ab47dce, 0x4a1863df, 0x3182e51a, 0x33609751, 0x7f456253, 0x77e0b164, 0xae84bb6b, 0xa01cfe81, 0x2b94f908, 0x68587048, 0xfd198f45, 0x6c8794de, 0xf8b7527b, 0xd323ab73, 0x02e2724b, 0x8f57e31f, 0xab2a6655, 0x2807b2eb, 0xc2032fb5, 0x7b9a86c5, 0x08a5d337, 0x87f23028, 0xa5b223bf, 0x6aba0203, 0x825ced16, 0x1c2b8acf, 0xb492a779, 0xf2f0f307, 0xe2a14e69, 0xf4cd65da, 0xbed50605, 0x621fd134, 0xfe8ac4a6, 0x539d342e, 0x55a0a2f3, 0xe132058a, 0xeb75a4f6, 0xec390b83, 0xefaa4060, 0x9f065e71, 0x1051bd6e, 0x8af93e21, 0x063d96dd, 0x05aedd3e, 0xbd464de6, 0x8db59154, 0x5d0571c4, 0xd46f0406, 0x15ff6050, 0xfb241998, 0xe997d6bd, 0x43cc8940, 0x9e7767d9, 0x42bdb0e8, 0x8b880789, 0x5b38e719, 0xeedb79c8, 0x0a47a17c, 0x0fe97c42, 0x1ec9f884, 0x00000000, 0x86830980, 0xed48322b, 0x70ac1e11, 0x724e6c5a, 0xfffbfd0e, 0x38560f85, 0xd51e3dae, 0x3927362d, 0xd9640a0f, 0xa621685c, 0x54d19b5b, 0x2e3a2436, 0x67b10c0a, 0xe70f9357, 0x96d2b4ee, 0x919e1b9b, 0xc54f80c0, 0x20a261dc, 0x4b695a77, 0x1a161c12, 0xba0ae293, 0x2ae5c0a0, 0xe0433c22, 0x171d121b, 0x0d0b0e09, 0xc7adf28b, 0xa8b92db6, 0xa9c8141e, 0x198557f1, 0x074caf75, 0xddbbee99, 0x60fda37f, 0x269ff701, 0xf5bc5c72, 0x3bc54466, 0x7e345bfb, 0x29768b43, 0xc6dccb23, 0xfc68b6ed, 0xf163b8e4, 0xdccad731, 0x85104263, 0x22401397, 0x112084c6, 0x247d854a, 0x3df8d2bb, 0x3211aef9, 0xa16dc729, 0x2f4b1d9e, 0x30f3dcb2, 0x52ec0d86, 0xe3d077c1, 0x166c2bb3, 0xb999a970, 0x48fa1194, 0x642247e9, 0x8cc4a8fc, 0x3f1aa0f0, 0x2cd8567d, 0x90ef2233, 0x4ec78749, 0xd1c1d938, 0xa2fe8cca, 0x0b3698d4, 0x81cfa6f5, 0xde28a57a, 0x8e26dab7, 0xbfa43fad, 0x9de42c3a, 0x920d5078, 0xcc9b6a5f, 0x4662547e, 0x13c2f68d, 0xb8e890d8, 0xf75e2e39, 0xaff582c3, 0x80be9f5d, 0x937c69d0, 0x2da96fd5, 0x12b3cf25, 0x993bc8ac, 0x7da71018, 0x636ee89c, 0xbb7bdb3b, 0x7809cd26, 0x18f46e59, 0xb701ec9a, 0x9aa8834f, 0x6e65e695, 0xe67eaaff, 0xcf0821bc, 0xe8e6ef15, 0x9bd9bae7, 0x36ce4a6f, 0x09d4ea9f, 0x7cd629b0, 0xb2af31a4, 0x23312a3f, 0x9430c6a5, 0x66c035a2, 0xbc37744e, 0xcaa6fc82, 0xd0b0e090, 0xd81533a7, 0x984af104, 0xdaf741ec, 0x500e7fcd, 0xf62f1791, 0xd68d764d, 0xb04d43ef, 0x4d54ccaa, 0x04dfe496, 0xb5e39ed1, 0x881b4c6a, 0x1fb8c12c, 0x517f4665, 0xea049d5e, 0x355d018c, 0x7473fa87, 0x412efb0b, 0x1d5ab367, 0xd25292db, 0x5633e910, 0x47136dd6, 0x618c9ad7, 0x0c7a37a1, 0x148e59f8, 0x3c89eb13, 0x27eecea9, 0xc935b761, 0xe5ede11c, 0xb13c7a47, 0xdf599cd2, 0x733f55f2, 0xce791814, 0x37bf73c7, 0xcdea53f7, 0xaa5b5ffd, 0x6f14df3d, 0xdb867844, 0xf381caaf, 0xc43eb968, 0x342c3824, 0x405fc2a3, 0xc372161d, 0x250cbce2, 0x498b283c, 0x9541ff0d, 0x017139a8, 0xb3de080c, 0xe49cd8b4, 0xc1906456, 0x84617bcb, 0xb670d532, 0x5c74486c, 0x5742d0b8];
176 | var T8 = [0xf4a75051, 0x4165537e, 0x17a4c31a, 0x275e963a, 0xab6bcb3b, 0x9d45f11f, 0xfa58abac, 0xe303934b, 0x30fa5520, 0x766df6ad, 0xcc769188, 0x024c25f5, 0xe5d7fc4f, 0x2acbd7c5, 0x35448026, 0x62a38fb5, 0xb15a49de, 0xba1b6725, 0xea0e9845, 0xfec0e15d, 0x2f7502c3, 0x4cf01281, 0x4697a38d, 0xd3f9c66b, 0x8f5fe703, 0x929c9515, 0x6d7aebbf, 0x5259da95, 0xbe832dd4, 0x7421d358, 0xe0692949, 0xc9c8448e, 0xc2896a75, 0x8e7978f4, 0x583e6b99, 0xb971dd27, 0xe14fb6be, 0x88ad17f0, 0x20ac66c9, 0xce3ab47d, 0xdf4a1863, 0x1a3182e5, 0x51336097, 0x537f4562, 0x6477e0b1, 0x6bae84bb, 0x81a01cfe, 0x082b94f9, 0x48685870, 0x45fd198f, 0xde6c8794, 0x7bf8b752, 0x73d323ab, 0x4b02e272, 0x1f8f57e3, 0x55ab2a66, 0xeb2807b2, 0xb5c2032f, 0xc57b9a86, 0x3708a5d3, 0x2887f230, 0xbfa5b223, 0x036aba02, 0x16825ced, 0xcf1c2b8a, 0x79b492a7, 0x07f2f0f3, 0x69e2a14e, 0xdaf4cd65, 0x05bed506, 0x34621fd1, 0xa6fe8ac4, 0x2e539d34, 0xf355a0a2, 0x8ae13205, 0xf6eb75a4, 0x83ec390b, 0x60efaa40, 0x719f065e, 0x6e1051bd, 0x218af93e, 0xdd063d96, 0x3e05aedd, 0xe6bd464d, 0x548db591, 0xc45d0571, 0x06d46f04, 0x5015ff60, 0x98fb2419, 0xbde997d6, 0x4043cc89, 0xd99e7767, 0xe842bdb0, 0x898b8807, 0x195b38e7, 0xc8eedb79, 0x7c0a47a1, 0x420fe97c, 0x841ec9f8, 0x00000000, 0x80868309, 0x2bed4832, 0x1170ac1e, 0x5a724e6c, 0x0efffbfd, 0x8538560f, 0xaed51e3d, 0x2d392736, 0x0fd9640a, 0x5ca62168, 0x5b54d19b, 0x362e3a24, 0x0a67b10c, 0x57e70f93, 0xee96d2b4, 0x9b919e1b, 0xc0c54f80, 0xdc20a261, 0x774b695a, 0x121a161c, 0x93ba0ae2, 0xa02ae5c0, 0x22e0433c, 0x1b171d12, 0x090d0b0e, 0x8bc7adf2, 0xb6a8b92d, 0x1ea9c814, 0xf1198557, 0x75074caf, 0x99ddbbee, 0x7f60fda3, 0x01269ff7, 0x72f5bc5c, 0x663bc544, 0xfb7e345b, 0x4329768b, 0x23c6dccb, 0xedfc68b6, 0xe4f163b8, 0x31dccad7, 0x63851042, 0x97224013, 0xc6112084, 0x4a247d85, 0xbb3df8d2, 0xf93211ae, 0x29a16dc7, 0x9e2f4b1d, 0xb230f3dc, 0x8652ec0d, 0xc1e3d077, 0xb3166c2b, 0x70b999a9, 0x9448fa11, 0xe9642247, 0xfc8cc4a8, 0xf03f1aa0, 0x7d2cd856, 0x3390ef22, 0x494ec787, 0x38d1c1d9, 0xcaa2fe8c, 0xd40b3698, 0xf581cfa6, 0x7ade28a5, 0xb78e26da, 0xadbfa43f, 0x3a9de42c, 0x78920d50, 0x5fcc9b6a, 0x7e466254, 0x8d13c2f6, 0xd8b8e890, 0x39f75e2e, 0xc3aff582, 0x5d80be9f, 0xd0937c69, 0xd52da96f, 0x2512b3cf, 0xac993bc8, 0x187da710, 0x9c636ee8, 0x3bbb7bdb, 0x267809cd, 0x5918f46e, 0x9ab701ec, 0x4f9aa883, 0x956e65e6, 0xffe67eaa, 0xbccf0821, 0x15e8e6ef, 0xe79bd9ba, 0x6f36ce4a, 0x9f09d4ea, 0xb07cd629, 0xa4b2af31, 0x3f23312a, 0xa59430c6, 0xa266c035, 0x4ebc3774, 0x82caa6fc, 0x90d0b0e0, 0xa7d81533, 0x04984af1, 0xecdaf741, 0xcd500e7f, 0x91f62f17, 0x4dd68d76, 0xefb04d43, 0xaa4d54cc, 0x9604dfe4, 0xd1b5e39e, 0x6a881b4c, 0x2c1fb8c1, 0x65517f46, 0x5eea049d, 0x8c355d01, 0x877473fa, 0x0b412efb, 0x671d5ab3, 0xdbd25292, 0x105633e9, 0xd647136d, 0xd7618c9a, 0xa10c7a37, 0xf8148e59, 0x133c89eb, 0xa927eece, 0x61c935b7, 0x1ce5ede1, 0x47b13c7a, 0xd2df599c, 0xf2733f55, 0x14ce7918, 0xc737bf73, 0xf7cdea53, 0xfdaa5b5f, 0x3d6f14df, 0x44db8678, 0xaff381ca, 0x68c43eb9, 0x24342c38, 0xa3405fc2, 0x1dc37216, 0xe2250cbc, 0x3c498b28, 0x0d9541ff, 0xa8017139, 0x0cb3de08, 0xb4e49cd8, 0x56c19064, 0xcb84617b, 0x32b670d5, 0x6c5c7448, 0xb85742d0];
177 |
178 | // Transformations for decryption key expansion
179 | var U1 = [0x00000000, 0x0e090d0b, 0x1c121a16, 0x121b171d, 0x3824342c, 0x362d3927, 0x24362e3a, 0x2a3f2331, 0x70486858, 0x7e416553, 0x6c5a724e, 0x62537f45, 0x486c5c74, 0x4665517f, 0x547e4662, 0x5a774b69, 0xe090d0b0, 0xee99ddbb, 0xfc82caa6, 0xf28bc7ad, 0xd8b4e49c, 0xd6bde997, 0xc4a6fe8a, 0xcaaff381, 0x90d8b8e8, 0x9ed1b5e3, 0x8ccaa2fe, 0x82c3aff5, 0xa8fc8cc4, 0xa6f581cf, 0xb4ee96d2, 0xbae79bd9, 0xdb3bbb7b, 0xd532b670, 0xc729a16d, 0xc920ac66, 0xe31f8f57, 0xed16825c, 0xff0d9541, 0xf104984a, 0xab73d323, 0xa57ade28, 0xb761c935, 0xb968c43e, 0x9357e70f, 0x9d5eea04, 0x8f45fd19, 0x814cf012, 0x3bab6bcb, 0x35a266c0, 0x27b971dd, 0x29b07cd6, 0x038f5fe7, 0x0d8652ec, 0x1f9d45f1, 0x119448fa, 0x4be30393, 0x45ea0e98, 0x57f11985, 0x59f8148e, 0x73c737bf, 0x7dce3ab4, 0x6fd52da9, 0x61dc20a2, 0xad766df6, 0xa37f60fd, 0xb16477e0, 0xbf6d7aeb, 0x955259da, 0x9b5b54d1, 0x894043cc, 0x87494ec7, 0xdd3e05ae, 0xd33708a5, 0xc12c1fb8, 0xcf2512b3, 0xe51a3182, 0xeb133c89, 0xf9082b94, 0xf701269f, 0x4de6bd46, 0x43efb04d, 0x51f4a750, 0x5ffdaa5b, 0x75c2896a, 0x7bcb8461, 0x69d0937c, 0x67d99e77, 0x3daed51e, 0x33a7d815, 0x21bccf08, 0x2fb5c203, 0x058ae132, 0x0b83ec39, 0x1998fb24, 0x1791f62f, 0x764dd68d, 0x7844db86, 0x6a5fcc9b, 0x6456c190, 0x4e69e2a1, 0x4060efaa, 0x527bf8b7, 0x5c72f5bc, 0x0605bed5, 0x080cb3de, 0x1a17a4c3, 0x141ea9c8, 0x3e218af9, 0x302887f2, 0x223390ef, 0x2c3a9de4, 0x96dd063d, 0x98d40b36, 0x8acf1c2b, 0x84c61120, 0xaef93211, 0xa0f03f1a, 0xb2eb2807, 0xbce2250c, 0xe6956e65, 0xe89c636e, 0xfa877473, 0xf48e7978, 0xdeb15a49, 0xd0b85742, 0xc2a3405f, 0xccaa4d54, 0x41ecdaf7, 0x4fe5d7fc, 0x5dfec0e1, 0x53f7cdea, 0x79c8eedb, 0x77c1e3d0, 0x65daf4cd, 0x6bd3f9c6, 0x31a4b2af, 0x3fadbfa4, 0x2db6a8b9, 0x23bfa5b2, 0x09808683, 0x07898b88, 0x15929c95, 0x1b9b919e, 0xa17c0a47, 0xaf75074c, 0xbd6e1051, 0xb3671d5a, 0x99583e6b, 0x97513360, 0x854a247d, 0x8b432976, 0xd134621f, 0xdf3d6f14, 0xcd267809, 0xc32f7502, 0xe9105633, 0xe7195b38, 0xf5024c25, 0xfb0b412e, 0x9ad7618c, 0x94de6c87, 0x86c57b9a, 0x88cc7691, 0xa2f355a0, 0xacfa58ab, 0xbee14fb6, 0xb0e842bd, 0xea9f09d4, 0xe49604df, 0xf68d13c2, 0xf8841ec9, 0xd2bb3df8, 0xdcb230f3, 0xcea927ee, 0xc0a02ae5, 0x7a47b13c, 0x744ebc37, 0x6655ab2a, 0x685ca621, 0x42638510, 0x4c6a881b, 0x5e719f06, 0x5078920d, 0x0a0fd964, 0x0406d46f, 0x161dc372, 0x1814ce79, 0x322bed48, 0x3c22e043, 0x2e39f75e, 0x2030fa55, 0xec9ab701, 0xe293ba0a, 0xf088ad17, 0xfe81a01c, 0xd4be832d, 0xdab78e26, 0xc8ac993b, 0xc6a59430, 0x9cd2df59, 0x92dbd252, 0x80c0c54f, 0x8ec9c844, 0xa4f6eb75, 0xaaffe67e, 0xb8e4f163, 0xb6edfc68, 0x0c0a67b1, 0x02036aba, 0x10187da7, 0x1e1170ac, 0x342e539d, 0x3a275e96, 0x283c498b, 0x26354480, 0x7c420fe9, 0x724b02e2, 0x605015ff, 0x6e5918f4, 0x44663bc5, 0x4a6f36ce, 0x587421d3, 0x567d2cd8, 0x37a10c7a, 0x39a80171, 0x2bb3166c, 0x25ba1b67, 0x0f853856, 0x018c355d, 0x13972240, 0x1d9e2f4b, 0x47e96422, 0x49e06929, 0x5bfb7e34, 0x55f2733f, 0x7fcd500e, 0x71c45d05, 0x63df4a18, 0x6dd64713, 0xd731dcca, 0xd938d1c1, 0xcb23c6dc, 0xc52acbd7, 0xef15e8e6, 0xe11ce5ed, 0xf307f2f0, 0xfd0efffb, 0xa779b492, 0xa970b999, 0xbb6bae84, 0xb562a38f, 0x9f5d80be, 0x91548db5, 0x834f9aa8, 0x8d4697a3];
180 | var U2 = [0x00000000, 0x0b0e090d, 0x161c121a, 0x1d121b17, 0x2c382434, 0x27362d39, 0x3a24362e, 0x312a3f23, 0x58704868, 0x537e4165, 0x4e6c5a72, 0x4562537f, 0x74486c5c, 0x7f466551, 0x62547e46, 0x695a774b, 0xb0e090d0, 0xbbee99dd, 0xa6fc82ca, 0xadf28bc7, 0x9cd8b4e4, 0x97d6bde9, 0x8ac4a6fe, 0x81caaff3, 0xe890d8b8, 0xe39ed1b5, 0xfe8ccaa2, 0xf582c3af, 0xc4a8fc8c, 0xcfa6f581, 0xd2b4ee96, 0xd9bae79b, 0x7bdb3bbb, 0x70d532b6, 0x6dc729a1, 0x66c920ac, 0x57e31f8f, 0x5ced1682, 0x41ff0d95, 0x4af10498, 0x23ab73d3, 0x28a57ade, 0x35b761c9, 0x3eb968c4, 0x0f9357e7, 0x049d5eea, 0x198f45fd, 0x12814cf0, 0xcb3bab6b, 0xc035a266, 0xdd27b971, 0xd629b07c, 0xe7038f5f, 0xec0d8652, 0xf11f9d45, 0xfa119448, 0x934be303, 0x9845ea0e, 0x8557f119, 0x8e59f814, 0xbf73c737, 0xb47dce3a, 0xa96fd52d, 0xa261dc20, 0xf6ad766d, 0xfda37f60, 0xe0b16477, 0xebbf6d7a, 0xda955259, 0xd19b5b54, 0xcc894043, 0xc787494e, 0xaedd3e05, 0xa5d33708, 0xb8c12c1f, 0xb3cf2512, 0x82e51a31, 0x89eb133c, 0x94f9082b, 0x9ff70126, 0x464de6bd, 0x4d43efb0, 0x5051f4a7, 0x5b5ffdaa, 0x6a75c289, 0x617bcb84, 0x7c69d093, 0x7767d99e, 0x1e3daed5, 0x1533a7d8, 0x0821bccf, 0x032fb5c2, 0x32058ae1, 0x390b83ec, 0x241998fb, 0x2f1791f6, 0x8d764dd6, 0x867844db, 0x9b6a5fcc, 0x906456c1, 0xa14e69e2, 0xaa4060ef, 0xb7527bf8, 0xbc5c72f5, 0xd50605be, 0xde080cb3, 0xc31a17a4, 0xc8141ea9, 0xf93e218a, 0xf2302887, 0xef223390, 0xe42c3a9d, 0x3d96dd06, 0x3698d40b, 0x2b8acf1c, 0x2084c611, 0x11aef932, 0x1aa0f03f, 0x07b2eb28, 0x0cbce225, 0x65e6956e, 0x6ee89c63, 0x73fa8774, 0x78f48e79, 0x49deb15a, 0x42d0b857, 0x5fc2a340, 0x54ccaa4d, 0xf741ecda, 0xfc4fe5d7, 0xe15dfec0, 0xea53f7cd, 0xdb79c8ee, 0xd077c1e3, 0xcd65daf4, 0xc66bd3f9, 0xaf31a4b2, 0xa43fadbf, 0xb92db6a8, 0xb223bfa5, 0x83098086, 0x8807898b, 0x9515929c, 0x9e1b9b91, 0x47a17c0a, 0x4caf7507, 0x51bd6e10, 0x5ab3671d, 0x6b99583e, 0x60975133, 0x7d854a24, 0x768b4329, 0x1fd13462, 0x14df3d6f, 0x09cd2678, 0x02c32f75, 0x33e91056, 0x38e7195b, 0x25f5024c, 0x2efb0b41, 0x8c9ad761, 0x8794de6c, 0x9a86c57b, 0x9188cc76, 0xa0a2f355, 0xabacfa58, 0xb6bee14f, 0xbdb0e842, 0xd4ea9f09, 0xdfe49604, 0xc2f68d13, 0xc9f8841e, 0xf8d2bb3d, 0xf3dcb230, 0xeecea927, 0xe5c0a02a, 0x3c7a47b1, 0x37744ebc, 0x2a6655ab, 0x21685ca6, 0x10426385, 0x1b4c6a88, 0x065e719f, 0x0d507892, 0x640a0fd9, 0x6f0406d4, 0x72161dc3, 0x791814ce, 0x48322bed, 0x433c22e0, 0x5e2e39f7, 0x552030fa, 0x01ec9ab7, 0x0ae293ba, 0x17f088ad, 0x1cfe81a0, 0x2dd4be83, 0x26dab78e, 0x3bc8ac99, 0x30c6a594, 0x599cd2df, 0x5292dbd2, 0x4f80c0c5, 0x448ec9c8, 0x75a4f6eb, 0x7eaaffe6, 0x63b8e4f1, 0x68b6edfc, 0xb10c0a67, 0xba02036a, 0xa710187d, 0xac1e1170, 0x9d342e53, 0x963a275e, 0x8b283c49, 0x80263544, 0xe97c420f, 0xe2724b02, 0xff605015, 0xf46e5918, 0xc544663b, 0xce4a6f36, 0xd3587421, 0xd8567d2c, 0x7a37a10c, 0x7139a801, 0x6c2bb316, 0x6725ba1b, 0x560f8538, 0x5d018c35, 0x40139722, 0x4b1d9e2f, 0x2247e964, 0x2949e069, 0x345bfb7e, 0x3f55f273, 0x0e7fcd50, 0x0571c45d, 0x1863df4a, 0x136dd647, 0xcad731dc, 0xc1d938d1, 0xdccb23c6, 0xd7c52acb, 0xe6ef15e8, 0xede11ce5, 0xf0f307f2, 0xfbfd0eff, 0x92a779b4, 0x99a970b9, 0x84bb6bae, 0x8fb562a3, 0xbe9f5d80, 0xb591548d, 0xa8834f9a, 0xa38d4697];
181 | var U3 = [0x00000000, 0x0d0b0e09, 0x1a161c12, 0x171d121b, 0x342c3824, 0x3927362d, 0x2e3a2436, 0x23312a3f, 0x68587048, 0x65537e41, 0x724e6c5a, 0x7f456253, 0x5c74486c, 0x517f4665, 0x4662547e, 0x4b695a77, 0xd0b0e090, 0xddbbee99, 0xcaa6fc82, 0xc7adf28b, 0xe49cd8b4, 0xe997d6bd, 0xfe8ac4a6, 0xf381caaf, 0xb8e890d8, 0xb5e39ed1, 0xa2fe8cca, 0xaff582c3, 0x8cc4a8fc, 0x81cfa6f5, 0x96d2b4ee, 0x9bd9bae7, 0xbb7bdb3b, 0xb670d532, 0xa16dc729, 0xac66c920, 0x8f57e31f, 0x825ced16, 0x9541ff0d, 0x984af104, 0xd323ab73, 0xde28a57a, 0xc935b761, 0xc43eb968, 0xe70f9357, 0xea049d5e, 0xfd198f45, 0xf012814c, 0x6bcb3bab, 0x66c035a2, 0x71dd27b9, 0x7cd629b0, 0x5fe7038f, 0x52ec0d86, 0x45f11f9d, 0x48fa1194, 0x03934be3, 0x0e9845ea, 0x198557f1, 0x148e59f8, 0x37bf73c7, 0x3ab47dce, 0x2da96fd5, 0x20a261dc, 0x6df6ad76, 0x60fda37f, 0x77e0b164, 0x7aebbf6d, 0x59da9552, 0x54d19b5b, 0x43cc8940, 0x4ec78749, 0x05aedd3e, 0x08a5d337, 0x1fb8c12c, 0x12b3cf25, 0x3182e51a, 0x3c89eb13, 0x2b94f908, 0x269ff701, 0xbd464de6, 0xb04d43ef, 0xa75051f4, 0xaa5b5ffd, 0x896a75c2, 0x84617bcb, 0x937c69d0, 0x9e7767d9, 0xd51e3dae, 0xd81533a7, 0xcf0821bc, 0xc2032fb5, 0xe132058a, 0xec390b83, 0xfb241998, 0xf62f1791, 0xd68d764d, 0xdb867844, 0xcc9b6a5f, 0xc1906456, 0xe2a14e69, 0xefaa4060, 0xf8b7527b, 0xf5bc5c72, 0xbed50605, 0xb3de080c, 0xa4c31a17, 0xa9c8141e, 0x8af93e21, 0x87f23028, 0x90ef2233, 0x9de42c3a, 0x063d96dd, 0x0b3698d4, 0x1c2b8acf, 0x112084c6, 0x3211aef9, 0x3f1aa0f0, 0x2807b2eb, 0x250cbce2, 0x6e65e695, 0x636ee89c, 0x7473fa87, 0x7978f48e, 0x5a49deb1, 0x5742d0b8, 0x405fc2a3, 0x4d54ccaa, 0xdaf741ec, 0xd7fc4fe5, 0xc0e15dfe, 0xcdea53f7, 0xeedb79c8, 0xe3d077c1, 0xf4cd65da, 0xf9c66bd3, 0xb2af31a4, 0xbfa43fad, 0xa8b92db6, 0xa5b223bf, 0x86830980, 0x8b880789, 0x9c951592, 0x919e1b9b, 0x0a47a17c, 0x074caf75, 0x1051bd6e, 0x1d5ab367, 0x3e6b9958, 0x33609751, 0x247d854a, 0x29768b43, 0x621fd134, 0x6f14df3d, 0x7809cd26, 0x7502c32f, 0x5633e910, 0x5b38e719, 0x4c25f502, 0x412efb0b, 0x618c9ad7, 0x6c8794de, 0x7b9a86c5, 0x769188cc, 0x55a0a2f3, 0x58abacfa, 0x4fb6bee1, 0x42bdb0e8, 0x09d4ea9f, 0x04dfe496, 0x13c2f68d, 0x1ec9f884, 0x3df8d2bb, 0x30f3dcb2, 0x27eecea9, 0x2ae5c0a0, 0xb13c7a47, 0xbc37744e, 0xab2a6655, 0xa621685c, 0x85104263, 0x881b4c6a, 0x9f065e71, 0x920d5078, 0xd9640a0f, 0xd46f0406, 0xc372161d, 0xce791814, 0xed48322b, 0xe0433c22, 0xf75e2e39, 0xfa552030, 0xb701ec9a, 0xba0ae293, 0xad17f088, 0xa01cfe81, 0x832dd4be, 0x8e26dab7, 0x993bc8ac, 0x9430c6a5, 0xdf599cd2, 0xd25292db, 0xc54f80c0, 0xc8448ec9, 0xeb75a4f6, 0xe67eaaff, 0xf163b8e4, 0xfc68b6ed, 0x67b10c0a, 0x6aba0203, 0x7da71018, 0x70ac1e11, 0x539d342e, 0x5e963a27, 0x498b283c, 0x44802635, 0x0fe97c42, 0x02e2724b, 0x15ff6050, 0x18f46e59, 0x3bc54466, 0x36ce4a6f, 0x21d35874, 0x2cd8567d, 0x0c7a37a1, 0x017139a8, 0x166c2bb3, 0x1b6725ba, 0x38560f85, 0x355d018c, 0x22401397, 0x2f4b1d9e, 0x642247e9, 0x692949e0, 0x7e345bfb, 0x733f55f2, 0x500e7fcd, 0x5d0571c4, 0x4a1863df, 0x47136dd6, 0xdccad731, 0xd1c1d938, 0xc6dccb23, 0xcbd7c52a, 0xe8e6ef15, 0xe5ede11c, 0xf2f0f307, 0xfffbfd0e, 0xb492a779, 0xb999a970, 0xae84bb6b, 0xa38fb562, 0x80be9f5d, 0x8db59154, 0x9aa8834f, 0x97a38d46];
182 | var U4 = [0x00000000, 0x090d0b0e, 0x121a161c, 0x1b171d12, 0x24342c38, 0x2d392736, 0x362e3a24, 0x3f23312a, 0x48685870, 0x4165537e, 0x5a724e6c, 0x537f4562, 0x6c5c7448, 0x65517f46, 0x7e466254, 0x774b695a, 0x90d0b0e0, 0x99ddbbee, 0x82caa6fc, 0x8bc7adf2, 0xb4e49cd8, 0xbde997d6, 0xa6fe8ac4, 0xaff381ca, 0xd8b8e890, 0xd1b5e39e, 0xcaa2fe8c, 0xc3aff582, 0xfc8cc4a8, 0xf581cfa6, 0xee96d2b4, 0xe79bd9ba, 0x3bbb7bdb, 0x32b670d5, 0x29a16dc7, 0x20ac66c9, 0x1f8f57e3, 0x16825ced, 0x0d9541ff, 0x04984af1, 0x73d323ab, 0x7ade28a5, 0x61c935b7, 0x68c43eb9, 0x57e70f93, 0x5eea049d, 0x45fd198f, 0x4cf01281, 0xab6bcb3b, 0xa266c035, 0xb971dd27, 0xb07cd629, 0x8f5fe703, 0x8652ec0d, 0x9d45f11f, 0x9448fa11, 0xe303934b, 0xea0e9845, 0xf1198557, 0xf8148e59, 0xc737bf73, 0xce3ab47d, 0xd52da96f, 0xdc20a261, 0x766df6ad, 0x7f60fda3, 0x6477e0b1, 0x6d7aebbf, 0x5259da95, 0x5b54d19b, 0x4043cc89, 0x494ec787, 0x3e05aedd, 0x3708a5d3, 0x2c1fb8c1, 0x2512b3cf, 0x1a3182e5, 0x133c89eb, 0x082b94f9, 0x01269ff7, 0xe6bd464d, 0xefb04d43, 0xf4a75051, 0xfdaa5b5f, 0xc2896a75, 0xcb84617b, 0xd0937c69, 0xd99e7767, 0xaed51e3d, 0xa7d81533, 0xbccf0821, 0xb5c2032f, 0x8ae13205, 0x83ec390b, 0x98fb2419, 0x91f62f17, 0x4dd68d76, 0x44db8678, 0x5fcc9b6a, 0x56c19064, 0x69e2a14e, 0x60efaa40, 0x7bf8b752, 0x72f5bc5c, 0x05bed506, 0x0cb3de08, 0x17a4c31a, 0x1ea9c814, 0x218af93e, 0x2887f230, 0x3390ef22, 0x3a9de42c, 0xdd063d96, 0xd40b3698, 0xcf1c2b8a, 0xc6112084, 0xf93211ae, 0xf03f1aa0, 0xeb2807b2, 0xe2250cbc, 0x956e65e6, 0x9c636ee8, 0x877473fa, 0x8e7978f4, 0xb15a49de, 0xb85742d0, 0xa3405fc2, 0xaa4d54cc, 0xecdaf741, 0xe5d7fc4f, 0xfec0e15d, 0xf7cdea53, 0xc8eedb79, 0xc1e3d077, 0xdaf4cd65, 0xd3f9c66b, 0xa4b2af31, 0xadbfa43f, 0xb6a8b92d, 0xbfa5b223, 0x80868309, 0x898b8807, 0x929c9515, 0x9b919e1b, 0x7c0a47a1, 0x75074caf, 0x6e1051bd, 0x671d5ab3, 0x583e6b99, 0x51336097, 0x4a247d85, 0x4329768b, 0x34621fd1, 0x3d6f14df, 0x267809cd, 0x2f7502c3, 0x105633e9, 0x195b38e7, 0x024c25f5, 0x0b412efb, 0xd7618c9a, 0xde6c8794, 0xc57b9a86, 0xcc769188, 0xf355a0a2, 0xfa58abac, 0xe14fb6be, 0xe842bdb0, 0x9f09d4ea, 0x9604dfe4, 0x8d13c2f6, 0x841ec9f8, 0xbb3df8d2, 0xb230f3dc, 0xa927eece, 0xa02ae5c0, 0x47b13c7a, 0x4ebc3774, 0x55ab2a66, 0x5ca62168, 0x63851042, 0x6a881b4c, 0x719f065e, 0x78920d50, 0x0fd9640a, 0x06d46f04, 0x1dc37216, 0x14ce7918, 0x2bed4832, 0x22e0433c, 0x39f75e2e, 0x30fa5520, 0x9ab701ec, 0x93ba0ae2, 0x88ad17f0, 0x81a01cfe, 0xbe832dd4, 0xb78e26da, 0xac993bc8, 0xa59430c6, 0xd2df599c, 0xdbd25292, 0xc0c54f80, 0xc9c8448e, 0xf6eb75a4, 0xffe67eaa, 0xe4f163b8, 0xedfc68b6, 0x0a67b10c, 0x036aba02, 0x187da710, 0x1170ac1e, 0x2e539d34, 0x275e963a, 0x3c498b28, 0x35448026, 0x420fe97c, 0x4b02e272, 0x5015ff60, 0x5918f46e, 0x663bc544, 0x6f36ce4a, 0x7421d358, 0x7d2cd856, 0xa10c7a37, 0xa8017139, 0xb3166c2b, 0xba1b6725, 0x8538560f, 0x8c355d01, 0x97224013, 0x9e2f4b1d, 0xe9642247, 0xe0692949, 0xfb7e345b, 0xf2733f55, 0xcd500e7f, 0xc45d0571, 0xdf4a1863, 0xd647136d, 0x31dccad7, 0x38d1c1d9, 0x23c6dccb, 0x2acbd7c5, 0x15e8e6ef, 0x1ce5ede1, 0x07f2f0f3, 0x0efffbfd, 0x79b492a7, 0x70b999a9, 0x6bae84bb, 0x62a38fb5, 0x5d80be9f, 0x548db591, 0x4f9aa883, 0x4697a38d];
183 |
184 | function convertToInt32(bytes) {
185 | var result = [];
186 | for (var i = 0; i < bytes.length; i += 4) {
187 | result.push(
188 | (bytes[i] << 24) |
189 | (bytes[i + 1] << 16) |
190 | (bytes[i + 2] << 8) |
191 | bytes[i + 3]
192 | );
193 | }
194 | return result;
195 | }
196 |
197 | var AES = function (key) {
198 | if (!(this instanceof AES)) {
199 | throw Error('AES must be instanitated with `new`');
200 | }
201 |
202 | Object.defineProperty(this, 'key', {
203 | value: coerceArray(key, true)
204 | });
205 |
206 | this._prepare();
207 | }
208 |
209 |
210 | AES.prototype._prepare = function () {
211 |
212 | var rounds = numberOfRounds[this.key.length];
213 | if (rounds == null) {
214 | throw new Error('invalid key size (must be 16, 24 or 32 bytes)');
215 | }
216 |
217 | // encryption round keys
218 | this._Ke = [];
219 |
220 | // decryption round keys
221 | this._Kd = [];
222 |
223 | for (var i = 0; i <= rounds; i++) {
224 | this._Ke.push([0, 0, 0, 0]);
225 | this._Kd.push([0, 0, 0, 0]);
226 | }
227 |
228 | var roundKeyCount = (rounds + 1) * 4;
229 | var KC = this.key.length / 4;
230 |
231 | // convert the key into ints
232 | var tk = convertToInt32(this.key);
233 |
234 | // copy values into round key arrays
235 | var index;
236 | for (var i = 0; i < KC; i++) {
237 | index = i >> 2;
238 | this._Ke[index][i % 4] = tk[i];
239 | this._Kd[rounds - index][i % 4] = tk[i];
240 | }
241 |
242 | // key expansion (fips-197 section 5.2)
243 | var rconpointer = 0;
244 | var t = KC, tt;
245 | while (t < roundKeyCount) {
246 | tt = tk[KC - 1];
247 | tk[0] ^= ((S[(tt >> 16) & 0xFF] << 24) ^
248 | (S[(tt >> 8) & 0xFF] << 16) ^
249 | (S[tt & 0xFF] << 8) ^
250 | S[(tt >> 24) & 0xFF] ^
251 | (rcon[rconpointer] << 24));
252 | rconpointer += 1;
253 |
254 | // key expansion (for non-256 bit)
255 | if (KC != 8) {
256 | for (var i = 1; i < KC; i++) {
257 | tk[i] ^= tk[i - 1];
258 | }
259 |
260 | // key expansion for 256-bit keys is "slightly different" (fips-197)
261 | } else {
262 | for (var i = 1; i < (KC / 2); i++) {
263 | tk[i] ^= tk[i - 1];
264 | }
265 | tt = tk[(KC / 2) - 1];
266 |
267 | tk[KC / 2] ^= (S[tt & 0xFF] ^
268 | (S[(tt >> 8) & 0xFF] << 8) ^
269 | (S[(tt >> 16) & 0xFF] << 16) ^
270 | (S[(tt >> 24) & 0xFF] << 24));
271 |
272 | for (var i = (KC / 2) + 1; i < KC; i++) {
273 | tk[i] ^= tk[i - 1];
274 | }
275 | }
276 |
277 | // copy values into round key arrays
278 | var i = 0, r, c;
279 | while (i < KC && t < roundKeyCount) {
280 | r = t >> 2;
281 | c = t % 4;
282 | this._Ke[r][c] = tk[i];
283 | this._Kd[rounds - r][c] = tk[i++];
284 | t++;
285 | }
286 | }
287 |
288 | // inverse-cipher-ify the decryption round key (fips-197 section 5.3)
289 | for (var r = 1; r < rounds; r++) {
290 | for (var c = 0; c < 4; c++) {
291 | tt = this._Kd[r][c];
292 | this._Kd[r][c] = (U1[(tt >> 24) & 0xFF] ^
293 | U2[(tt >> 16) & 0xFF] ^
294 | U3[(tt >> 8) & 0xFF] ^
295 | U4[tt & 0xFF]);
296 | }
297 | }
298 | }
299 |
300 | AES.prototype.encrypt = function (plaintext) {
301 | if (plaintext.length != 16) {
302 | throw new Error('invalid plaintext size (must be 16 bytes)');
303 | }
304 |
305 | var rounds = this._Ke.length - 1;
306 | var a = [0, 0, 0, 0];
307 |
308 | // convert plaintext to (ints ^ key)
309 | var t = convertToInt32(plaintext);
310 | for (var i = 0; i < 4; i++) {
311 | t[i] ^= this._Ke[0][i];
312 | }
313 |
314 | // apply round transforms
315 | for (var r = 1; r < rounds; r++) {
316 | for (var i = 0; i < 4; i++) {
317 | a[i] = (T1[(t[i] >> 24) & 0xff] ^
318 | T2[(t[(i + 1) % 4] >> 16) & 0xff] ^
319 | T3[(t[(i + 2) % 4] >> 8) & 0xff] ^
320 | T4[t[(i + 3) % 4] & 0xff] ^
321 | this._Ke[r][i]);
322 | }
323 | t = a.slice();
324 | }
325 |
326 | // the last round is special
327 | var result = createArray(16), tt;
328 | for (var i = 0; i < 4; i++) {
329 | tt = this._Ke[rounds][i];
330 | result[4 * i] = (S[(t[i] >> 24) & 0xff] ^ (tt >> 24)) & 0xff;
331 | result[4 * i + 1] = (S[(t[(i + 1) % 4] >> 16) & 0xff] ^ (tt >> 16)) & 0xff;
332 | result[4 * i + 2] = (S[(t[(i + 2) % 4] >> 8) & 0xff] ^ (tt >> 8)) & 0xff;
333 | result[4 * i + 3] = (S[t[(i + 3) % 4] & 0xff] ^ tt) & 0xff;
334 | }
335 |
336 | return result;
337 | }
338 |
339 | AES.prototype.decrypt = function (ciphertext) {
340 | if (ciphertext.length != 16) {
341 | throw new Error('invalid ciphertext size (must be 16 bytes)');
342 | }
343 |
344 | var rounds = this._Kd.length - 1;
345 | var a = [0, 0, 0, 0];
346 |
347 | // convert plaintext to (ints ^ key)
348 | var t = convertToInt32(ciphertext);
349 | for (var i = 0; i < 4; i++) {
350 | t[i] ^= this._Kd[0][i];
351 | }
352 |
353 | // apply round transforms
354 | for (var r = 1; r < rounds; r++) {
355 | for (var i = 0; i < 4; i++) {
356 | a[i] = (T5[(t[i] >> 24) & 0xff] ^
357 | T6[(t[(i + 3) % 4] >> 16) & 0xff] ^
358 | T7[(t[(i + 2) % 4] >> 8) & 0xff] ^
359 | T8[t[(i + 1) % 4] & 0xff] ^
360 | this._Kd[r][i]);
361 | }
362 | t = a.slice();
363 | }
364 |
365 | // the last round is special
366 | var result = createArray(16), tt;
367 | for (var i = 0; i < 4; i++) {
368 | tt = this._Kd[rounds][i];
369 | result[4 * i] = (Si[(t[i] >> 24) & 0xff] ^ (tt >> 24)) & 0xff;
370 | result[4 * i + 1] = (Si[(t[(i + 3) % 4] >> 16) & 0xff] ^ (tt >> 16)) & 0xff;
371 | result[4 * i + 2] = (Si[(t[(i + 2) % 4] >> 8) & 0xff] ^ (tt >> 8)) & 0xff;
372 | result[4 * i + 3] = (Si[t[(i + 1) % 4] & 0xff] ^ tt) & 0xff;
373 | }
374 |
375 | return result;
376 | }
377 |
378 |
379 | /**
380 | * Mode Of Operation - Electonic Codebook (ECB)
381 | */
382 | var ModeOfOperationECB = function (key) {
383 | if (!(this instanceof ModeOfOperationECB)) {
384 | throw Error('AES must be instanitated with `new`');
385 | }
386 |
387 | this.description = "Electronic Code Block";
388 | this.name = "ecb";
389 |
390 | this._aes = new AES(key);
391 | }
392 |
393 | ModeOfOperationECB.prototype.encrypt = function (plaintext) {
394 | plaintext = coerceArray(plaintext);
395 |
396 | if ((plaintext.length % 16) !== 0) {
397 | throw new Error('invalid plaintext size (must be multiple of 16 bytes)');
398 | }
399 |
400 | var ciphertext = createArray(plaintext.length);
401 | var block = createArray(16);
402 |
403 | for (var i = 0; i < plaintext.length; i += 16) {
404 | copyArray(plaintext, block, 0, i, i + 16);
405 | block = this._aes.encrypt(block);
406 | copyArray(block, ciphertext, i);
407 | }
408 |
409 | return ciphertext;
410 | }
411 |
412 | ModeOfOperationECB.prototype.decrypt = function (ciphertext) {
413 | ciphertext = coerceArray(ciphertext);
414 |
415 | if ((ciphertext.length % 16) !== 0) {
416 | throw new Error('invalid ciphertext size (must be multiple of 16 bytes)');
417 | }
418 |
419 | var plaintext = createArray(ciphertext.length);
420 | var block = createArray(16);
421 |
422 | for (var i = 0; i < ciphertext.length; i += 16) {
423 | copyArray(ciphertext, block, 0, i, i + 16);
424 | block = this._aes.decrypt(block);
425 | copyArray(block, plaintext, i);
426 | }
427 |
428 | return plaintext;
429 | }
430 |
431 |
432 | /**
433 | * Mode Of Operation - Cipher Block Chaining (CBC)
434 | */
435 | var ModeOfOperationCBC = function (key, iv) {
436 | if (!(this instanceof ModeOfOperationCBC)) {
437 | throw Error('AES must be instanitated with `new`');
438 | }
439 |
440 | this.description = "Cipher Block Chaining";
441 | this.name = "cbc";
442 |
443 | if (!iv) {
444 | iv = createArray(16);
445 |
446 | } else if (iv.length != 16) {
447 | throw new Error('invalid initialation vector size (must be 16 bytes)');
448 | }
449 |
450 | this._lastCipherblock = coerceArray(iv, true);
451 |
452 | this._aes = new AES(key);
453 | }
454 |
455 | ModeOfOperationCBC.prototype.encrypt = function (plaintext) {
456 | plaintext = coerceArray(plaintext);
457 |
458 | if ((plaintext.length % 16) !== 0) {
459 | throw new Error('invalid plaintext size (must be multiple of 16 bytes)');
460 | }
461 |
462 | var ciphertext = createArray(plaintext.length);
463 | var block = createArray(16);
464 |
465 | for (var i = 0; i < plaintext.length; i += 16) {
466 | copyArray(plaintext, block, 0, i, i + 16);
467 |
468 | for (var j = 0; j < 16; j++) {
469 | block[j] ^= this._lastCipherblock[j];
470 | }
471 |
472 | this._lastCipherblock = this._aes.encrypt(block);
473 | copyArray(this._lastCipherblock, ciphertext, i);
474 | }
475 |
476 | return ciphertext;
477 | }
478 |
479 | ModeOfOperationCBC.prototype.decrypt = function (ciphertext) {
480 | ciphertext = coerceArray(ciphertext);
481 |
482 | if ((ciphertext.length % 16) !== 0) {
483 | throw new Error('invalid ciphertext size (must be multiple of 16 bytes)');
484 | }
485 |
486 | var plaintext = createArray(ciphertext.length);
487 | var block = createArray(16);
488 |
489 | for (var i = 0; i < ciphertext.length; i += 16) {
490 | copyArray(ciphertext, block, 0, i, i + 16);
491 | block = this._aes.decrypt(block);
492 |
493 | for (var j = 0; j < 16; j++) {
494 | plaintext[i + j] = block[j] ^ this._lastCipherblock[j];
495 | }
496 |
497 | copyArray(ciphertext, this._lastCipherblock, 0, i, i + 16);
498 | }
499 |
500 | return plaintext;
501 | }
502 |
503 |
504 | /**
505 | * Mode Of Operation - Cipher Feedback (CFB)
506 | */
507 | var ModeOfOperationCFB = function (key, iv, segmentSize) {
508 | if (!(this instanceof ModeOfOperationCFB)) {
509 | throw Error('AES must be instanitated with `new`');
510 | }
511 |
512 | this.description = "Cipher Feedback";
513 | this.name = "cfb";
514 |
515 | if (!iv) {
516 | iv = createArray(16);
517 |
518 | } else if (iv.length != 16) {
519 | throw new Error('invalid initialation vector size (must be 16 size)');
520 | }
521 |
522 | if (!segmentSize) { segmentSize = 1; }
523 |
524 | this.segmentSize = segmentSize;
525 |
526 | this._shiftRegister = coerceArray(iv, true);
527 |
528 | this._aes = new AES(key);
529 | }
530 |
531 | ModeOfOperationCFB.prototype.encrypt = function (plaintext) {
532 | if ((plaintext.length % this.segmentSize) != 0) {
533 | throw new Error('invalid plaintext size (must be segmentSize bytes)');
534 | }
535 |
536 | var encrypted = coerceArray(plaintext, true);
537 |
538 | var xorSegment;
539 | for (var i = 0; i < encrypted.length; i += this.segmentSize) {
540 | xorSegment = this._aes.encrypt(this._shiftRegister);
541 | for (var j = 0; j < this.segmentSize; j++) {
542 | encrypted[i + j] ^= xorSegment[j];
543 | }
544 |
545 | // Shift the register
546 | copyArray(this._shiftRegister, this._shiftRegister, 0, this.segmentSize);
547 | copyArray(encrypted, this._shiftRegister, 16 - this.segmentSize, i, i + this.segmentSize);
548 | }
549 |
550 | return encrypted;
551 | }
552 |
553 | ModeOfOperationCFB.prototype.decrypt = function (ciphertext) {
554 | if ((ciphertext.length % this.segmentSize) != 0) {
555 | throw new Error('invalid ciphertext size (must be segmentSize bytes)');
556 | }
557 |
558 | var plaintext = coerceArray(ciphertext, true);
559 |
560 | var xorSegment;
561 | for (var i = 0; i < plaintext.length; i += this.segmentSize) {
562 | xorSegment = this._aes.encrypt(this._shiftRegister);
563 |
564 | for (var j = 0; j < this.segmentSize; j++) {
565 | plaintext[i + j] ^= xorSegment[j];
566 | }
567 |
568 | // Shift the register
569 | copyArray(this._shiftRegister, this._shiftRegister, 0, this.segmentSize);
570 | copyArray(ciphertext, this._shiftRegister, 16 - this.segmentSize, i, i + this.segmentSize);
571 | }
572 |
573 | return plaintext;
574 | }
575 |
576 | /**
577 | * Mode Of Operation - Output Feedback (OFB)
578 | */
579 | var ModeOfOperationOFB = function (key, iv) {
580 | if (!(this instanceof ModeOfOperationOFB)) {
581 | throw Error('AES must be instanitated with `new`');
582 | }
583 |
584 | this.description = "Output Feedback";
585 | this.name = "ofb";
586 |
587 | if (!iv) {
588 | iv = createArray(16);
589 |
590 | } else if (iv.length != 16) {
591 | throw new Error('invalid initialation vector size (must be 16 bytes)');
592 | }
593 |
594 | this._lastPrecipher = coerceArray(iv, true);
595 | this._lastPrecipherIndex = 16;
596 |
597 | this._aes = new AES(key);
598 | }
599 |
600 | ModeOfOperationOFB.prototype.encrypt = function (plaintext) {
601 | var encrypted = coerceArray(plaintext, true);
602 |
603 | for (var i = 0; i < encrypted.length; i++) {
604 | if (this._lastPrecipherIndex === 16) {
605 | this._lastPrecipher = this._aes.encrypt(this._lastPrecipher);
606 | this._lastPrecipherIndex = 0;
607 | }
608 | encrypted[i] ^= this._lastPrecipher[this._lastPrecipherIndex++];
609 | }
610 |
611 | return encrypted;
612 | }
613 |
614 | // Decryption is symetric
615 | ModeOfOperationOFB.prototype.decrypt = ModeOfOperationOFB.prototype.encrypt;
616 |
617 |
618 | /**
619 | * Counter object for CTR common mode of operation
620 | */
621 | var Counter = function (initialValue) {
622 | if (!(this instanceof Counter)) {
623 | throw Error('Counter must be instanitated with `new`');
624 | }
625 |
626 | // We allow 0, but anything false-ish uses the default 1
627 | if ( initialValue !== 0 && ! initialValue )
628 | {
629 | initialValue = 1;
630 | }
631 |
632 | if (typeof (initialValue) === 'number') {
633 | this._counter = createArray(16);
634 | this.setValue(initialValue);
635 |
636 | } else {
637 | this.setBytes(initialValue);
638 | }
639 | }
640 |
641 | Counter.prototype.setValue = function (value) {
642 | if (typeof (value) !== 'number' || parseInt(value) != value) {
643 | throw new Error('invalid counter value (must be an integer)');
644 | }
645 |
646 | // We cannot safely handle numbers beyond the safe range for integers
647 | if (value > Number.MAX_SAFE_INTEGER) {
648 | throw new Error('integer value out of safe range');
649 | }
650 |
651 | for (var index = 15; index >= 0; --index) {
652 | this._counter[index] = value % 256;
653 | value = parseInt(value / 256);
654 | }
655 | }
656 |
657 | Counter.prototype.setBytes = function (bytes) {
658 | bytes = coerceArray(bytes, true);
659 |
660 | if (bytes.length != 16) {
661 | throw new Error('invalid counter bytes size (must be 16 bytes)');
662 | }
663 |
664 | this._counter = bytes;
665 | };
666 |
667 | Counter.prototype.increment = function () {
668 | for (var i = 15; i >= 0; i--) {
669 | if (this._counter[i] === 255) {
670 | this._counter[i] = 0;
671 | } else {
672 | this._counter[i]++;
673 | break;
674 | }
675 | }
676 | }
677 |
678 |
679 | /**
680 | * Mode Of Operation - Counter (CTR)
681 | */
682 | var ModeOfOperationCTR = function (key, counter) {
683 | if (!(this instanceof ModeOfOperationCTR)) {
684 | throw Error('AES must be instanitated with `new`');
685 | }
686 |
687 | this.description = "Counter";
688 | this.name = "ctr";
689 |
690 | if (!(counter instanceof Counter)) {
691 | counter = new Counter(counter)
692 | }
693 |
694 | this._counter = counter;
695 |
696 | this._remainingCounter = null;
697 | this._remainingCounterIndex = 16;
698 |
699 | this._aes = new AES(key);
700 | }
701 |
702 | ModeOfOperationCTR.prototype.encrypt = function (plaintext) {
703 | var encrypted = coerceArray(plaintext, true);
704 |
705 | for (var i = 0; i < encrypted.length; i++) {
706 | if (this._remainingCounterIndex === 16) {
707 | this._remainingCounter = this._aes.encrypt(this._counter._counter);
708 | this._remainingCounterIndex = 0;
709 | this._counter.increment();
710 | }
711 | encrypted[i] ^= this._remainingCounter[this._remainingCounterIndex++];
712 | }
713 |
714 | return encrypted;
715 | }
716 |
717 | // Decryption is symetric
718 | ModeOfOperationCTR.prototype.decrypt = ModeOfOperationCTR.prototype.encrypt;
719 |
720 |
721 | ///////////////////////
722 | // Padding
723 |
724 | // See:https://tools.ietf.org/html/rfc2315
725 | function pkcs7pad(data) {
726 | data = coerceArray(data, true);
727 | var padder = 16 - (data.length % 16);
728 | var result = createArray(data.length + padder);
729 | copyArray(data, result);
730 | for (var i = data.length; i < result.length; i++) {
731 | result[i] = padder;
732 | }
733 | return result;
734 | }
735 |
736 | function pkcs7strip(data) {
737 | data = coerceArray(data, true);
738 | if (data.length < 16) { throw new Error('PKCS#7 invalid length'); }
739 |
740 | var padder = data[data.length - 1];
741 | if (padder > 16) { throw new Error('PKCS#7 padding byte out of range'); }
742 |
743 | var length = data.length - padder;
744 | for (var i = 0; i < padder; i++) {
745 | if (data[length + i] !== padder) {
746 | throw new Error('PKCS#7 invalid padding byte');
747 | }
748 | }
749 |
750 | var result = createArray(length);
751 | copyArray(data, result, 0, 0, length);
752 | return result;
753 | }
754 |
755 |
756 |
757 |
758 |
759 | /**
760 | * exports
761 | */
762 | module.exports =
763 | {
764 | // The block cipher
765 |
766 | AES : AES,
767 | Counter : Counter,
768 |
769 | ModeOfOperation :
770 | {
771 | ecb: ModeOfOperationECB,
772 | cbc: ModeOfOperationCBC,
773 | cfb: ModeOfOperationCFB,
774 | ofb: ModeOfOperationOFB,
775 | ctr: ModeOfOperationCTR
776 | },
777 |
778 | utils :
779 | {
780 | hex : convertHex,
781 | utf8 : convertUtf8
782 | },
783 |
784 | padding :
785 | {
786 | pkcs7 :
787 | {
788 | pad : pkcs7pad,
789 | strip : pkcs7strip
790 | }
791 | },
792 |
793 | _arrayTest :
794 | {
795 | coerceArray : coerceArray,
796 | createArray : createArray,
797 | copyArray : copyArray,
798 | }
799 | };
--------------------------------------------------------------------------------