mirror of
https://github.com/cryptpad/cryptpad.git
synced 2026-09-14 11:05:41 +05:00
Merge branch 'staging' into badges
This commit is contained in:
commit
e8fd44f1e9
1
.gitignore
vendored
1
.gitignore
vendored
@ -32,6 +32,7 @@ www/common/onlyoffice/v*
|
||||
/onlyoffice-conf/
|
||||
/onlyoffice-dist/
|
||||
|
||||
www/common/worker.bundle.js
|
||||
_build
|
||||
|
||||
# ---> Node
|
||||
|
||||
163
.reuse/dep5
163
.reuse/dep5
@ -1,163 +0,0 @@
|
||||
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Upstream-Name: CryptPad
|
||||
Upstream-Contact: XWiki <contact@cryptpad.org>
|
||||
Source: https://cryptpad.org
|
||||
|
||||
# Sample paragraph, commented out:
|
||||
#
|
||||
# Files: src/*
|
||||
# Copyright: $YEAR $NAME <$CONTACT>
|
||||
# License: ...
|
||||
|
||||
Files: *.png
|
||||
Copyright: 2023 XWiki CryptPad Team <contact@cryptpad.org> and contributors
|
||||
License: AGPL-3.0-or-later
|
||||
|
||||
Files: *.json
|
||||
Copyright: 2023 XWiki CryptPad Team <contact@cryptpad.org> and contributors
|
||||
License: AGPL-3.0-or-later
|
||||
|
||||
Files: .jshintignore
|
||||
Copyright: 2023 XWiki CryptPad Team <contact@cryptpad.org> and contributors
|
||||
License: AGPL-3.0-or-later
|
||||
|
||||
Files: .jshintrc
|
||||
Copyright: 2023 XWiki CryptPad Team <contact@cryptpad.org> and contributors
|
||||
License: AGPL-3.0-or-later
|
||||
|
||||
Files: .stylelintrc.js
|
||||
Copyright: 2023 XWiki CryptPad Team <contact@cryptpad.org> and contributors
|
||||
License: AGPL-3.0-or-later
|
||||
|
||||
Files: scripts/tests/test-data/*
|
||||
Copyright: 2024 XWiki CryptPad Team <contact@cryptpad.org> and contributors
|
||||
License: AGPL-3.0-or-later
|
||||
|
||||
## Dependencies
|
||||
|
||||
Files: www/common/theme/*
|
||||
Copyright: 2017 by Marijn Haverbeke <marijn@haverbeke.berlin> and others
|
||||
License: MIT
|
||||
|
||||
Files: www/lib/mermaid/*
|
||||
Copyright: (c) 2014 - 2021 Knut Sveidqvist
|
||||
License: MIT
|
||||
|
||||
Files: www/lib/calendar/moment.min.js
|
||||
Copyright: (c) JS Foundation and other contributors
|
||||
License: MIT
|
||||
|
||||
Files: www/lib/pdfjs/*
|
||||
Copyright: 2017 Mozilla Foundation
|
||||
License: Apache-2.0
|
||||
|
||||
Files: www/lib/codemirror-extra-modes/asciidoc/*
|
||||
Copyright: (c) 2015, the Asciidoctor Project
|
||||
License: BSD-3-Clause
|
||||
|
||||
Files: www/lib/datepicker/*
|
||||
Copyright: 2017 Gregory Petrosyan
|
||||
License: MIT
|
||||
|
||||
Files: www/lib/diff-dom/*
|
||||
Copyright: Johannes Wilm, Fidus Writer
|
||||
License: LGPL-3.0-only
|
||||
|
||||
Files: www/lib/fabric-history.min.js
|
||||
Copyright: 2008-2015 Printio (Juriy Zaytsev, Maxim Chernyak)
|
||||
License: MIT
|
||||
|
||||
Files: www/lib/fabric.min.js
|
||||
Copyright: 2008-2015 Printio (Juriy Zaytsev, Maxim Chernyak)
|
||||
License: MIT
|
||||
|
||||
Files: www/lib/pdfjs/*
|
||||
Copyright: 2012 Mozilla Foundation
|
||||
License: Apache-2.0
|
||||
|
||||
Files: www/lib/qrcode.min.js
|
||||
Copyright: Sangmin Shim
|
||||
License: MIT
|
||||
|
||||
Files: www/lib/rangy/rangy-core.min.js
|
||||
Copyright: 2015, Tim Down
|
||||
License: MIT
|
||||
|
||||
Files: www/lib/textFit.min.js
|
||||
Copyright: 11/2014 by STRML (strml.github.com)
|
||||
License: MIT
|
||||
|
||||
Files: www/lib/tippy/*
|
||||
Copyright: 2017 atomiks
|
||||
License: MIT
|
||||
|
||||
Files: www/lib/turndown.browser.umd.js
|
||||
Copyright: 2017 Dom Christie
|
||||
License: MIT
|
||||
|
||||
Files: www/lib/markmap/*
|
||||
Copyright: 2015 Jakub Dundalek
|
||||
License: MIT
|
||||
|
||||
Files: www/pad/mathjax/*
|
||||
Copyright: 2009-2018 The MathJax Consortium
|
||||
License: Apache-2.0
|
||||
|
||||
Files: www/pad/wordcount/*
|
||||
Copyright: Ingo Herbote
|
||||
License: MIT
|
||||
|
||||
### same as CKEditor
|
||||
Files: www/pad/wysiwygarea-plugin.js
|
||||
Copyright: 2003-2017, CKSource - Frederico Knabben. All rights reserved
|
||||
License: GPL-2.0-or-later
|
||||
|
||||
Files: www/pad/icons/*
|
||||
Copyright: unknown
|
||||
License: GPL-2.0-or-later
|
||||
|
||||
## OnlyOffice
|
||||
|
||||
Files: www/common/onlyoffice/AllFonts.js
|
||||
Copyright: Ascensio System Limited 2010-2022
|
||||
License: AGPL-3.0-or-later
|
||||
|
||||
Files: www/common/onlyoffice/fonts_thumbnail.png
|
||||
Copyright: Ascensio System Limited 2010-2022
|
||||
License: AGPL-3.0-or-later
|
||||
|
||||
Files: www/common/onlyoffice/fonts_thumbnail@2x.png
|
||||
Copyright: Ascensio System Limited 2010-2022
|
||||
License: AGPL-3.0-or-later
|
||||
|
||||
Files: www/common/onlyoffice/plugins.json
|
||||
Copyright: Ascensio System Limited 2010-2022
|
||||
License: AGPL-3.0-or-later
|
||||
|
||||
Files: www/common/onlyoffice/v1/*
|
||||
Copyright: Ascensio System Limited 2010-2022
|
||||
License: AGPL-3.0-or-later
|
||||
|
||||
Files: www/common/onlyoffice/v2b/*
|
||||
Copyright: Ascensio System Limited 2010-2022
|
||||
License: AGPL-3.0-or-later
|
||||
|
||||
Files: www/common/onlyoffice/v4/*
|
||||
Copyright: Ascensio System Limited 2010-2022
|
||||
License: AGPL-3.0-or-later
|
||||
|
||||
Files: www/common/onlyoffice/v5/*
|
||||
Copyright: Ascensio System Limited 2010-2022
|
||||
License: AGPL-3.0-or-later
|
||||
|
||||
Files: www/common/onlyoffice/v6/*
|
||||
Copyright: Ascensio System Limited 2010-2022
|
||||
License: AGPL-3.0-or-later
|
||||
|
||||
Files: www/common/onlyoffice/v7/*
|
||||
Copyright: Ascensio System Limited 2010-2022
|
||||
License: AGPL-3.0-or-later
|
||||
|
||||
Files: www/common/onlyoffice/x2t/*
|
||||
Copyright: Ascensio System Limited 2010-2022
|
||||
License: AGPL-3.0-or-later
|
||||
112
CHANGELOG.md
112
CHANGELOG.md
@ -4,6 +4,118 @@ SPDX-FileCopyrightText: 2023 XWiki CryptPad Team <contact@cryptpad.org> and cont
|
||||
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
-->
|
||||
|
||||
# 💐 Spring 2025 release (2025.3.0)
|
||||
|
||||
## Goals
|
||||
|
||||
This release starts the important work of refactoring CryptPad code to be more modular and optimized. The first improvements will benefit users with large drives or teams as we now avoid loading _all of your drives and shared folders_ before opening a document. We also include some admin features, numerous fixes and improvements with our usual focus on accessibility and mobile usage.
|
||||
|
||||
> [!NOTE]
|
||||
> We had planned to upgrade OnlyOffice applications (Sheet, Document, Presentation) to version 8 in this release. However we are still working on blocking bugs in the integration. Since the upgrade of documents is non-reversible we are going to keep working to fix the bugs and release `2025.3.1` with OnlyOffice 8 when ready.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> This release contains security fixes, we encourage instance administrators to upgrade.
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
- SharedWorker build with faster loading for requested data [#1822](https://github.com/cryptpad/cryptpad/pull/1822)
|
||||
- Add and remove admins from the UI [#1801](https://github.com/cryptpad/cryptpad/pull/1801)
|
||||
- Upload diagram images on import [#1828](https://github.com/cryptpad/cryptpad/pull/1828)
|
||||
- Integration API [#1797](https://github.com/cryptpad/cryptpad/pull/1797)
|
||||
|
||||
|
||||
## Improvements
|
||||
|
||||
- Drive
|
||||
- Sort files and folders with "natural" sort [#1739](https://github.com/cryptpad/cryptpad/pull/1739) thanks to @jfly
|
||||
- "recent pads" drive category improvements [#1836](https://github.com/cryptpad/cryptpad/pull/1836)
|
||||
- Mobile
|
||||
- Enable preview mode on mobile code app [#1759](https://github.com/cryptpad/cryptpad/pull/1759)
|
||||
- Fix profile layout on small screens [#1742](https://github.com/cryptpad/cryptpad/pull/1742)
|
||||
- Buttons for moving Kanban boards and items on mobile [#1727](https://github.com/cryptpad/cryptpad/pull/1727)
|
||||
- Buttons for moving question blocks in Forms (mobile) [#1753](https://github.com/cryptpad/cryptpad/pull/1753)
|
||||
- Calendar
|
||||
- Improved calendar dropdown: keyboard accessibility and title overflow fixes [#1755](https://github.com/cryptpad/cryptpad/pull/1755)
|
||||
- OnlyOffice
|
||||
- New OnlyOffice default config options [#1820](https://github.com/cryptpad/cryptpad/pull/1820)
|
||||
- Add `--check`, `--rdfind`, `--no-rdfind` options to `install-onlyoffice.sh` [#1740](https://github.com/cryptpad/cryptpad/pull/1740) thanks to @jfly
|
||||
- OnlyOffice configurations (compact header, hide right menu, light/dark theme) [d1799d1](https://github.com/cryptpad/cryptpad/commit/d1799d106cd45b1f97251f9e0451cd519eb169d0)
|
||||
- Treat relative URLs in the sandbox as relative to the outer domain [#1752](https://github.com/cryptpad/cryptpad/pull/1752) thanks to @ansuz
|
||||
- Blob metadata refactoring [#1800](https://github.com/cryptpad/cryptpad/pull/1800)
|
||||
- Reload server subprocesses after a configured number of tasks [#1796](https://github.com/cryptpad/cryptpad/pull/1796)
|
||||
- Reduce server memory usage when accessing document history [#1795](https://github.com/cryptpad/cryptpad/pull/1795)
|
||||
- Add descriptive error messages [#1789](https://github.com/cryptpad/cryptpad/pull/1789)
|
||||
- Add Skip Link [#1774](https://github.com/cryptpad/cryptpad/pull/1774)
|
||||
|
||||
## Fixes
|
||||
|
||||
- Kanban
|
||||
- Fix kanban cursor issues when editing collaboratively [#1816](https://github.com/cryptpad/cryptpad/pull/1816)
|
||||
- Kanban "See all tags" button fix [#1812](https://github.com/cryptpad/cryptpad/pull/1812)
|
||||
- Enable keyboard usage for "Add Item" buttons in Kanban [#1802](https://github.com/cryptpad/cryptpad/pull/1802)
|
||||
- Forms
|
||||
- Conditional section after page break [#1749](https://github.com/cryptpad/cryptpad/pull/1749)
|
||||
- Fix long question text overflow and weird sizing of the required label in forms [#1747](https://github.com/cryptpad/cryptpad/pull/1747)
|
||||
- Drive
|
||||
- Fix anonymous drive download [#1784](https://github.com/cryptpad/cryptpad/pull/1784)
|
||||
- Form answers Drive download [#1711](https://github.com/cryptpad/cryptpad/pull/1711)
|
||||
- Prevent saving file to Drive multiple times [#1775](https://github.com/cryptpad/cryptpad/pull/1775)
|
||||
- Links
|
||||
- Fix link dialog focus issues & Improve error handling [#1758](https://github.com/cryptpad/cryptpad/pull/1758)
|
||||
- OnlyOffice
|
||||
- Fix /checkup/ false positive when OnlyOffice is not installed [#1731](https://github.com/cryptpad/cryptpad/pull/1731)
|
||||
- Large file uploads don't fail anymore on Chromium [#1783](https://github.com/cryptpad/cryptpad/issues/1783)
|
||||
- Fix blob Access-Control-Allow-Origin header [#1832](https://github.com/cryptpad/cryptpad/pull/1832)
|
||||
- Remove OCSP Stapling support for Nginx [#1818](https://github.com/cryptpad/cryptpad/pull/1818)
|
||||
- Notifications sidebar: Fix keyboard navigation issues [#1780](https://github.com/cryptpad/cryptpad/pull/1780)
|
||||
- Accessibility fixes to Admin UI [#1829](https://github.com/cryptpad/cryptpad/pull/1829)
|
||||
|
||||
<!---
|
||||
## Dependencies
|
||||
|
||||
nothing here?
|
||||
-->
|
||||
|
||||
## Upgrade notes
|
||||
|
||||
If you are upgrading from a version older than `2024.12.0` please read the upgrade notes of all versions between yours and `2025.3.0` to avoid configuration issues.
|
||||
|
||||
To upgrade:
|
||||
|
||||
1. Stop your server
|
||||
2. Get the latest code with git
|
||||
|
||||
```bash
|
||||
git fetch --depth 1 origin tag 2025.3.0
|
||||
git checkout 2025.3.0
|
||||
npm ci
|
||||
npm run install:components
|
||||
```
|
||||
|
||||
1. Restart your server
|
||||
2. Review your instance's checkup page to ensure that you are passing all tests
|
||||
|
||||
|
||||
### (Optional) Re-build the SharedWorker
|
||||
|
||||
|
||||
With this release we introduce `www/common/worker.bundle.min.js` which contains all code for the Shared Worker (thread common to all your CryptPad tabs) in a single built and minified file.
|
||||
|
||||
You can build this file yourself with `npm run api` before restarting the server.
|
||||
|
||||
**Note:** You must install the dev dependencies from npm if you want to build this command (don't use the `--production` flag)
|
||||
|
||||
|
||||
## Contributors
|
||||
|
||||
Community: @jfly, @nisbet-hubbard
|
||||
|
||||
Alumni: @ansuz
|
||||
|
||||
CryptPad team: @AAAMON @Chouhartem @dariiing @davidbenque @DianaXWIKI @mathilde-cryptpad @wginolas @yflory @zuzanna-maria
|
||||
|
||||
|
||||
|
||||
# ❄️ Winter release (2024.12.0)
|
||||
|
||||
|
||||
10
LICENSES/Unlicense.txt
Normal file
10
LICENSES/Unlicense.txt
Normal file
@ -0,0 +1,10 @@
|
||||
This is free and unencumbered software released into the public domain.
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means.
|
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors of this software dedicate any and all copyright interest in the software to the public domain. We make this dedication for the benefit of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
For more information, please refer to <http://unlicense.org/>
|
||||
238
REUSE.toml
Normal file
238
REUSE.toml
Normal file
@ -0,0 +1,238 @@
|
||||
version = 1
|
||||
SPDX-PackageName = "CryptPad"
|
||||
SPDX-PackageSupplier = "XWiki <contact@cryptpad.org>"
|
||||
SPDX-PackageDownloadLocation = "https://cryptpad.org"
|
||||
|
||||
[[annotations]]
|
||||
path = "**.png"
|
||||
precedence = "aggregate"
|
||||
SPDX-FileCopyrightText = "2023 XWiki CryptPad Team <contact@cryptpad.org> and contributors"
|
||||
SPDX-License-Identifier = "AGPL-3.0-or-later"
|
||||
|
||||
[[annotations]]
|
||||
path = "**.json"
|
||||
precedence = "aggregate"
|
||||
SPDX-FileCopyrightText = "2023 XWiki CryptPad Team <contact@cryptpad.org> and contributors"
|
||||
SPDX-License-Identifier = "AGPL-3.0-or-later"
|
||||
|
||||
[[annotations]]
|
||||
path = ".jshintignore"
|
||||
precedence = "aggregate"
|
||||
SPDX-FileCopyrightText = "2023 XWiki CryptPad Team <contact@cryptpad.org> and contributors"
|
||||
SPDX-License-Identifier = "AGPL-3.0-or-later"
|
||||
|
||||
[[annotations]]
|
||||
path = ".jshintrc"
|
||||
precedence = "aggregate"
|
||||
SPDX-FileCopyrightText = "2023 XWiki CryptPad Team <contact@cryptpad.org> and contributors"
|
||||
SPDX-License-Identifier = "AGPL-3.0-or-later"
|
||||
|
||||
[[annotations]]
|
||||
path = ".stylelintrc.js"
|
||||
precedence = "aggregate"
|
||||
SPDX-FileCopyrightText = "2023 XWiki CryptPad Team <contact@cryptpad.org> and contributors"
|
||||
SPDX-License-Identifier = "AGPL-3.0-or-later"
|
||||
|
||||
[[annotations]]
|
||||
path = "scripts/tests/test-data/**"
|
||||
precedence = "aggregate"
|
||||
SPDX-FileCopyrightText = "2024 XWiki CryptPad Team <contact@cryptpad.org> and contributors"
|
||||
SPDX-License-Identifier = "AGPL-3.0-or-later"
|
||||
|
||||
[[annotations]]
|
||||
path = "www/common/theme/**"
|
||||
precedence = "aggregate"
|
||||
SPDX-FileCopyrightText = "2017 by Marijn Haverbeke <marijn@haverbeke.berlin> and others"
|
||||
SPDX-License-Identifier = "MIT"
|
||||
|
||||
[[annotations]]
|
||||
path = "www/lib/mermaid/**"
|
||||
precedence = "aggregate"
|
||||
SPDX-FileCopyrightText = "(c) 2014 - 2021 Knut Sveidqvist"
|
||||
SPDX-License-Identifier = "MIT"
|
||||
|
||||
[[annotations]]
|
||||
path = "www/lib/calendar/moment.min.js"
|
||||
precedence = "aggregate"
|
||||
SPDX-FileCopyrightText = "(c) JS Foundation and other contributors"
|
||||
SPDX-License-Identifier = "MIT"
|
||||
|
||||
[[annotations]]
|
||||
path = "www/lib/pdfjs/**"
|
||||
precedence = "aggregate"
|
||||
SPDX-FileCopyrightText = "2017 Mozilla Foundation"
|
||||
SPDX-License-Identifier = "Apache-2.0"
|
||||
|
||||
[[annotations]]
|
||||
path = "www/lib/codemirror-extra-modes/asciidoc/**"
|
||||
precedence = "aggregate"
|
||||
SPDX-FileCopyrightText = "(c) 2015, the Asciidoctor Project"
|
||||
SPDX-License-Identifier = "BSD-3-Clause"
|
||||
|
||||
[[annotations]]
|
||||
path = "www/lib/datepicker/**"
|
||||
precedence = "aggregate"
|
||||
SPDX-FileCopyrightText = "2017 Gregory Petrosyan"
|
||||
SPDX-License-Identifier = "MIT"
|
||||
|
||||
[[annotations]]
|
||||
path = "www/lib/diff-dom/**"
|
||||
precedence = "aggregate"
|
||||
SPDX-FileCopyrightText = "Johannes Wilm, Fidus Writer"
|
||||
SPDX-License-Identifier = "LGPL-3.0-only"
|
||||
|
||||
[[annotations]]
|
||||
path = "www/lib/fabric-history.min.js"
|
||||
precedence = "aggregate"
|
||||
SPDX-FileCopyrightText = "2008-2015 Printio (Juriy Zaytsev, Maxim Chernyak)"
|
||||
SPDX-License-Identifier = "MIT"
|
||||
|
||||
[[annotations]]
|
||||
path = "www/lib/fabric.min.js"
|
||||
precedence = "aggregate"
|
||||
SPDX-FileCopyrightText = "2008-2015 Printio (Juriy Zaytsev, Maxim Chernyak)"
|
||||
SPDX-License-Identifier = "MIT"
|
||||
|
||||
[[annotations]]
|
||||
path = "www/lib/pdfjs/**"
|
||||
precedence = "aggregate"
|
||||
SPDX-FileCopyrightText = "2012 Mozilla Foundation"
|
||||
SPDX-License-Identifier = "Apache-2.0"
|
||||
|
||||
[[annotations]]
|
||||
path = "www/lib/qrcode.min.js"
|
||||
precedence = "aggregate"
|
||||
SPDX-FileCopyrightText = "Sangmin Shim"
|
||||
SPDX-License-Identifier = "MIT"
|
||||
|
||||
[[annotations]]
|
||||
path = "www/lib/rangy/rangy-core.min.js"
|
||||
precedence = "aggregate"
|
||||
SPDX-FileCopyrightText = "2015, Tim Down"
|
||||
SPDX-License-Identifier = "MIT"
|
||||
|
||||
[[annotations]]
|
||||
path = "www/lib/textFit.min.js"
|
||||
precedence = "aggregate"
|
||||
SPDX-FileCopyrightText = "11/2014 by STRML (strml.github.com)"
|
||||
SPDX-License-Identifier = "MIT"
|
||||
|
||||
[[annotations]]
|
||||
path = "www/lib/tippy/**"
|
||||
precedence = "aggregate"
|
||||
SPDX-FileCopyrightText = "2017 atomiks"
|
||||
SPDX-License-Identifier = "MIT"
|
||||
|
||||
[[annotations]]
|
||||
path = "www/lib/turndown.browser.umd.js"
|
||||
precedence = "aggregate"
|
||||
SPDX-FileCopyrightText = "2017 Dom Christie"
|
||||
SPDX-License-Identifier = "MIT"
|
||||
|
||||
[[annotations]]
|
||||
path = "www/lib/markmap/**"
|
||||
precedence = "aggregate"
|
||||
SPDX-FileCopyrightText = "2015 Jakub Dundalek"
|
||||
SPDX-License-Identifier = "MIT"
|
||||
|
||||
[[annotations]]
|
||||
path = "www/pad/mathjax/**"
|
||||
precedence = "aggregate"
|
||||
SPDX-FileCopyrightText = "2009-2018 The MathJax Consortium"
|
||||
SPDX-License-Identifier = "Apache-2.0"
|
||||
|
||||
[[annotations]]
|
||||
path = "www/pad/wordcount/**"
|
||||
precedence = "aggregate"
|
||||
SPDX-FileCopyrightText = "Ingo Herbote"
|
||||
SPDX-License-Identifier = "MIT"
|
||||
|
||||
[[annotations]]
|
||||
path = "www/pad/wysiwygarea-plugin.js"
|
||||
precedence = "aggregate"
|
||||
SPDX-FileCopyrightText = "2003-2017, CKSource - Frederico Knabben. All rights reserved"
|
||||
SPDX-License-Identifier = "GPL-2.0-or-later"
|
||||
|
||||
[[annotations]]
|
||||
path = "www/pad/icons/**"
|
||||
precedence = "aggregate"
|
||||
SPDX-FileCopyrightText = "unknown"
|
||||
SPDX-License-Identifier = "GPL-2.0-or-later"
|
||||
|
||||
[[annotations]]
|
||||
path = "www/common/onlyoffice/AllFonts.js"
|
||||
precedence = "aggregate"
|
||||
SPDX-FileCopyrightText = "Ascensio System Limited 2010-2022"
|
||||
SPDX-License-Identifier = "AGPL-3.0-or-later"
|
||||
|
||||
[[annotations]]
|
||||
path = "www/common/onlyoffice/fonts_thumbnail.png"
|
||||
precedence = "aggregate"
|
||||
SPDX-FileCopyrightText = "Ascensio System Limited 2010-2022"
|
||||
SPDX-License-Identifier = "AGPL-3.0-or-later"
|
||||
|
||||
[[annotations]]
|
||||
path = "www/common/onlyoffice/fonts_thumbnail@2x.png"
|
||||
precedence = "aggregate"
|
||||
SPDX-FileCopyrightText = "Ascensio System Limited 2010-2022"
|
||||
SPDX-License-Identifier = "AGPL-3.0-or-later"
|
||||
|
||||
[[annotations]]
|
||||
path = "www/common/onlyoffice/plugins.json"
|
||||
precedence = "aggregate"
|
||||
SPDX-FileCopyrightText = "Ascensio System Limited 2010-2022"
|
||||
SPDX-License-Identifier = "AGPL-3.0-or-later"
|
||||
|
||||
[[annotations]]
|
||||
path = "www/common/onlyoffice/v1/**"
|
||||
precedence = "aggregate"
|
||||
SPDX-FileCopyrightText = "Ascensio System Limited 2010-2022"
|
||||
SPDX-License-Identifier = "AGPL-3.0-or-later"
|
||||
|
||||
[[annotations]]
|
||||
path = "www/common/onlyoffice/v2b/**"
|
||||
precedence = "aggregate"
|
||||
SPDX-FileCopyrightText = "Ascensio System Limited 2010-2022"
|
||||
SPDX-License-Identifier = "AGPL-3.0-or-later"
|
||||
|
||||
[[annotations]]
|
||||
path = "www/common/onlyoffice/v4/**"
|
||||
precedence = "aggregate"
|
||||
SPDX-FileCopyrightText = "Ascensio System Limited 2010-2022"
|
||||
SPDX-License-Identifier = "AGPL-3.0-or-later"
|
||||
|
||||
[[annotations]]
|
||||
path = "www/common/onlyoffice/v5/**"
|
||||
precedence = "aggregate"
|
||||
SPDX-FileCopyrightText = "Ascensio System Limited 2010-2022"
|
||||
SPDX-License-Identifier = "AGPL-3.0-or-later"
|
||||
|
||||
[[annotations]]
|
||||
path = "www/common/onlyoffice/v6/**"
|
||||
precedence = "aggregate"
|
||||
SPDX-FileCopyrightText = "Ascensio System Limited 2010-2022"
|
||||
SPDX-License-Identifier = "AGPL-3.0-or-later"
|
||||
|
||||
[[annotations]]
|
||||
path = "www/common/onlyoffice/v7/**"
|
||||
precedence = "aggregate"
|
||||
SPDX-FileCopyrightText = "Ascensio System Limited 2010-2022"
|
||||
SPDX-License-Identifier = "AGPL-3.0-or-later"
|
||||
|
||||
[[annotations]]
|
||||
path = "www/common/onlyoffice/x2t/**"
|
||||
precedence = "aggregate"
|
||||
SPDX-FileCopyrightText = "Ascensio System Limited 2010-2022"
|
||||
SPDX-License-Identifier = "AGPL-3.0-or-later"
|
||||
|
||||
[[annotations]]
|
||||
path = "src/tweetnacl/**"
|
||||
precedence = "aggregate"
|
||||
SPDX-FileCopyrightText = "Unknown"
|
||||
SPDX-License-Identifier = "Unlicense"
|
||||
|
||||
[[annotations]]
|
||||
path = "www/common/worker.bundle.min.js"
|
||||
precedence = "aggregate"
|
||||
SPDX-FileCopyrightText = "2025 XWiki CryptPad Team <contact@cryptpad.org> and contributors"
|
||||
SPDX-License-Identifier = "AGPL-3.0-or-later"
|
||||
@ -117,7 +117,6 @@ define(req, function(AppConfig, Default, Language) {
|
||||
|
||||
Messages._languages = map;
|
||||
Messages._languageUsed = language;
|
||||
|
||||
// Get keys with parameters
|
||||
Messages._getKey = function (key, argArray) {
|
||||
if (!Messages[key]) { return '?'; }
|
||||
@ -135,22 +134,7 @@ define(req, function(AppConfig, Default, Language) {
|
||||
}
|
||||
};
|
||||
|
||||
// XXX
|
||||
Messages.admin_cat_admins = "Administrators";
|
||||
Messages.admin_admin = "Admin";
|
||||
Messages.admin_listAdminsTitle = "Current administrators";
|
||||
Messages.admin_listAdminsHint = "View and remove administrators";
|
||||
Messages.admin_addAdminsTitle = "Add administrators";
|
||||
Messages.admin_addAdminsHint = "Add administrators from their public key or from your contacts list";
|
||||
Messages.admin_addAdminsAdd = "Promote a contact to admin";
|
||||
Messages.admin_addKeyLabel = "Add an admin using their public key";
|
||||
|
||||
Messages.admin_listName = "Admin name";
|
||||
Messages.admin_listKey = "Admin key";
|
||||
Messages.admin_listAction = "Remove admin rights";
|
||||
|
||||
Messages.admin_listHardcoded = "Admin added into config.js. Can only be removed by editing the config file.";
|
||||
Messages.admin_listConfirm = "Are you sure you want to remove the admin rights of this user?";
|
||||
|
||||
|
||||
return Messages;
|
||||
|
||||
|
||||
@ -165,6 +165,10 @@
|
||||
@cp_buttons-default: @cryptpad_color_grey_700;
|
||||
@cp_buttons-default-color: @cryptpad_text_col;
|
||||
@cp_buttons-default-border: @cryptpad_text_col;
|
||||
@cp_buttons-default-bg: @cryptpad_text_col;
|
||||
@cp_buttons-default-fg: @cryptpad_color_grey_900;
|
||||
@cp_buttons-default-alt-bg: @cryptpad_color_grey_900;
|
||||
@cp_buttons-default-alt-fg: @cryptpad_text_col;
|
||||
@cp_buttons-red: #E55236;
|
||||
@cp_buttons-red-text: @cryptpad_color_light_red;
|
||||
@cp_buttons-red-color: #FFF;
|
||||
|
||||
@ -164,6 +164,10 @@
|
||||
@cp_buttons-default: #CCC;
|
||||
@cp_buttons-default-color: @cryptpad_text_col;
|
||||
@cp_buttons-default-border: @cryptpad_text_col;
|
||||
@cp_buttons-default-bg: @cryptpad_color_grey_200;
|
||||
@cp_buttons-default-fg: @cryptpad_text_col;
|
||||
@cp_buttons-default-alt-bg: @cryptpad_color_white;
|
||||
@cp_buttons-default-alt-fg: @cryptpad_text_col;
|
||||
@cp_buttons-red: #E55236;
|
||||
@cp_buttons-red-text: @cp_buttons-red;
|
||||
@cp_buttons-red-color: #FFF;
|
||||
|
||||
@ -199,6 +199,24 @@
|
||||
background-color: @cp_buttons-default;
|
||||
}
|
||||
}
|
||||
&.btn-toolbar {
|
||||
background-color: @cp_buttons-default-bg;
|
||||
color: @cp_buttons-default-fg;
|
||||
border-color: @cp_buttons-default-bg;
|
||||
&:hover, &:not(:disabled):active, &:focus {
|
||||
background-color: fade(@cryptpad_text_col, 20%);
|
||||
border-color: @cryptpad_text_col;
|
||||
color: @cryptpad_text_col;
|
||||
}
|
||||
}
|
||||
&.btn-toolbar-alt {
|
||||
border-color: @cp_buttons-default-alt-fg;
|
||||
color: @cp_buttons-default-alt-fg;
|
||||
background-color: @cp_buttons-default-alt-bg;
|
||||
&:hover, &:not(:disabled):active, &:focus {
|
||||
background-color: fade(@cryptpad_text_col, 20%);
|
||||
}
|
||||
}
|
||||
|
||||
&.danger, &.btn-danger {
|
||||
background-color: @cp_buttons-red;
|
||||
|
||||
@ -71,6 +71,7 @@
|
||||
button {
|
||||
height: @toolbar_line-height !important;
|
||||
outline: 0;
|
||||
border-radius: @variables_radius;
|
||||
color: @toolbar-color;
|
||||
.toolbar_button;
|
||||
font: normal normal normal 14px/1 FontAwesome;
|
||||
@ -445,6 +446,23 @@
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.cp-toolbar-skip-link {
|
||||
position: absolute;
|
||||
top: -100px;
|
||||
left: 45%;
|
||||
background-color: @cp_buttons-primary;
|
||||
color: @cp_buttons-primary-text;
|
||||
padding: 0.3rem 0.5rem;
|
||||
font-size: 1rem;
|
||||
text-decoration: none;
|
||||
border-radius: @variables_radius;
|
||||
z-index: 1000;
|
||||
transition: top 0.3s ease;
|
||||
}
|
||||
.cp-toolbar-skip-link:focus {
|
||||
top: 10px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: @browser_media-medium-screen),
|
||||
screen and (max-height: 500px) {
|
||||
flex-wrap: wrap;
|
||||
|
||||
@ -89,16 +89,6 @@ server {
|
||||
# HSTS (ngx_http_headers_module is required) (63072000 seconds)
|
||||
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
|
||||
|
||||
# OCSP stapling
|
||||
ssl_stapling on;
|
||||
ssl_stapling_verify on;
|
||||
|
||||
# verify chain of trust of OCSP response using Root CA and Intermediate certs
|
||||
ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt;
|
||||
|
||||
# replace with the IP address of your resolver
|
||||
resolver 8.8.8.8 8.8.4.4 1.1.1.1 1.0.0.1 9.9.9.9 149.112.112.112 208.67.222.222 208.67.220.220;
|
||||
|
||||
# OnlyOffice fonts may be loaded from both domains
|
||||
if ($uri ~ ^/common/onlyoffice/.*/fonts/) { set $allowed_origins "*"; }
|
||||
|
||||
|
||||
@ -65,16 +65,6 @@ server {
|
||||
# HSTS (ngx_http_headers_module is required) (63072000 seconds)
|
||||
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
|
||||
|
||||
# OCSP stapling
|
||||
ssl_stapling on;
|
||||
ssl_stapling_verify on;
|
||||
|
||||
# verify chain of trust of OCSP response using Root CA and Intermediate certs
|
||||
ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt;
|
||||
|
||||
# replace with the IP address of your resolver
|
||||
resolver 8.8.8.8 8.8.4.4 1.1.1.1 1.0.0.1 9.9.9.9 149.112.112.112 208.67.222.222 208.67.220.220;
|
||||
|
||||
location / {
|
||||
proxy_pass http://localhost:3000;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
|
||||
@ -44,9 +44,10 @@ module.exports = [{
|
||||
"www/code/mermaid*.js",
|
||||
"www/code/orgmode.js",
|
||||
"www/common/worker.bundle.js",
|
||||
"www/common/worker.bundle.min.js",
|
||||
"src/tweetnacl",
|
||||
"_build",
|
||||
"testapi.js",
|
||||
"scripts/api/testapi.js",
|
||||
"rollup.config.mjs",
|
||||
],
|
||||
}, ...compat.extends("eslint:recommended", "plugin:compat/recommended"), {
|
||||
@ -70,6 +71,7 @@ module.exports = [{
|
||||
"linebreak-style": ["off", "unix"],
|
||||
quotes: ["off", "single"],
|
||||
semi: ["error", "always"],
|
||||
eqeqeq: ["error", "always"],
|
||||
"no-irregular-whitespace": ["off"],
|
||||
"no-self-assign": ["off"],
|
||||
"no-empty": ["off"],
|
||||
|
||||
@ -37,7 +37,17 @@ main() {
|
||||
install_x2t v7.3+1 ab0c05b0e4c81071acea83f0c6a8e75f5870c360ec4abc4af09105dd9b52264af9711ec0b7020e87095193ac9b6e20305e446f2321a541f743626a598e5318c1
|
||||
|
||||
rm -rf "$BUILDS_DIR"
|
||||
if command -v rdfind &>/dev/null; then
|
||||
|
||||
if [ "${RDFIND+x}" != "x" ]; then
|
||||
if command -v rdfind &>/dev/null; then
|
||||
RDFIND="1"
|
||||
else
|
||||
RDFIND="0"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$RDFIND" = "1" ]; then
|
||||
ensure_command_available rdfind
|
||||
rdfind -makehardlinks true -makeresultsfile false $OO_DIR/v*
|
||||
fi
|
||||
}
|
||||
@ -73,6 +83,18 @@ parse_arguments() {
|
||||
TRUST_REPOSITORY="1"
|
||||
shift
|
||||
;;
|
||||
--check)
|
||||
CHECK="1"
|
||||
shift
|
||||
;;
|
||||
--rdfind)
|
||||
RDFIND="1"
|
||||
shift
|
||||
;;
|
||||
--no-rdfind)
|
||||
RDFIND="0"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
show_help
|
||||
shift
|
||||
@ -103,9 +125,6 @@ show_help() {
|
||||
cat <<EOF
|
||||
install-onlyoffice installs or upgrades OnlyOffice.
|
||||
|
||||
NOTE: When you have rdfind installed, it will be used to save ~650MB of disk
|
||||
space.
|
||||
|
||||
OPTIONS:
|
||||
-h, --help
|
||||
Show this help.
|
||||
@ -120,6 +139,18 @@ OPTIONS:
|
||||
as a safe.directory.
|
||||
https://git-scm.com/docs/git-config/#Documentation/git-config.txt-safedirectory
|
||||
|
||||
--check
|
||||
Do not install OnlyOffice, only check if the existing installation
|
||||
is up to date. Exits 0 if it is up to date, nonzero otherwise.
|
||||
|
||||
--rdfind
|
||||
Run rdfind to save ~650MB of disk space.
|
||||
If neither '--rdfind' nor '--no-rdfind' is specified, then rdfind
|
||||
will only run if rdfind is installed.
|
||||
|
||||
--no-rdfind
|
||||
Do not run rdfind, even if it is installed.
|
||||
|
||||
EOF
|
||||
exit 1
|
||||
}
|
||||
@ -143,7 +174,17 @@ install_version() {
|
||||
local LAST_DIR
|
||||
LAST_DIR=$(pwd)
|
||||
|
||||
if [ ! -e "$FULL_DIR"/.commit ] || [ "$(cat "$FULL_DIR"/.commit)" != "$COMMIT" ]; then
|
||||
local ACTUAL_COMMIT="not installed"
|
||||
if [ -e "$FULL_DIR"/.commit ]; then
|
||||
ACTUAL_COMMIT="$(cat "$FULL_DIR"/.commit)"
|
||||
fi
|
||||
|
||||
if [ "$ACTUAL_COMMIT" != "$COMMIT" ]; then
|
||||
if [ ${CHECK+x} ]; then
|
||||
echo "Wrong commit of $FULL_DIR found. Expected: $COMMIT. Actual: $ACTUAL_COMMIT"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ensure_oo_is_downloaded
|
||||
|
||||
rm -rf "$FULL_DIR"
|
||||
@ -166,22 +207,31 @@ install_version() {
|
||||
}
|
||||
|
||||
install_x2t() {
|
||||
ensure_command_available curl
|
||||
ensure_command_available sha512sum
|
||||
ensure_command_available unzip
|
||||
|
||||
local VERSION=$1
|
||||
local HASH=$2
|
||||
local LAST_DIR
|
||||
LAST_DIR=$(pwd)
|
||||
local X2T_DIR=$OO_DIR/x2t
|
||||
|
||||
local ACTUAL_VERSION="not installed"
|
||||
if [ -e "$X2T_DIR"/.version ]; then
|
||||
ACTUAL_VERSION="$(cat "$X2T_DIR"/.version)"
|
||||
fi
|
||||
|
||||
if [ ! -e "$X2T_DIR"/.version ] || [ "$(cat "$X2T_DIR"/.version)" != "$VERSION" ]; then
|
||||
if [ ${CHECK+x} ]; then
|
||||
echo "Wrong version of x2t found. Expected: $VERSION. Actual: $ACTUAL_VERSION"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
rm -rf "$X2T_DIR"
|
||||
mkdir -p "$X2T_DIR"
|
||||
|
||||
cd "$X2T_DIR"
|
||||
|
||||
ensure_command_available curl
|
||||
ensure_command_available sha512sum
|
||||
ensure_command_available unzip
|
||||
curl "https://github.com/cryptpad/onlyoffice-x2t-wasm/releases/download/$VERSION/x2t.zip" --location --output x2t.zip
|
||||
# curl "https://github.com/cryptpad/onlyoffice-x2t-wasm/releases/download/v7.3%2B1/x2t.zip" --location --output x2t.zip
|
||||
echo "$HASH x2t.zip" >x2t.zip.sha512
|
||||
|
||||
@ -80,7 +80,7 @@ Data.setMetadata = function (Env, safeKey, data, cb, Server) {
|
||||
|
||||
var channel = data.channel;
|
||||
var command = data.command;
|
||||
// XXX BLOBMD allow blobs
|
||||
|
||||
if (!channel || !Core.isValidId(channel)) { return void cb ('INVALID_CHAN'); }
|
||||
if (!command || typeof (command) !== 'string') { return void cb('INVALID_COMMAND'); }
|
||||
if (Meta.commands.indexOf(command) === -1) { return void cb('UNSUPPORTED_COMMAND'); }
|
||||
@ -142,7 +142,6 @@ Data.setMetadata = function (Env, safeKey, data, cb, Server) {
|
||||
cb(void 0, metadata);
|
||||
return void next();
|
||||
}
|
||||
// XXX BLOBMD use correct store for blobs
|
||||
Env.msgStore.writeMetadata(channel, JSON.stringify(line), function (e) {
|
||||
if (e) {
|
||||
cb(e);
|
||||
@ -158,7 +157,7 @@ Data.setMetadata = function (Env, safeKey, data, cb, Server) {
|
||||
|
||||
// update the cached metadata
|
||||
metadata_cache[channel] = metadata;
|
||||
Env.checkCache(channel); // XXX ???
|
||||
Env.checkCache(channel);
|
||||
|
||||
// it's easy to check if the channel is restricted
|
||||
const isRestricted = metadata.restricted;
|
||||
|
||||
11
lib/env.js
11
lib/env.js
@ -242,9 +242,14 @@ module.exports.create = function (config) {
|
||||
sso: plugins?.SSO?.config || {},
|
||||
enforceMFA: config.enforceMFA,
|
||||
|
||||
onlyOffice: {
|
||||
availableVersions: getInstalledOOVersions()
|
||||
},
|
||||
...(getInstalledOOVersions().length > 0
|
||||
? {
|
||||
onlyOffice: {
|
||||
availableVersions: getInstalledOOVersions(),
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
|
||||
|
||||
// initialized as undefined
|
||||
bearerSecret: void 0,
|
||||
|
||||
@ -767,15 +767,16 @@ const handleGetHistoryRange = function (Env, Server, seq, userId, parsed) {
|
||||
var channelName = parsed[1];
|
||||
var map = parsed[2];
|
||||
const HISTORY_KEEPER_ID = Env.id;
|
||||
const store = Env.store;
|
||||
|
||||
if (!(map && typeof(map) === 'object')) {
|
||||
return void Server.send(userId, [seq, 'ERROR', 'INVALID_ARGS', HISTORY_KEEPER_ID]);
|
||||
}
|
||||
|
||||
var oldestKnownHash = map.from;
|
||||
var untilHash = map.to;
|
||||
var desiredMessages = map.count;
|
||||
var desiredCheckpoint = map.cpCount;
|
||||
var oldestKnownHash = map.from; // last known hash
|
||||
var untilHash = map.to; // oldest hash (unknown), start point if defined
|
||||
var desiredMessages = map.count; // nb messages before lkh
|
||||
var desiredCheckpoint = map.cpCount; // nb cp before lkh
|
||||
var txid = map.txid;
|
||||
if (typeof(desiredMessages) !== 'number' && typeof(desiredCheckpoint) !== 'number' && !untilHash) {
|
||||
return void Server.send(userId, [seq, 'ERROR', 'UNSPECIFIED_COUNT', HISTORY_KEEPER_ID]);
|
||||
@ -786,6 +787,43 @@ const handleGetHistoryRange = function (Env, Server, seq, userId, parsed) {
|
||||
}
|
||||
|
||||
Server.send(userId, [seq, 'ACK']);
|
||||
|
||||
if (untilHash) {
|
||||
// Get all messages between untilHash (oldest but unknown)
|
||||
// and oldestKnownHesh (last known hash) (or until the end if undefined)
|
||||
// Messages can be streamed since we instantly know the start point
|
||||
let found = false;
|
||||
store.readMessagesBin(channelName, 0, (msgObj, readMore, abort) => {
|
||||
const parsed = tryParse(Env, msgObj.buff.toString('utf8'));
|
||||
if (!parsed) { return void readMore(); }
|
||||
if (isMetadataMessage(parsed)) { return void readMore(); }
|
||||
const content = parsed[4];
|
||||
if (typeof(content) !== 'string') { return void readMore(); }
|
||||
|
||||
const hash = getHash(content);
|
||||
if (hash === untilHash || untilHash === 'NONE') { found = true; }
|
||||
let then = hash === oldestKnownHash ? abort : readMore;
|
||||
if (found) {
|
||||
Server.send(userId, [0, HISTORY_KEEPER_ID, 'MSG', userId,
|
||||
JSON.stringify(['HISTORY_RANGE', txid, parsed])], then);
|
||||
}
|
||||
return void readMore();
|
||||
}, function (err, reason) {
|
||||
if (err) {
|
||||
Env.Log.error("HK_GET_OLDER_HISTORY", channelName, err, reason);
|
||||
Server.send(userId, [0, HISTORY_KEEPER_ID, 'MSG', userId,
|
||||
JSON.stringify(['HISTORY_RANGE_ERROR', txid, err])
|
||||
]);
|
||||
return;
|
||||
}
|
||||
Server.send(userId, [0, HISTORY_KEEPER_ID, 'MSG', userId,
|
||||
JSON.stringify(['HISTORY_RANGE_END', txid, channelName])
|
||||
]);
|
||||
});
|
||||
return;
|
||||
}
|
||||
// If desiredCp or desiredMsg are defined, we can't stream and must
|
||||
// get a list of messages to send from a worker
|
||||
Env.getOlderHistory(channelName, oldestKnownHash, untilHash, desiredMessages, desiredCheckpoint, function (err, toSend) {
|
||||
if (err && err.code !== 'ENOENT') {
|
||||
Env.Log.error("HK_GET_OLDER_HISTORY", err);
|
||||
|
||||
@ -145,7 +145,7 @@ var cacheHeaders = function (Env, key, headers) {
|
||||
|
||||
var getHeaders = function (Env, type) {
|
||||
var key = type + 'HeadersCache';
|
||||
if (Env[key]) { return Env[key]; }
|
||||
if (Env[key]) { return Util.clone(Env[key]); }
|
||||
|
||||
var headers = Default.httpHeaders(Env);
|
||||
|
||||
@ -165,7 +165,7 @@ var getHeaders = function (Env, type) {
|
||||
// when duplicated by NGINX in production environments
|
||||
if (type === 'api') { delete headers['Content-Security-Policy']; }
|
||||
|
||||
return headers;
|
||||
return Util.clone(headers);
|
||||
};
|
||||
|
||||
var setHeaders = function (req, res) {
|
||||
@ -326,6 +326,12 @@ app.use(function (req, res, next) {
|
||||
next();
|
||||
});
|
||||
|
||||
Object.keys(plugins || {}).forEach(name => {
|
||||
let plugin = plugins[name];
|
||||
if (!plugin.addHttpEndpoints) { return; }
|
||||
plugin.addHttpEndpoints(Env, app);
|
||||
});
|
||||
|
||||
|
||||
// serve custom app content from the customize directory
|
||||
// useful for testing pages customized with opengraph data
|
||||
@ -359,9 +365,14 @@ app.use('/block/', function (req, res, next) {
|
||||
// block access control only applies to files
|
||||
// identified by base64-encoded public keys
|
||||
// skip everything else, ie. /block/placeholder.txt
|
||||
if (typeof(name) !== 'string' || name.length !== 44) {
|
||||
if (/placeholder\.txt(\?.+)?/.test(parsed.base)) {
|
||||
return void next();
|
||||
}
|
||||
if (typeof(name) !== 'string' || name.length !== 44) {
|
||||
return void res.status(404).json({
|
||||
error: "INVALID_ID",
|
||||
});
|
||||
}
|
||||
|
||||
var authorization = req.headers.authorization;
|
||||
|
||||
@ -531,12 +542,6 @@ app.use("/block", (req, res, next) => {
|
||||
next();
|
||||
});
|
||||
|
||||
Object.keys(plugins || {}).forEach(name => {
|
||||
let plugin = plugins[name];
|
||||
if (!plugin.addHttpEndpoints) { return; }
|
||||
plugin.addHttpEndpoints(Env, app);
|
||||
});
|
||||
|
||||
app.use("/customize", Express.static('customize'));
|
||||
app.use("/customize", Express.static('customize.dist'));
|
||||
app.use("/customize.dist", Express.static('customize.dist'));
|
||||
|
||||
@ -234,7 +234,7 @@ var writeMetadata = function (env, channelId, data, cb) {
|
||||
var archiveMetadata = (Env, blobId, cb) => {
|
||||
var path = mkMetadataPath(Env, blobId);
|
||||
var archivePath = prependArchive(Env, path);
|
||||
// XXX eviction clean lone md files
|
||||
// TODO eviction clean lone md files
|
||||
// if we fail to delete the metadata file, it can still be removed later by the eviction script
|
||||
Fse.move(path, archivePath, { overwrite: true }, cb);
|
||||
};
|
||||
|
||||
@ -366,7 +366,7 @@ var readMessages = function (path, msgHandler, _cb) {
|
||||
return readFileBin(stream, function (msgObj, readMore) {
|
||||
collector.keepAlive();
|
||||
msgHandler(msgObj.buff.toString('utf8'));
|
||||
readMore();
|
||||
setTimeout(readMore);
|
||||
}, function (err) {
|
||||
cb(err);
|
||||
});
|
||||
|
||||
@ -40,7 +40,7 @@ Logger.levels.forEach(function (level) {
|
||||
};
|
||||
});
|
||||
|
||||
const HISTORY_SIZE_LIMIT = 1024 * 1024 * 1024; // XXX 1GB
|
||||
//const HISTORY_SIZE_LIMIT = 1024 * 1024 * 1024; // 1GB
|
||||
|
||||
var DETAIL = 1000;
|
||||
var round = function (n) {
|
||||
@ -396,11 +396,50 @@ const getFileSize = function (data, cb) {
|
||||
|
||||
const getOlderHistory = function (data, cb) {
|
||||
const oldestKnownHash = data.hash;
|
||||
const untilHash = data.toHash;
|
||||
const channelName = data.channel;
|
||||
const desiredMessages = data.desiredMessages;
|
||||
const desiredCheckpoint = data.desiredCheckpoint;
|
||||
|
||||
let messages = [];
|
||||
store.readMessagesBin(channelName, 0, (msgObj, readMore, abort) => {
|
||||
const parsed = HK.tryParse(Env, msgObj.buff.toString('utf8'));
|
||||
if (!parsed) { return void readMore(); }
|
||||
if (HK.isMetadataMessage(parsed)) { return void readMore(); }
|
||||
const content = parsed[4];
|
||||
if (typeof(content) !== 'string') { return void readMore(); }
|
||||
const hash = HK.getHash(content);
|
||||
|
||||
messages.push(parsed);
|
||||
|
||||
// "X" messages before oldestKnownHash
|
||||
if (typeof (desiredMessages) === "number") {
|
||||
messages = messages.slice(-desiredMessages);
|
||||
if (hash === oldestKnownHash) { return void abort(); }
|
||||
return void readMore();
|
||||
}
|
||||
|
||||
// "X" checkpoints before oldestKnownHash
|
||||
if (hash === oldestKnownHash) { return void abort(); }
|
||||
if (/^cp\|/.test(content)) { // clean whenever we push a cp
|
||||
let foundCp = 0;
|
||||
const idx = messages.findLastIndex(parsed => {
|
||||
let isCp = /^cp\|/.test(parsed[4]);
|
||||
if (!isCp) { return; }
|
||||
foundCp++;
|
||||
return foundCp >= desiredCheckpoint;
|
||||
});
|
||||
if (idx > 0) {
|
||||
messages = messages.slice(idx);
|
||||
}
|
||||
}
|
||||
readMore();
|
||||
}, function (err, reason) {
|
||||
if (err) { return void cb(err, reason); }
|
||||
cb(void 0, messages);
|
||||
});
|
||||
|
||||
/*
|
||||
const untilHash = data.toHash;
|
||||
var next = () => {
|
||||
var messages = [];
|
||||
var found = false;
|
||||
@ -456,6 +495,7 @@ const getOlderHistory = function (data, cb) {
|
||||
}
|
||||
next();
|
||||
});
|
||||
*/
|
||||
};
|
||||
|
||||
const getPinState = function (data, cb) {
|
||||
|
||||
@ -53,16 +53,19 @@ Workers.initialize = function (Env, config, _cb) {
|
||||
//return Object.keys(workers[index].tasks || {}).length;
|
||||
};
|
||||
|
||||
const WORKER_TASK_LIMIT = 100000; // XXX
|
||||
|
||||
var workerOffset = -1;
|
||||
var queue = [];
|
||||
var getAvailableWorkerIndex = function () {
|
||||
var getAvailableWorkerIndex = function (isQueue) {
|
||||
// If there is already a backlog of tasks you can avoid some work
|
||||
// by going to the end of the line
|
||||
if (queue.length) { return -1; }
|
||||
// by going to the end of the line (unless we're trying to
|
||||
// empty the queue)
|
||||
if (queue.length && !isQueue) { return -1; }
|
||||
|
||||
var L = workers.length;
|
||||
if (L === 0) {
|
||||
Log.error('NO_WORKERS_AVAILABLE', {
|
||||
Log.warn('NO_WORKERS_AVAILABLE', {
|
||||
queue: queue.length,
|
||||
});
|
||||
return -1;
|
||||
@ -94,7 +97,7 @@ Workers.initialize = function (Env, config, _cb) {
|
||||
};
|
||||
|
||||
var drained = true;
|
||||
var sendCommand = function (msg, _cb, opt) {
|
||||
var sendCommand = function (msg, _cb, opt, isQueue) {
|
||||
if (!_cb) {
|
||||
return void Log.error('WORKER_COMMAND_MISSING_CB', {
|
||||
msg: msg,
|
||||
@ -103,7 +106,7 @@ Workers.initialize = function (Env, config, _cb) {
|
||||
}
|
||||
|
||||
opt = opt || {};
|
||||
var index = getAvailableWorkerIndex();
|
||||
var index = getAvailableWorkerIndex(isQueue);
|
||||
|
||||
var state = workers[index];
|
||||
// if there is no worker available:
|
||||
@ -115,7 +118,7 @@ Workers.initialize = function (Env, config, _cb) {
|
||||
});
|
||||
if (drained) {
|
||||
drained = false;
|
||||
Log.error('WORKER_QUEUE_BACKLOG', {
|
||||
Log.warn('WORKER_QUEUE_BACKLOG', {
|
||||
workers: workers.length,
|
||||
});
|
||||
}
|
||||
@ -128,13 +131,14 @@ Workers.initialize = function (Env, config, _cb) {
|
||||
var cb = Util.once(Util.mkAsync(Util.both(_cb, function (err /*, value */) {
|
||||
incrementTime(msg && msg.command, start);
|
||||
if (err !== 'TIMEOUT') { return; }
|
||||
Log.debug("WORKER_TIMEOUT_CAUSE", msg);
|
||||
Log.warn("WORKER_TIMEOUT_CAUSE", msg);
|
||||
// in the event of a timeout the user will receive an error
|
||||
// but the state used to resend a query in the event of a worker crash
|
||||
// won't be cleared. This also leaks a slot that could be used to keep
|
||||
// an upper bound on the amount of parallelism for any given worker.
|
||||
// if you run out of slots then the worker locks up.
|
||||
delete state.tasks[txid];
|
||||
state.checkTasks();
|
||||
})));
|
||||
|
||||
if (!msg) {
|
||||
@ -165,6 +169,12 @@ Workers.initialize = function (Env, config, _cb) {
|
||||
msg._cb = _cb;
|
||||
msg._opt = opt;
|
||||
});
|
||||
|
||||
state.count++;
|
||||
if (state.count > WORKER_TASK_LIMIT) {
|
||||
// Remove from list and spawn new one
|
||||
if (state.replaceWorker) { state.replaceWorker(); }
|
||||
}
|
||||
};
|
||||
|
||||
const pluginsResponses = {};
|
||||
@ -208,6 +218,8 @@ Workers.initialize = function (Env, config, _cb) {
|
||||
if (!res.txid) { return; }
|
||||
response.handle(res.txid, [res.error, res.value]);
|
||||
delete state.tasks[res.txid];
|
||||
state.checkTasks();
|
||||
|
||||
if (!queue.length) {
|
||||
if (!drained) {
|
||||
drained = true;
|
||||
@ -235,7 +247,7 @@ Workers.initialize = function (Env, config, _cb) {
|
||||
to the back because the following msg took its place. OR, in an
|
||||
even worse scenario, we cycle through the queue but don't run anything.
|
||||
*/
|
||||
sendCommand(nextMsg.msg, nextMsg.cb);
|
||||
sendCommand(nextMsg.msg, nextMsg.cb, {}, true);
|
||||
};
|
||||
|
||||
const initWorker = function (worker, cb) {
|
||||
@ -244,13 +256,60 @@ Workers.initialize = function (Env, config, _cb) {
|
||||
const state = {
|
||||
worker: worker,
|
||||
tasks: {},
|
||||
count: Math.floor(Math.random()*(WORKER_TASK_LIMIT/10)),
|
||||
pid: worker.pid, // store the child process's id in an easily accessible location
|
||||
};
|
||||
|
||||
state.replaceWorker = () => {
|
||||
let index = workers.indexOf(state);
|
||||
if (index === -1) { return; }
|
||||
// Remove old
|
||||
workers.splice(index, 1);
|
||||
// Create new
|
||||
state.complete = true;
|
||||
const w = fork(DB_PATH);
|
||||
Log.info('WORKER_REPLACE_START', {
|
||||
from: state.worker.pid,
|
||||
to: w.pid
|
||||
});
|
||||
initWorker(w, function (err) {
|
||||
if (err) {
|
||||
throw new Error(err);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// If we've reached the limit, kill the worker once
|
||||
// all the tasks are complete or timed out
|
||||
state.checkTasks = () => {
|
||||
// Check limit
|
||||
if (!state.complete || !state.worker) { return; }
|
||||
// Check remaining tasks
|
||||
if (Object.keys(state.tasks).length) { return; }
|
||||
// Kill
|
||||
Log.info('WORKER_KILL', {
|
||||
worker: state.worker.pid,
|
||||
count: state.count
|
||||
});
|
||||
delete state.worker;
|
||||
worker.kill();
|
||||
};
|
||||
|
||||
response.expect(txid, function (err) {
|
||||
if (err) { return void cb(err); }
|
||||
workers.push(state);
|
||||
cb(void 0, state);
|
||||
// We just pushed a new worker, available to receive
|
||||
// a task, so we can empty the queue if necessary
|
||||
if (queue.length) {
|
||||
const nextMsg = queue.shift();
|
||||
if (!nextMsg || !nextMsg.msg) {
|
||||
return Log.error('WORKER_QUEUE_EMPTY_MESSAGE', {
|
||||
item: nextMsg,
|
||||
});
|
||||
}
|
||||
sendCommand(nextMsg.msg, nextMsg.cb, {}, true);
|
||||
}
|
||||
}, 15000);
|
||||
|
||||
worker.send({
|
||||
@ -298,18 +357,21 @@ Workers.initialize = function (Env, config, _cb) {
|
||||
});
|
||||
|
||||
worker.on('exit', function () {
|
||||
if (!state.worker) { return; } // Manually killed
|
||||
substituteWorker();
|
||||
Env.Log.error("DB_WORKER_EXIT", {
|
||||
pid: state.pid,
|
||||
});
|
||||
});
|
||||
worker.on('close', function () {
|
||||
if (!state.worker) { return; } // Manually killed
|
||||
substituteWorker();
|
||||
Env.Log.error("DB_WORKER_CLOSE", {
|
||||
pid: state.pid,
|
||||
});
|
||||
});
|
||||
worker.on('error', function (err) {
|
||||
if (!state.worker) { return; } // Manually killed
|
||||
substituteWorker();
|
||||
Env.Log.error("DB_WORKER_ERROR", {
|
||||
pid: state.pid,
|
||||
|
||||
@ -1,3 +1,7 @@
|
||||
// SPDX-FileCopyrightText: 2025 XWiki CryptPad Team <contact@cryptpad.org> and contributors
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
// Move file from "src" to "www"
|
||||
// This script can be used to copy src files into their old location in order to
|
||||
// merge code more easily.
|
||||
|
||||
18
package-lock.json
generated
18
package-lock.json
generated
@ -18,7 +18,7 @@
|
||||
"chainpad": "^5.2.6",
|
||||
"chainpad-crypto": "^0.2.5",
|
||||
"chainpad-listmap": "^1.1.1",
|
||||
"chainpad-netflux": "^1.2.2",
|
||||
"chainpad-netflux": "^1.2.3",
|
||||
"chainpad-server": "^5.2.4",
|
||||
"ckeditor": "npm:ckeditor4@~4.22.1",
|
||||
"codemirror": "^5.19.0",
|
||||
@ -1927,9 +1927,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/chainpad-netflux": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/chainpad-netflux/-/chainpad-netflux-1.2.2.tgz",
|
||||
"integrity": "sha512-fcKugW29BE4wo4l3WYLc56yeFznu15bGi6tU3uPtsLGSExXGqNwS+3kmpzI0AFAsuoI0OKPeT4uLX4YzKT/D+A==",
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/chainpad-netflux/-/chainpad-netflux-1.2.3.tgz",
|
||||
"integrity": "sha512-bXLUSxAsCu4kRnGorW+7fVofiCWSNGRkB+uFJ4kUV/zDJ3RJYU4J3+DZsL4rCTkLkAjgKt+YQCoYciCKLlTwqg==",
|
||||
"license": "LGPL-2.1",
|
||||
"dependencies": {
|
||||
"netflux-websocket": "^1.2.0"
|
||||
@ -6404,9 +6404,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/xml-crypto": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/xml-crypto/-/xml-crypto-3.2.0.tgz",
|
||||
"integrity": "sha512-qVurBUOQrmvlgmZqIVBqmb06TD2a/PpEUfFPgD7BuBfjmoH4zgkqaWSIJrnymlCvM2GGt9x+XtJFA+ttoAufqg==",
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/xml-crypto/-/xml-crypto-3.2.1.tgz",
|
||||
"integrity": "sha512-0GUNbPtQt+PLMsC5HoZRONX+K6NBJEqpXe/lsvrFj0EqfpGPpVfJKGE7a5jCg8s2+Wkrf/2U1G41kIH+zC9eyQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@xmldom/xmldom": "^0.8.8",
|
||||
"xpath": "0.0.32"
|
||||
@ -6499,8 +6500,7 @@
|
||||
},
|
||||
"src/tweetnacl": {
|
||||
"version": "0.12.2",
|
||||
"license": "Public domain",
|
||||
"devDependencies": {}
|
||||
"license": "Public domain"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
"chainpad": "^5.2.6",
|
||||
"chainpad-crypto": "^0.2.5",
|
||||
"chainpad-listmap": "^1.1.1",
|
||||
"chainpad-netflux": "^1.2.2",
|
||||
"chainpad-netflux": "^1.2.3",
|
||||
"chainpad-server": "^5.2.4",
|
||||
"ckeditor": "npm:ckeditor4@~4.22.1",
|
||||
"codemirror": "^5.19.0",
|
||||
|
||||
@ -1,3 +1,7 @@
|
||||
// SPDX-FileCopyrightText: 2023 XWiki CryptPad Team <contact@cryptpad.org> and contributors
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import {nodeResolve} from "@rollup/plugin-node-resolve"
|
||||
import commonjs from '@rollup/plugin-commonjs';
|
||||
//import builtins from 'rollup-plugin-node-builtins';
|
||||
@ -10,11 +14,30 @@ import json from '@rollup/plugin-json';
|
||||
export default {
|
||||
//input: "./_src/worker/index.ts",
|
||||
input: "./src/worker/store.ts",
|
||||
output: {
|
||||
output: [{
|
||||
name: 'cryptpad-worker',
|
||||
file: "./_build/worker.bundle.js",
|
||||
format: "umd"
|
||||
},
|
||||
file: "./www/common/worker.bundle.js",
|
||||
format: "umd",
|
||||
plugins: [
|
||||
terser({
|
||||
format: {
|
||||
comments: 'some',
|
||||
beautify: true,
|
||||
ecma: '2015',
|
||||
},
|
||||
compress: false,
|
||||
mangle: false,
|
||||
module: true,
|
||||
}),
|
||||
]
|
||||
}, {
|
||||
name: 'cryptpad-worker-min',
|
||||
file: "./www/common/worker.bundle.min.js",
|
||||
format: "umd",
|
||||
plugins: [terser({
|
||||
format: { comments: false, ecma: '2015' }
|
||||
})]
|
||||
}],
|
||||
preserveSymlinks: true,
|
||||
plugins: [
|
||||
json(),
|
||||
@ -25,16 +48,6 @@ export default {
|
||||
commonjs({
|
||||
ignore:['crypto', 'node:http', 'node:https'] // required by tweetnacl for node
|
||||
}),
|
||||
terser({
|
||||
format: {
|
||||
comments: 'some',
|
||||
beautify: true,
|
||||
ecma: '2015',
|
||||
},
|
||||
compress: false,
|
||||
mangle: false,
|
||||
module: true,
|
||||
}),
|
||||
//nodePolyfills( /* options */ )
|
||||
]
|
||||
}
|
||||
|
||||
@ -1,7 +1,11 @@
|
||||
const Messages = require('./src/messages');
|
||||
const AppConfig = require('./customize/application_config');
|
||||
// SPDX-FileCopyrightText: 2023 XWiki CryptPad Team <contact@cryptpad.org> and contributors
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
const Messages = require('../../src/messages');
|
||||
const AppConfig = require('../../customize/application_config');
|
||||
//const App = require('./_build/worker.bundle');
|
||||
const Store = require('./www/common/store-interface');
|
||||
const Store = require('../../www/common/store-interface');
|
||||
const Http = require('node:http');
|
||||
|
||||
|
||||
@ -36,6 +36,7 @@ const factory = (Util, localForage) => {
|
||||
disabled = true;
|
||||
allowed = supported && !disabled;
|
||||
};
|
||||
S.isEnabled = () => allowed;
|
||||
|
||||
var cache = localForage.createInstance({
|
||||
driver: localForage.INDEXEDDB,
|
||||
|
||||
@ -32,7 +32,7 @@ const factory = function (AppConfig = {}) {
|
||||
MAX_PREMIUM_TEAMS_OWNED: Math.max(AppConfig.maxOwnedTeams || 0, AppConfig.maxPremiumTeamsOwned || 0) || 5,
|
||||
// Apps
|
||||
criticalApps: ['profile', 'settings', 'debug', 'admin', 'support', 'notifications', 'calendar', 'moderation', 'oldadmin'], // XXX oldadmin
|
||||
earlyAccessApps: ['doc', 'presentation']
|
||||
earlyAccessApps: []
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@ -86,6 +86,12 @@
|
||||
Util.mkEvent = function (once) {
|
||||
var handlers = [];
|
||||
var fired = false;
|
||||
let promiseResolve;
|
||||
|
||||
const promise = new Promise(resolve => {
|
||||
promiseResolve = resolve;
|
||||
});
|
||||
|
||||
return {
|
||||
reg: function (cb) {
|
||||
if (once && fired) { return void setTimeout(cb); }
|
||||
@ -99,10 +105,13 @@
|
||||
},
|
||||
fire: function () {
|
||||
if (once && fired) { return; }
|
||||
fired = true;
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
if (!fired) { promiseResolve.apply(null, args); }
|
||||
fired = true;
|
||||
handlers.forEach(function (h) { h.apply(null, args); });
|
||||
}
|
||||
},
|
||||
// Since a promise can only resolve once only the 1st call to fire() is reflected here. Even is `once` is `false`.
|
||||
promise
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@ -233,11 +233,25 @@ const factory = (UserObject, Util, Hash,
|
||||
var findFile = function (Env, id) {
|
||||
var ret = [];
|
||||
var userObjects = _getUserObjects(Env);
|
||||
let mainRes = {};
|
||||
userObjects.forEach(function (uo) {
|
||||
var fPath = _getUserObjectPath(Env, uo);
|
||||
var results = uo.findFile(id);
|
||||
if (fPath) {
|
||||
var fId = Number(uo.id);
|
||||
let results;
|
||||
if (!fId) {
|
||||
// Main drive: get the paths of all the SF
|
||||
// in addition to the paths of the requested file
|
||||
let ids = [id];
|
||||
let fIds = userObjects.map(uo => {
|
||||
return +uo.id;
|
||||
}).filter(Boolean);
|
||||
Array.prototype.push.apply(ids, fIds);
|
||||
mainRes = uo.findFiles(ids); // Store paths of each SF
|
||||
results = mainRes[id]; // Paths of requested file
|
||||
} else {
|
||||
results = uo.findFile(id);
|
||||
// This is a shared folder, we have to fix the paths in the results
|
||||
let fPath = (mainRes[fId] || [])[0];
|
||||
if (!fPath) { return; } // Can't search into this sf
|
||||
results.forEach(function (p) {
|
||||
Array.prototype.unshift.apply(p, fPath);
|
||||
});
|
||||
@ -247,6 +261,41 @@ const factory = (UserObject, Util, Hash,
|
||||
});
|
||||
return ret;
|
||||
};
|
||||
var findFiles = function (Env, ids) {
|
||||
var ret = {};
|
||||
var userObjects = _getUserObjects(Env);
|
||||
let mainRes = {};
|
||||
userObjects.forEach(function (uo) {
|
||||
//var fPath = _getUserObjectPath(Env, uo);
|
||||
var fId = Number(uo.id);
|
||||
if (!uo.id) {
|
||||
let fIds = userObjects.map(uo => {
|
||||
return +uo.id;
|
||||
}).filter(Boolean);
|
||||
Array.prototype.push.apply(ids, fIds);
|
||||
}
|
||||
var results = uo.findFiles(ids);
|
||||
if (!uo.id) { mainRes = results; }
|
||||
//console.error(results);
|
||||
if (fId) {
|
||||
// This is a shared folder, we have to fix the paths in the results
|
||||
let fPath = (mainRes[fId] || [])[0];
|
||||
if (!fPath) { return; } // Can't search into this sf
|
||||
Object.keys(results).forEach(file => {
|
||||
results[file].forEach(p => {
|
||||
Array.prototype.unshift.apply(p, fPath);
|
||||
});
|
||||
});
|
||||
}
|
||||
// Push the results from this proxy
|
||||
Object.keys(results).forEach(file => {
|
||||
ret[file] ||= [];
|
||||
Array.prototype.push.apply(ret[file], results[file]);
|
||||
});
|
||||
});
|
||||
return ret;
|
||||
};
|
||||
|
||||
|
||||
// Returns file IDs corresponding to the provided channels
|
||||
var _findChannels = function (Env, channels, onlyMain) {
|
||||
@ -588,7 +637,9 @@ const factory = (UserObject, Util, Hash,
|
||||
var parsed = Hash.parsePadUrl(folderData.href);
|
||||
var secret = Hash.getSecrets('drive', parsed.hash, folderData.password);
|
||||
SF.upgrade(secret.channel, secret);
|
||||
Env.folders[folderId].userObject.setReadOnly(false, secret.keys.secondaryKey);
|
||||
if (Env.folders[folderId]) {
|
||||
Env.folders[folderId].userObject.setReadOnly(false, secret.keys.secondaryKey);
|
||||
}
|
||||
waitFor.abort();
|
||||
return void cb(folderId);
|
||||
}
|
||||
@ -1752,6 +1803,7 @@ const factory = (UserObject, Util, Hash,
|
||||
getOwnedPads: callWithEnv(getOwnedPads),
|
||||
getTagsList: callWithEnv(getTagsList),
|
||||
findFile: callWithEnv(findFile),
|
||||
findFiles: callWithEnv(findFiles),
|
||||
findChannels: callWithEnv(findChannels),
|
||||
getSharedFolderData: callWithEnv(getSharedFolderData),
|
||||
getFolderData: callWithEnv(getFolderData),
|
||||
|
||||
@ -248,7 +248,7 @@ const factory = (Util, Hash,
|
||||
|
||||
var isFolder = exp.isFolder = function (element) {
|
||||
if (isFolderData(element)) { return false; }
|
||||
return typeof(element) === "object" || isSharedFolder(element);
|
||||
return (typeof(element) === "object" && !element.channel) || isSharedFolder(element);
|
||||
};
|
||||
exp.isFolderEmpty = function (element) {
|
||||
if (!isFolder(element)) { return false; }
|
||||
@ -573,56 +573,65 @@ const factory = (Util, Hash,
|
||||
};
|
||||
|
||||
// SEARCH
|
||||
var _findFileInRoot = function (path, file) {
|
||||
var _findFileInRoot = function (path, files) {
|
||||
if (!isPathIn(path, [ROOT, TRASH])) { return []; }
|
||||
var paths = [];
|
||||
files = Array.isArray(files) ? files : [files];
|
||||
var paths = {};
|
||||
var root = find(path);
|
||||
var addPaths = function (p) {
|
||||
if (paths.indexOf(p) === -1) {
|
||||
paths.push(p);
|
||||
}
|
||||
Object.keys(p).forEach(file => {
|
||||
paths[file] ||= [];
|
||||
Array.prototype.push.apply(paths[file], p[file]);
|
||||
});
|
||||
};
|
||||
|
||||
if (isFile(root) || isSharedFolder(root)) {
|
||||
if (compareFiles(file, root)) {
|
||||
if (paths.indexOf(path) === -1) {
|
||||
paths.push(path);
|
||||
files.some(file => {
|
||||
if (compareFiles(file, root)) {
|
||||
paths[file] ||= [];
|
||||
paths[file].push(path);
|
||||
}
|
||||
}
|
||||
});
|
||||
return paths;
|
||||
}
|
||||
if (isFolder(root)) {
|
||||
for (var e in root) {
|
||||
var nPath = path.slice();
|
||||
let nPath = path.slice();
|
||||
nPath.push(e);
|
||||
_findFileInRoot(nPath, file).forEach(addPaths);
|
||||
addPaths(_findFileInRoot(nPath, files));
|
||||
}
|
||||
}
|
||||
|
||||
return paths;
|
||||
};
|
||||
exp.findFileInRoot = function (file) {
|
||||
return _findFileInRoot([ROOT], file);
|
||||
/*
|
||||
exp.findFileInRoot = function (files) {
|
||||
return _findFileInRoot([ROOT], files);
|
||||
};
|
||||
var _findFileInHrefArray = function (rootName, file) {
|
||||
if (sharedFolder) { return []; }
|
||||
if (!files[rootName]) { return []; }
|
||||
*/
|
||||
var _findFileInHrefArray = function (rootName, toFind) {
|
||||
if (sharedFolder) { return {}; }
|
||||
if (!files[rootName]) { return {}; }
|
||||
var unsorted = files[rootName].slice();
|
||||
var ret = [];
|
||||
var ret = {};
|
||||
var i = -1;
|
||||
while ((i = unsorted.indexOf(file, i+1)) !== -1){
|
||||
ret.push([rootName, i]);
|
||||
}
|
||||
toFind.forEach(file => {
|
||||
while ((i = unsorted.indexOf(file, i+1)) !== -1){
|
||||
ret[file] ||= [];
|
||||
ret[file].push([rootName, i]);
|
||||
}
|
||||
});
|
||||
return ret;
|
||||
};
|
||||
var _findFileInTrash = function (path, file) {
|
||||
var _findFileInTrash = function (path, files) {
|
||||
if (sharedFolder) { return []; }
|
||||
var root = find(path);
|
||||
var paths = [];
|
||||
var paths = {};
|
||||
var addPaths = function (p) {
|
||||
if (paths.indexOf(p) === -1) {
|
||||
paths.push(p);
|
||||
}
|
||||
Object.keys(p).forEach(file => {
|
||||
paths[file] ||= [];
|
||||
Array.prototype.push.apply(paths[file], p[file]);
|
||||
});
|
||||
};
|
||||
if (path.length === 1 && typeof(root) === 'object') {
|
||||
Object.keys(root).forEach(function (key) {
|
||||
@ -630,7 +639,7 @@ const factory = (Util, Hash,
|
||||
if (!Array.isArray(arr)) { return; }
|
||||
var nPath = path.slice();
|
||||
nPath.push(key);
|
||||
_findFileInTrash(nPath, file).forEach(addPaths);
|
||||
addPaths(_findFileInTrash(nPath, files));
|
||||
});
|
||||
}
|
||||
if (path.length === 2) {
|
||||
@ -640,24 +649,39 @@ const factory = (Util, Hash,
|
||||
nPath.push(i);
|
||||
nPath.push('element');
|
||||
if (isFile(el.element)) {
|
||||
if (compareFiles(file, el.element)) {
|
||||
addPaths(nPath);
|
||||
}
|
||||
files.some(file => {
|
||||
if (compareFiles(file, el.element)) {
|
||||
paths[file] ||= [];
|
||||
paths[file].push(nPath);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
_findFileInTrash(nPath, file).forEach(addPaths);
|
||||
addPaths(_findFileInTrash(nPath, files));
|
||||
});
|
||||
}
|
||||
if (path.length >= 4) {
|
||||
_findFileInRoot(path, file).forEach(addPaths);
|
||||
addPaths(_findFileInRoot(path, files));
|
||||
}
|
||||
return paths;
|
||||
};
|
||||
var findFiles = exp.findFiles = function (files) {
|
||||
var rootpaths = _findFileInRoot([ROOT], files);
|
||||
var templatepaths = _findFileInHrefArray(TEMPLATE, files);
|
||||
var trashpaths = _findFileInTrash([TRASH], files);
|
||||
let res = {};
|
||||
files.forEach(file => { res[file] = []; });
|
||||
[rootpaths, templatepaths, trashpaths].forEach(r => {
|
||||
Object.keys(r).forEach(file => {
|
||||
res[file] ||= [];
|
||||
Array.prototype.push.apply(res[file], r[file]);
|
||||
});
|
||||
});
|
||||
return res;
|
||||
};
|
||||
var findFile = exp.findFile = function (file) {
|
||||
var rootpaths = _findFileInRoot([ROOT], file);
|
||||
var templatepaths = _findFileInHrefArray(TEMPLATE, file);
|
||||
var trashpaths = _findFileInTrash([TRASH], file);
|
||||
return rootpaths.concat(templatepaths, trashpaths);
|
||||
let res = findFiles([file]);
|
||||
return res[file] || [];
|
||||
};
|
||||
|
||||
// Get drive ids of files from their channel ids
|
||||
|
||||
@ -1,3 +1,7 @@
|
||||
// SPDX-FileCopyrightText: 2025 XWiki CryptPad Team <contact@cryptpad.org> and contributors
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
(() => {
|
||||
const factory = (Messages) => {
|
||||
Messages = Messages || {};
|
||||
|
||||
1
src/tweetnacl/.gitignore
vendored
Normal file
1
src/tweetnacl/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
node_modules
|
||||
7
src/tweetnacl/.travis.yml
Normal file
7
src/tweetnacl/.travis.yml
Normal file
@ -0,0 +1,7 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- "0.10"
|
||||
env:
|
||||
- NACL_SRC=nacl.min.js
|
||||
- NACL_SRC=nacl-fast.min.js
|
||||
script: "npm run testall"
|
||||
36
src/tweetnacl/bower.json
Normal file
36
src/tweetnacl/bower.json
Normal file
@ -0,0 +1,36 @@
|
||||
{
|
||||
"name": "tweetnacl",
|
||||
"version": "0.12.2",
|
||||
"homepage": "https://dchest.github.io/tweetnacl-js",
|
||||
"authors": [
|
||||
"TweetNaCl.js Contributors"
|
||||
],
|
||||
"description": "Port of TweetNaCl cryptographic library to JavaScript",
|
||||
"main": "nacl.js",
|
||||
"moduleType": [
|
||||
"globals",
|
||||
"node"
|
||||
],
|
||||
"keywords": [
|
||||
"crypto",
|
||||
"cryptography",
|
||||
"curve25519",
|
||||
"ed25519",
|
||||
"encrypt",
|
||||
"hash",
|
||||
"key",
|
||||
"nacl",
|
||||
"poly1305",
|
||||
"public",
|
||||
"salsa20",
|
||||
"signatures"
|
||||
],
|
||||
"license": "Public domain",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"package.json"
|
||||
]
|
||||
}
|
||||
4327
src/tweetnacl/package-lock.json
generated
4327
src/tweetnacl/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -53,7 +53,5 @@
|
||||
"bugs": {
|
||||
"url": "https://github.com/dchest/tweetnacl-js/issues"
|
||||
},
|
||||
"homepage": "https://dchest.github.io/tweetnacl-js",
|
||||
"devDependencies": {
|
||||
}
|
||||
"homepage": "https://dchest.github.io/tweetnacl-js"
|
||||
}
|
||||
|
||||
15
src/tweetnacl/test/00-utils.js
Normal file
15
src/tweetnacl/test/00-utils.js
Normal file
@ -0,0 +1,15 @@
|
||||
var nacl = (typeof window !== 'undefined') ? window.nacl : require('../' + (process.env.NACL_SRC || 'nacl.min.js'));
|
||||
var test = require('tape');
|
||||
|
||||
var b64Vectors = require('./data/base64.random');
|
||||
|
||||
test('nacl.util.encodeBase64 random test vectors', function(t) {
|
||||
b64Vectors.forEach(function(vec) {
|
||||
var b = new Uint8Array(vec[0]);
|
||||
var s = vec[1];
|
||||
t.equal(nacl.util.encodeBase64(b), s);
|
||||
t.deepEqual(nacl.util.decodeBase64(s), b);
|
||||
});
|
||||
t.end();
|
||||
});
|
||||
|
||||
26
src/tweetnacl/test/00-utils.quick.js
Normal file
26
src/tweetnacl/test/00-utils.quick.js
Normal file
@ -0,0 +1,26 @@
|
||||
var nacl = (typeof window !== 'undefined') ? window.nacl : require('../' + (process.env.NACL_SRC || 'nacl.min.js'));
|
||||
var test = require('tape');
|
||||
|
||||
var testBytes = new Uint8Array([208,159,209,128,208,184,208,178,208,181,209,130,44,32,78,97,67,108]);
|
||||
var utf8String = "Привет, NaCl";
|
||||
var b64String = "0J/RgNC40LLQtdGCLCBOYUNs";
|
||||
|
||||
test('nacl.util.decodeUTF8', function(t) {
|
||||
t.plan(1);
|
||||
t.deepEqual(nacl.util.decodeUTF8(utf8String), testBytes);
|
||||
});
|
||||
|
||||
test('nacl.util.encodeUTF8', function(t) {
|
||||
t.plan(1);
|
||||
t.equal(nacl.util.encodeUTF8(testBytes), utf8String);
|
||||
});
|
||||
|
||||
test('nacl.util.decodeBase64', function(t) {
|
||||
t.plan(1);
|
||||
t.deepEqual(nacl.util.decodeBase64(b64String), testBytes);
|
||||
});
|
||||
|
||||
test('nacl.util.encodeBase64', function(t) {
|
||||
t.plan(1);
|
||||
t.equal(nacl.util.encodeBase64(testBytes), b64String);
|
||||
});
|
||||
16
src/tweetnacl/test/01-verify.quick.js
Normal file
16
src/tweetnacl/test/01-verify.quick.js
Normal file
@ -0,0 +1,16 @@
|
||||
var nacl = (typeof window !== 'undefined') ? window.nacl : require('../' + (process.env.NACL_SRC || 'nacl.min.js'));
|
||||
var test = require('tape');
|
||||
|
||||
test('nacl.verify', function(t) {
|
||||
t.ok(nacl.verify(new Uint8Array(1), new Uint8Array(1)), 'equal arrays of length 1 should verify');
|
||||
t.ok(nacl.verify(new Uint8Array(1000), new Uint8Array(1000)), 'equal arrays of length 1000 should verify');
|
||||
var a = new Uint8Array(764), b = new Uint8Array(764);
|
||||
for (i = 0; i < a.length; i++) a[i] = b[i] = i & 0xff;
|
||||
t.ok(nacl.verify(a, b), 'equal arrays should verify');
|
||||
t.ok(nacl.verify(a, a), 'same arrays should verify');
|
||||
b[0] = 255;
|
||||
t.notOk(nacl.verify(a, b), 'different arrays don\'t verify');
|
||||
t.notOk(nacl.verify(new Uint8Array(1), new Uint8Array(10)), 'arrays of different lengths should not verify');
|
||||
t.notOk(nacl.verify(new Uint8Array(0), new Uint8Array(0)), 'zero-length arrays should not verify');
|
||||
t.end();
|
||||
});
|
||||
16
src/tweetnacl/test/02-randombytes.quick.js
Normal file
16
src/tweetnacl/test/02-randombytes.quick.js
Normal file
@ -0,0 +1,16 @@
|
||||
var nacl = (typeof window !== 'undefined') ? window.nacl : require('../' + (process.env.NACL_SRC || 'nacl.min.js'));
|
||||
var test = require('tape');
|
||||
|
||||
test('nacl.randomBytes', function(t) {
|
||||
t.plan(1);
|
||||
var set = {}, s, i;
|
||||
for (i = 0; i < 10000; i++) {
|
||||
s = nacl.util.encodeBase64(nacl.randomBytes(32));
|
||||
if (set[s]) {
|
||||
t.fail("duplicate random sequence! ", s);
|
||||
return;
|
||||
}
|
||||
set[s] = true;
|
||||
}
|
||||
t.pass('no collisions');
|
||||
});
|
||||
17
src/tweetnacl/test/03-onetimeauth.quick.js
Normal file
17
src/tweetnacl/test/03-onetimeauth.quick.js
Normal file
@ -0,0 +1,17 @@
|
||||
var nacl = (typeof window !== 'undefined') ? window.nacl : require('../' + (process.env.NACL_SRC || 'nacl.min.js'));
|
||||
var test = require('tape');
|
||||
|
||||
var specVectors = require('./data/onetimeauth.spec');
|
||||
|
||||
var enc = nacl.util.encodeBase64,
|
||||
dec = nacl.util.decodeBase64;
|
||||
|
||||
test('nacl.lowlevel.crypto_onetimeauth specified vectors', function(t) {
|
||||
var out = new Uint8Array(16);
|
||||
specVectors.forEach(function(v) {
|
||||
nacl.lowlevel.crypto_onetimeauth(out, 0, v.m, 0, v.m.length, v.k);
|
||||
t.equal(enc(out), enc(v.out));
|
||||
});
|
||||
t.end();
|
||||
});
|
||||
|
||||
24
src/tweetnacl/test/04-secretbox.js
Normal file
24
src/tweetnacl/test/04-secretbox.js
Normal file
@ -0,0 +1,24 @@
|
||||
var nacl = (typeof window !== 'undefined') ? window.nacl : require('../' + (process.env.NACL_SRC || 'nacl.min.js'));
|
||||
var test = require('tape');
|
||||
|
||||
var randomVectors = require('./data/secretbox.random');
|
||||
|
||||
var enc = nacl.util.encodeBase64,
|
||||
dec = nacl.util.decodeBase64;
|
||||
|
||||
test('nacl.secretbox random test vectors', function(t) {
|
||||
randomVectors.forEach(function(vec) {
|
||||
var key = dec(vec[0]);
|
||||
var nonce = dec(vec[1]);
|
||||
var msg = dec(vec[2]);
|
||||
var goodBox = dec(vec[3]);
|
||||
var box = nacl.secretbox(msg, nonce, key);
|
||||
t.ok(box, 'box should be created');
|
||||
t.equal(enc(box), enc(goodBox));
|
||||
var openedBox = nacl.secretbox.open(goodBox, nonce, key);
|
||||
t.ok(openedBox, 'box should open');
|
||||
t.equal(enc(openedBox), enc(msg));
|
||||
});
|
||||
t.end();
|
||||
});
|
||||
|
||||
52
src/tweetnacl/test/04-secretbox.quick.js
Normal file
52
src/tweetnacl/test/04-secretbox.quick.js
Normal file
@ -0,0 +1,52 @@
|
||||
var nacl = (typeof window !== 'undefined') ? window.nacl : require('../' + (process.env.NACL_SRC || 'nacl.min.js'));
|
||||
var test = require('tape');
|
||||
|
||||
var enc = nacl.util.encodeBase64,
|
||||
dec = nacl.util.decodeBase64;
|
||||
|
||||
test('nacl.secretbox and nacl.secretbox.open', function(t) {
|
||||
var key = new Uint8Array(nacl.secretbox.keyLength);
|
||||
var nonce = new Uint8Array(nacl.secretbox.nonceLength);
|
||||
for (var i = 0; i < key.length; i++) key[i] = i & 0xff;
|
||||
for (i = 0; i < nonce.length; i++) nonce[i] = (32+i) & 0xff;
|
||||
var msg = nacl.util.decodeUTF8('message to encrypt');
|
||||
var box = nacl.secretbox(msg, nonce, key);
|
||||
var openedMsg = nacl.secretbox.open(box, nonce, key);
|
||||
t.equal(nacl.util.encodeUTF8(openedMsg), nacl.util.encodeUTF8(msg), 'opened messages should be equal');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('nacl.secretbox.open with invalid box', function(t) {
|
||||
var key = new Uint8Array(nacl.secretbox.keyLength);
|
||||
var nonce = new Uint8Array(nacl.secretbox.nonceLength);
|
||||
t.equal(nacl.secretbox.open(new Uint8Array(0), nonce, key), false);
|
||||
t.equal(nacl.secretbox.open(new Uint8Array(10), nonce, key), false);
|
||||
t.equal(nacl.secretbox.open(new Uint8Array(100), nonce, key), false);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('nacl.secretbox.open with invalid nonce', function(t) {
|
||||
var key = new Uint8Array(nacl.secretbox.keyLength);
|
||||
var nonce = new Uint8Array(nacl.secretbox.nonceLength);
|
||||
for (i = 0; i < nonce.length; i++) nonce[i] = i & 0xff;
|
||||
var msg = nacl.util.decodeUTF8('message to encrypt');
|
||||
var box = nacl.secretbox(msg, nonce, key);
|
||||
t.equal(nacl.util.encodeUTF8(nacl.secretbox.open(box, nonce, key)),
|
||||
nacl.util.encodeUTF8(msg));
|
||||
nonce[0] = 255;
|
||||
t.equal(nacl.secretbox.open(box, nonce, key), false);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('nacl.secretbox.open with invalid key', function(t) {
|
||||
var key = new Uint8Array(nacl.secretbox.keyLength);
|
||||
for (var i = 0; i < key.length; i++) key[i] = i & 0xff;
|
||||
var nonce = new Uint8Array(nacl.secretbox.nonceLength);
|
||||
var msg = nacl.util.decodeUTF8('message to encrypt');
|
||||
var box = nacl.secretbox(msg, nonce, key);
|
||||
t.equal(nacl.util.encodeUTF8(nacl.secretbox.open(box, nonce, key)),
|
||||
nacl.util.encodeUTF8(msg));
|
||||
key[0] = 255;
|
||||
t.equal(nacl.secretbox.open(box, nonce, key), false);
|
||||
t.end();
|
||||
});
|
||||
43
src/tweetnacl/test/05-scalarmult.js
Normal file
43
src/tweetnacl/test/05-scalarmult.js
Normal file
@ -0,0 +1,43 @@
|
||||
var nacl = (typeof window !== 'undefined') ? window.nacl : require('../' + (process.env.NACL_SRC || 'nacl.min.js'));
|
||||
var test = require('tape');
|
||||
|
||||
var randomVectors = require('./data/scalarmult.random');
|
||||
|
||||
var enc = nacl.util.encodeBase64,
|
||||
dec = nacl.util.decodeBase64;
|
||||
|
||||
test('nacl.scalarMult.base', function(t) {
|
||||
// This takes takes a bit of time.
|
||||
// Similar to https://code.google.com/p/go/source/browse/curve25519/curve25519_test.go?repo=crypto
|
||||
var golden = new Uint8Array([0x89, 0x16, 0x1f, 0xde, 0x88, 0x7b, 0x2b, 0x53, 0xde, 0x54,
|
||||
0x9a, 0xf4, 0x83, 0x94, 0x01, 0x06, 0xec, 0xc1, 0x14, 0xd6, 0x98, 0x2d,
|
||||
0xaa, 0x98, 0x25, 0x6d, 0xe2, 0x3b, 0xdf, 0x77, 0x66, 0x1a]);
|
||||
var input = new Uint8Array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
|
||||
for (var i = 0; i < 200; i++) {
|
||||
input = nacl.scalarMult.base(input);
|
||||
}
|
||||
t.equal(enc(input), enc(golden));
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('nacl.scalarMult and nacl.scalarMult.base random test vectors', function(t) {
|
||||
randomVectors.forEach(function(vec) {
|
||||
var pk1 = dec(vec[0]);
|
||||
var sk1 = dec(vec[1]);
|
||||
var pk2 = dec(vec[2]);
|
||||
var sk2 = dec(vec[3]);
|
||||
var out = dec(vec[4]);
|
||||
|
||||
var jpk1 = nacl.scalarMult.base(sk1);
|
||||
t.equal(enc(jpk1), enc(pk1));
|
||||
var jpk2 = nacl.scalarMult.base(sk2);
|
||||
t.equal(enc(jpk2), enc(pk2));
|
||||
var jout1 = nacl.scalarMult(sk1, pk2);
|
||||
t.equal(enc(jout1), enc(out));
|
||||
var jout2 = nacl.scalarMult(sk2, pk1);
|
||||
t.equal(enc(jout2), enc(out));
|
||||
});
|
||||
t.end();
|
||||
});
|
||||
|
||||
22
src/tweetnacl/test/06-box.js
Normal file
22
src/tweetnacl/test/06-box.js
Normal file
@ -0,0 +1,22 @@
|
||||
var nacl = (typeof window !== 'undefined') ? window.nacl : require('../' + (process.env.NACL_SRC || 'nacl.min.js'));
|
||||
var test = require('tape');
|
||||
|
||||
var randomVectors = require('./data/box.random');
|
||||
|
||||
var enc = nacl.util.encodeBase64,
|
||||
dec = nacl.util.decodeBase64;
|
||||
|
||||
test('nacl.box random test vectors', function(t) {
|
||||
var nonce = new Uint8Array(nacl.box.nonceLength);
|
||||
randomVectors.forEach(function(vec) {
|
||||
var pk1 = dec(vec[0]);
|
||||
var sk2 = dec(vec[1]);
|
||||
var msg = dec(vec[2]);
|
||||
var goodBox = dec(vec[3]);
|
||||
var box = nacl.box(msg, nonce, pk1, sk2);
|
||||
t.equal(enc(box), enc(goodBox));
|
||||
var openedBox = nacl.box.open(goodBox, nonce, pk1, sk2);
|
||||
t.equal(enc(openedBox), enc(msg));
|
||||
});
|
||||
t.end();
|
||||
});
|
||||
78
src/tweetnacl/test/06-box.quick.js
Normal file
78
src/tweetnacl/test/06-box.quick.js
Normal file
@ -0,0 +1,78 @@
|
||||
var nacl = (typeof window !== 'undefined') ? window.nacl : require('../' + (process.env.NACL_SRC || 'nacl.min.js'));
|
||||
var test = require('tape');
|
||||
|
||||
var enc = nacl.util.encodeBase64,
|
||||
dec = nacl.util.decodeBase64;
|
||||
|
||||
test('nacl.box.keyPair', function(t) {
|
||||
var keys = nacl.box.keyPair();
|
||||
t.ok(keys.secretKey && keys.secretKey.length === nacl.box.secretKeyLength, 'has secret key');
|
||||
t.ok(keys.publicKey && keys.publicKey.length === nacl.box.publicKeyLength, 'has public key');
|
||||
t.notEqual(enc(keys.secretKey), enc(keys.publicKey));
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('nacl.box.keyPair.fromSecretKey', function(t) {
|
||||
var k1 = nacl.box.keyPair();
|
||||
var k2 = nacl.box.keyPair.fromSecretKey(k1.secretKey);
|
||||
t.equal(enc(k2.secretKey), enc(k1.secretKey));
|
||||
t.equal(enc(k2.publicKey), enc(k1.publicKey));
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('nacl.box and nacl.box.open', function(t) {
|
||||
var clientKeys = nacl.box.keyPair();
|
||||
var serverKeys = nacl.box.keyPair();
|
||||
var nonce = new Uint8Array(nacl.box.nonceLength);
|
||||
for (i = 0; i < nonce.length; i++) nonce[i] = (32+i) & 0xff;
|
||||
var msg = nacl.util.decodeUTF8('message to encrypt');
|
||||
var clientBox = nacl.box(msg, nonce, serverKeys.publicKey, clientKeys.secretKey);
|
||||
var clientMsg = nacl.box.open(clientBox, nonce, clientKeys.publicKey, serverKeys.secretKey);
|
||||
t.equal(nacl.util.encodeUTF8(clientMsg), nacl.util.encodeUTF8(msg));
|
||||
var serverBox = nacl.box(msg, nonce, clientKeys.publicKey, serverKeys.secretKey);
|
||||
t.equal(enc(clientBox), enc(serverBox));
|
||||
var serverMsg = nacl.box.open(serverBox, nonce, serverKeys.publicKey, clientKeys.secretKey);
|
||||
t.equal(nacl.util.encodeUTF8(serverMsg), nacl.util.encodeUTF8(msg));
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('nacl.box.open with invalid box', function(t) {
|
||||
var clientKeys = nacl.box.keyPair();
|
||||
var serverKeys = nacl.box.keyPair();
|
||||
var nonce = new Uint8Array(nacl.box.nonceLength);
|
||||
t.equal(nacl.box.open(new Uint8Array(0), nonce, serverKeys.publicKey, clientKeys.secretKey), false);
|
||||
t.equal(nacl.box.open(new Uint8Array(10), nonce, serverKeys.publicKey, clientKeys.secretKey), false);
|
||||
t.equal(nacl.box.open(new Uint8Array(100), nonce, serverKeys.publicKey, clientKeys.secretKey), false);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('nacl.box.open with invalid nonce', function(t) {
|
||||
var clientKeys = nacl.box.keyPair();
|
||||
var serverKeys = nacl.box.keyPair();
|
||||
var nonce = new Uint8Array(nacl.box.nonceLength);
|
||||
for (i = 0; i < nonce.length; i++) nonce[i] = i & 0xff;
|
||||
var msg = nacl.util.decodeUTF8('message to encrypt');
|
||||
var box = nacl.box(msg, nonce, clientKeys.publicKey, serverKeys.secretKey);
|
||||
t.equal(nacl.util.encodeUTF8(nacl.box.open(box, nonce, serverKeys.publicKey, clientKeys.secretKey)),
|
||||
nacl.util.encodeUTF8(msg));
|
||||
nonce[0] = 255;
|
||||
t.equal(nacl.box.open(box, nonce, serverKeys.publicKey, clientKeys.secretKey), false);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('nacl.box.open with invalid keys', function(t) {
|
||||
var clientKeys = nacl.box.keyPair();
|
||||
var serverKeys = nacl.box.keyPair();
|
||||
var nonce = new Uint8Array(nacl.box.nonceLength);
|
||||
var msg = nacl.util.decodeUTF8('message to encrypt');
|
||||
var box = nacl.box(msg, nonce, clientKeys.publicKey, serverKeys.secretKey);
|
||||
t.equal(nacl.util.encodeUTF8(nacl.box.open(box, nonce, serverKeys.publicKey, clientKeys.secretKey)),
|
||||
nacl.util.encodeUTF8(msg));
|
||||
t.equal(nacl.util.encodeUTF8(nacl.box.open(box, nonce, clientKeys.publicKey, serverKeys.secretKey)),
|
||||
nacl.util.encodeUTF8(msg));
|
||||
badPublicKey = new Uint8Array(nacl.box.publicKeyLength);
|
||||
t.equal(nacl.box.open(box, nonce, badPublicKey, clientKeys.secretKey), false);
|
||||
badSecretKey = new Uint8Array(nacl.box.secretKeyLength);
|
||||
t.equal(nacl.box.open(box, nonce, serverKeys.publicKey, badSecretKey), false);
|
||||
t.end();
|
||||
});
|
||||
17
src/tweetnacl/test/07-hash.js
Normal file
17
src/tweetnacl/test/07-hash.js
Normal file
@ -0,0 +1,17 @@
|
||||
var nacl = (typeof window !== 'undefined') ? window.nacl : require('../' + (process.env.NACL_SRC || 'nacl.min.js'));
|
||||
var test = require('tape');
|
||||
|
||||
var randomVectors = require('./data/hash.random');
|
||||
|
||||
var enc = nacl.util.encodeBase64,
|
||||
dec = nacl.util.decodeBase64;
|
||||
|
||||
test('nacl.hash random test vectors', function(t) {
|
||||
randomVectors.forEach(function(vec) {
|
||||
var msg = dec(vec[0]);
|
||||
var goodHash = dec(vec[1]);
|
||||
var hash = nacl.hash(msg);
|
||||
t.equal(enc(hash), enc(goodHash));
|
||||
});
|
||||
t.end();
|
||||
});
|
||||
29
src/tweetnacl/test/07-hash.quick.js
Normal file
29
src/tweetnacl/test/07-hash.quick.js
Normal file
@ -0,0 +1,29 @@
|
||||
var nacl = (typeof window !== 'undefined') ? window.nacl : require('../' + (process.env.NACL_SRC || 'nacl.min.js'));
|
||||
var test = require('tape');
|
||||
|
||||
var specVectors = require('./data/hash.spec');
|
||||
|
||||
var enc = nacl.util.encodeBase64,
|
||||
dec = nacl.util.decodeBase64;
|
||||
|
||||
test('nacl.hash length', function(t) {
|
||||
t.equal(nacl.hash(new Uint8Array(0)).length, 64);
|
||||
t.equal(nacl.hash(new Uint8Array(100)).length, 64);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('nacl.hash exceptions for bad types', function(t) {
|
||||
t.throws(function() { nacl.hash('string'); }, TypeError, 'should throw TypeError for string type');
|
||||
t.throws(function() { nacl.hash([1,2,3]); }, TypeError, 'should throw TypeError for array type');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('nacl.hash specified test vectors', function(t) {
|
||||
specVectors.forEach(function(vec) {
|
||||
var goodHash = new Uint8Array(vec[0]);
|
||||
var msg = new Uint8Array(vec[1]);
|
||||
var hash = nacl.hash(msg);
|
||||
t.equal(enc(hash), enc(goodHash));
|
||||
});
|
||||
t.end();
|
||||
});
|
||||
38
src/tweetnacl/test/08-sign.js
Normal file
38
src/tweetnacl/test/08-sign.js
Normal file
@ -0,0 +1,38 @@
|
||||
var nacl = (typeof window !== 'undefined') ? window.nacl : require('../' + (process.env.NACL_SRC || 'nacl.min.js'));
|
||||
var test = require('tape');
|
||||
|
||||
var specVectors = require('./data/sign.spec');
|
||||
|
||||
var enc = nacl.util.encodeBase64,
|
||||
dec = nacl.util.decodeBase64;
|
||||
|
||||
test('nacl.sign and nacl.sign.open specified vectors', function(t) {
|
||||
specVectors.forEach(function(vec) {
|
||||
var keys = nacl.sign.keyPair.fromSecretKey(dec(vec[0]));
|
||||
var msg = dec(vec[1]);
|
||||
var goodSig = dec(vec[2]);
|
||||
|
||||
var signedMsg = nacl.sign(msg, keys.secretKey);
|
||||
t.equal(enc(signedMsg.subarray(0, nacl.sign.signatureLength)), enc(goodSig), 'signatures must be equal');
|
||||
var openedMsg = nacl.sign.open(signedMsg, keys.publicKey);
|
||||
t.equal(enc(openedMsg), enc(msg), 'messages must be equal');
|
||||
});
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('nacl.sign.detached and nacl.sign.detached.verify some specified vectors', function(t) {
|
||||
specVectors.forEach(function(vec, i) {
|
||||
// We don't need to test all, as internals are already tested above.
|
||||
if (i % 100 !== 0) return;
|
||||
|
||||
var keys = nacl.sign.keyPair.fromSecretKey(dec(vec[0]));
|
||||
var msg = dec(vec[1]);
|
||||
var goodSig = dec(vec[2]);
|
||||
|
||||
var sig = nacl.sign.detached(msg, keys.secretKey);
|
||||
t.equal(enc(sig), enc(goodSig), 'signatures must be equal');
|
||||
var result = nacl.sign.detached.verify(msg, sig, keys.publicKey);
|
||||
t.ok(result, 'signature must be verified');
|
||||
});
|
||||
t.end();
|
||||
});
|
||||
80
src/tweetnacl/test/08-sign.quick.js
Normal file
80
src/tweetnacl/test/08-sign.quick.js
Normal file
@ -0,0 +1,80 @@
|
||||
var nacl = (typeof window !== 'undefined') ? window.nacl : require('../' + (process.env.NACL_SRC || 'nacl.min.js'));
|
||||
var test = require('tape');
|
||||
|
||||
var enc = nacl.util.encodeBase64,
|
||||
dec = nacl.util.decodeBase64;
|
||||
|
||||
test('nacl.sign.keyPair', function(t) {
|
||||
var keys = nacl.sign.keyPair();
|
||||
t.ok(keys.secretKey && keys.secretKey.length === nacl.sign.secretKeyLength, 'has secret key');
|
||||
t.ok(keys.publicKey && keys.publicKey.length === nacl.sign.publicKeyLength, 'has public key');
|
||||
t.notEqual(enc(keys.secretKey), enc(keys.publicKey));
|
||||
var newKeys = nacl.sign.keyPair();
|
||||
t.notEqual(enc(newKeys.secretKey), enc(keys.secretKey), 'two keys differ');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('nacl.sign.keyPair.fromSecretKey', function(t) {
|
||||
var k1 = nacl.sign.keyPair();
|
||||
var k2 = nacl.sign.keyPair.fromSecretKey(k1.secretKey);
|
||||
t.equal(enc(k2.secretKey), enc(k1.secretKey));
|
||||
t.equal(enc(k2.publicKey), enc(k1.publicKey));
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('nacl.sign.keyPair.fromSeed', function(t) {
|
||||
var seed = nacl.randomBytes(nacl.sign.seedLength);
|
||||
var k1 = nacl.sign.keyPair.fromSeed(seed);
|
||||
var k2 = nacl.sign.keyPair.fromSeed(seed);
|
||||
t.equal(k1.secretKey.length, nacl.sign.secretKeyLength);
|
||||
t.equal(k1.publicKey.length, nacl.sign.publicKeyLength);
|
||||
t.equal(k2.secretKey.length, nacl.sign.secretKeyLength);
|
||||
t.equal(k2.publicKey.length, nacl.sign.publicKeyLength);
|
||||
t.equal(enc(k2.secretKey), enc(k1.secretKey));
|
||||
t.equal(enc(k2.publicKey), enc(k1.publicKey));
|
||||
var seed2 = nacl.randomBytes(nacl.sign.seedLength);
|
||||
var k3 = nacl.sign.keyPair.fromSeed(seed2);
|
||||
t.equal(k3.secretKey.length, nacl.sign.secretKeyLength);
|
||||
t.equal(k3.publicKey.length, nacl.sign.publicKeyLength);
|
||||
t.notEqual(enc(k3.secretKey), enc(k1.secretKey));
|
||||
t.notEqual(enc(k3.publicKey), enc(k1.publicKey));
|
||||
t.throws(function() { nacl.sign.keyPair.fromSeed(seed2.subarray(0, 16)) }, Error, 'should throw error for wrong seed size');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('nacl.sign and nacl.sign.open', function(t) {
|
||||
var k = nacl.sign.keyPair();
|
||||
var m = new Uint8Array(100);
|
||||
for (var i = 0; i < m.length; i++) m[i] = i & 0xff;
|
||||
var sm = nacl.sign(m, k.secretKey);
|
||||
t.ok(sm.length > m.length, 'signed message length should be greater than message length');
|
||||
var om = nacl.sign.open(sm, k.publicKey);
|
||||
t.deepEqual(om, m);
|
||||
t.throws(function() { nacl.sign.open(sm, k.publicKey.subarray(1)) }, Error, 'throws error for wrong public key size');
|
||||
var badPublicKey = new Uint8Array(k.publicKey.length);
|
||||
om = nacl.sign.open(sm, badPublicKey);
|
||||
t.equal(om, null, 'opened message must be null when using wrong public key');
|
||||
for (i = 80; i < 90; i++) sm[i] = 0;
|
||||
om = nacl.sign.open(sm, k.publicKey);
|
||||
t.equal(om, null, 'opened message must be null when opening bad signed message');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('nacl.sign.detached and nacl.sign.detached.verify', function(t) {
|
||||
var k = nacl.sign.keyPair();
|
||||
var m = new Uint8Array(100);
|
||||
for (var i = 0; i < m.length; i++) m[i] = i & 0xff;
|
||||
var sig = nacl.sign.detached(m, k.secretKey);
|
||||
t.ok(sig.length === nacl.sign.signatureLength, 'signature must have correct length');
|
||||
var result = nacl.sign.detached.verify(m, sig, k.publicKey);
|
||||
t.ok(result, 'signature must be verified');
|
||||
t.throws(function() { nacl.sign.detached.verify(m, sig, k.publicKey.subarray(1)) }, Error, 'throws error for wrong public key size');
|
||||
t.throws(function() { nacl.sign.detached.verify(m, sig.subarray(1), k.publicKey) }, Error, 'throws error for wrong signature size');
|
||||
var badPublicKey = new Uint8Array(k.publicKey.length);
|
||||
result = nacl.sign.detached.verify(m, sig, badPublicKey);
|
||||
t.equal(result, false, 'signature must not be verified with wrong public key');
|
||||
for (i = 0; i < 10; i++) sig[i] = 0;
|
||||
result = nacl.sign.detached.verify(m, sig, k.publicKey);
|
||||
t.equal(result, false, 'bad signature must not be verified');
|
||||
t.end();
|
||||
});
|
||||
11
src/tweetnacl/test/benchmark/README
Normal file
11
src/tweetnacl/test/benchmark/README
Normal file
@ -0,0 +1,11 @@
|
||||
This directory contains benchmarks that run in Node.js and browsers.
|
||||
|
||||
To run benchmarks in Node.js, from the root project directory:
|
||||
|
||||
$ npm run bench
|
||||
|
||||
alternatively, in this directory, run:
|
||||
|
||||
$ node bench.js
|
||||
|
||||
To run benchmarks in a browser, open bench.html.
|
||||
13
src/tweetnacl/test/benchmark/bench-fast.html
Normal file
13
src/tweetnacl/test/benchmark/bench-fast.html
Normal file
@ -0,0 +1,13 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf8">
|
||||
<title>TweetNaCl-js Benchmarks (fast)</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>TweetNaCl-js Benchmarks (fast)</h1>
|
||||
<script src="../../nacl-fast.min.js"></script>
|
||||
<script src="helpers.js"></script>
|
||||
<script src="bench.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
13
src/tweetnacl/test/benchmark/bench.html
Normal file
13
src/tweetnacl/test/benchmark/bench.html
Normal file
@ -0,0 +1,13 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf8">
|
||||
<title>TweetNaCl-js Benchmarks</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>TweetNaCl-js Benchmarks</h1>
|
||||
<script src="../../nacl.min.js"></script>
|
||||
<script src="helpers.js"></script>
|
||||
<script src="bench.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
164
src/tweetnacl/test/benchmark/bench.js
Normal file
164
src/tweetnacl/test/benchmark/bench.js
Normal file
@ -0,0 +1,164 @@
|
||||
var nacl = (typeof window !== 'undefined') ? window.nacl : require('../../' + (process.env.NACL_SRC || 'nacl.min.js'));
|
||||
var helpers = (typeof require !== 'undefined') ? require('./helpers') : window.helpers;
|
||||
var log = helpers.log;
|
||||
|
||||
if (!nacl) throw new Error('nacl not loaded');
|
||||
|
||||
function benchmark(fn, bytes, num) {
|
||||
if (!num) num = 1000;
|
||||
var i, elapsed, start = new Date();
|
||||
while (1) {
|
||||
for (i = 0; i < num; i++) fn();
|
||||
elapsed = (new Date()) - start;
|
||||
if (elapsed < 500) {
|
||||
num += num*1000/elapsed/2;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
log.print(' ' + ((bytes*num/1024/1024*1000)/elapsed).toFixed(3), 'MB/s');
|
||||
log.print(' ' + ((num*1000)/elapsed).toFixed(3), 'ops/s');
|
||||
}
|
||||
|
||||
function benchmarkOps(fn, num) {
|
||||
var i, elapsed, start = new Date();
|
||||
while (1) {
|
||||
for (i = 0; i < num; i++) {
|
||||
fn();
|
||||
}
|
||||
elapsed = (new Date()) - start;
|
||||
if (elapsed < 500) {
|
||||
num += num*1000/elapsed/2;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
log.print(' ' + ((num*1000)/elapsed).toFixed(3), 'ops/s');
|
||||
}
|
||||
|
||||
function crypto_stream_xor_benchmark() {
|
||||
log.start('Benchmarking crypto_stream_xor');
|
||||
var m = new Uint8Array(1024),
|
||||
n = new Uint8Array(24),
|
||||
k = new Uint8Array(32),
|
||||
out = new Uint8Array(1024);
|
||||
for (i = 0; i < 1024; i++) m[i] = i & 255;
|
||||
for (i = 0; i < 24; i++) n[i] = i;
|
||||
for (i = 0; i < 32; i++) k[i] = i;
|
||||
benchmark(function(){
|
||||
nacl.lowlevel.crypto_stream_xor(out, 0, m, 0, m.length, n, k);
|
||||
}, m.length);
|
||||
}
|
||||
|
||||
function crypto_onetimeauth_benchmark() {
|
||||
log.start('Benchmarking crypto_onetimeauth');
|
||||
var m = new Uint8Array(1024),
|
||||
out = new Uint8Array(1024),
|
||||
k = new Uint8Array([0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1]);
|
||||
for (i = 0; i < 1024; i++) {
|
||||
m[i] = i & 255;
|
||||
}
|
||||
benchmark(function(){
|
||||
nacl.lowlevel.crypto_onetimeauth(out, 0, m, 0, m.length, k);
|
||||
}, m.length);
|
||||
}
|
||||
|
||||
function crypto_secretbox_benchmark() {
|
||||
log.start('Benchmarking crypto_secretbox');
|
||||
var i, k = new Uint8Array(32), n = new Uint8Array(24),
|
||||
m = new Uint8Array(1024), c = new Uint8Array(1024);
|
||||
for (i = 0; i < 32; i++) k[i] = 1;
|
||||
for (i = 0; i < 24; i++) n[i] = 2;
|
||||
for (i = 0; i < 1024; i++) m[i] = 3;
|
||||
benchmark(function() {
|
||||
nacl.lowlevel.crypto_secretbox(c, m, m.length, n, k);
|
||||
}, m.length);
|
||||
}
|
||||
|
||||
function secretbox_seal_open_benchmark() {
|
||||
var key = new Uint8Array(32),
|
||||
nonce = new Uint8Array(24),
|
||||
msg = new Uint8Array(1024),
|
||||
box, i;
|
||||
for (i = 0; i < 32; i++) key[i] = 1;
|
||||
for (i = 0; i < 24; i++) nonce[i] = 2;
|
||||
for (i = 0; i < 1024; i++) msg[i] = 3;
|
||||
|
||||
log.start('Benchmarking secretbox');
|
||||
benchmark(function() {
|
||||
box = nacl.secretbox(msg, nonce, key);
|
||||
}, msg.length);
|
||||
log.start('Benchmarking secretbox.open');
|
||||
benchmark(function() {
|
||||
nacl.secretbox.open(box, nonce, key);
|
||||
}, msg.length);
|
||||
}
|
||||
|
||||
function crypto_scalarmult_base_benchmark() {
|
||||
log.start('Benchmarking crypto_scalarmult_base');
|
||||
var n = new Uint8Array(32), q = new Uint8Array(32);
|
||||
for (var i = 0; i < 32; i++) n[i] = i;
|
||||
benchmarkOps(function() {
|
||||
nacl.lowlevel.crypto_scalarmult_base(q, n);
|
||||
}, 10);
|
||||
}
|
||||
|
||||
function box_seal_open_benchmark() {
|
||||
var pk1 = new Uint8Array(32), sk1 = new Uint8Array(32),
|
||||
pk2 = new Uint8Array(32), sk2 = new Uint8Array(32);
|
||||
nacl.lowlevel.crypto_box_keypair(pk1, sk1);
|
||||
nacl.lowlevel.crypto_box_keypair(pk2, sk2);
|
||||
var nonce = nacl.util.decodeUTF8('123456789012345678901234');
|
||||
var msg = nacl.util.decodeUTF8((new Array(1024)).join('a'));
|
||||
var box = null;
|
||||
log.start('Benchmarking box');
|
||||
benchmark(function() {
|
||||
box = nacl.box(msg, nonce, pk1, sk2);
|
||||
}, msg.length, 20);
|
||||
log.start('Benchmarking box.open');
|
||||
benchmark(function() {
|
||||
nacl.box.open(box, nonce, pk2, sk1);
|
||||
}, msg.length, 20);
|
||||
}
|
||||
|
||||
function sign_open_benchmark() {
|
||||
var k = nacl.sign.keyPair();
|
||||
var sk = k.secretKey;
|
||||
var pk = k.publicKey;
|
||||
var msg = nacl.util.decodeUTF8((new Array(128)).join('a'));
|
||||
var sm;
|
||||
log.start('Benchmarking sign');
|
||||
benchmark(function() {
|
||||
sm = nacl.sign(msg, sk);
|
||||
}, msg.length, 20);
|
||||
log.start('Benchmarking sign.open');
|
||||
benchmark(function() {
|
||||
nacl.sign.open(sm, pk);
|
||||
}, msg.length, 20);
|
||||
}
|
||||
|
||||
function crypto_hash_benchmark() {
|
||||
log.start('Benchmarking crypto_hash (1024 bytes)');
|
||||
var m = new Uint8Array(1024), out = new Uint8Array(64);
|
||||
for (i = 0; i < m.length; i++) m[i] = i & 255;
|
||||
benchmark(function(){
|
||||
nacl.lowlevel.crypto_hash(out, m, m.length);
|
||||
}, m.length);
|
||||
|
||||
log.start('Benchmarking crypto_hash (16 KiB)');
|
||||
m = new Uint8Array(16*1024);
|
||||
for (i = 0; i < m.length; i++) m[i] = i & 255;
|
||||
benchmark(function(){
|
||||
nacl.lowlevel.crypto_hash(out, m, m.length);
|
||||
}, m.length);
|
||||
}
|
||||
|
||||
crypto_stream_xor_benchmark();
|
||||
crypto_onetimeauth_benchmark();
|
||||
crypto_secretbox_benchmark();
|
||||
crypto_hash_benchmark();
|
||||
secretbox_seal_open_benchmark();
|
||||
crypto_scalarmult_base_benchmark();
|
||||
box_seal_open_benchmark();
|
||||
sign_open_benchmark();
|
||||
62
src/tweetnacl/test/benchmark/helpers.js
Normal file
62
src/tweetnacl/test/benchmark/helpers.js
Normal file
@ -0,0 +1,62 @@
|
||||
// Test helpers.
|
||||
(function(exports) {
|
||||
|
||||
function NodeLogger() {
|
||||
this.print = function() {
|
||||
console.log.apply(console, arguments);
|
||||
};
|
||||
|
||||
this.ok = function() {
|
||||
process.stdout.write('.');
|
||||
};
|
||||
|
||||
this.error = function() {
|
||||
console.error.apply(console, arguments);
|
||||
process.exit(1);
|
||||
};
|
||||
|
||||
this.start = this.print.bind(this, '\n');
|
||||
}
|
||||
|
||||
function BrowserLogger() {
|
||||
var el = document.createElement('pre');
|
||||
document.body.appendChild(el);
|
||||
|
||||
function escape(s) {
|
||||
var reps = {
|
||||
'&': '&',
|
||||
'<': '<',
|
||||
'>': '>',
|
||||
'"': '"',
|
||||
"'": ''',
|
||||
'/': '/'
|
||||
};
|
||||
return String(s).replace(/[&<>"'\/]/g, function (x) { return reps[x]; });
|
||||
}
|
||||
|
||||
this.print = function() {
|
||||
console.log.apply(console, arguments);
|
||||
var s = escape(arguments.length ? Array.prototype.slice.call(arguments).join(' ') : '');
|
||||
el.innerHTML += s + '\n';
|
||||
};
|
||||
|
||||
this.ok = function() {
|
||||
// No console output.
|
||||
el.innerHTML += '.';
|
||||
};
|
||||
|
||||
this.error = function() {
|
||||
console.error.apply(console, arguments);
|
||||
var s = escape(arguments.length ? Array.prototype.slice.call(arguments) : '');
|
||||
el.innerHTML += 'ERROR: ' + s + '\n';
|
||||
};
|
||||
|
||||
this.start = this.print.bind(this, '\n');
|
||||
}
|
||||
|
||||
if (typeof window !== 'undefined')
|
||||
exports.log = new BrowserLogger();
|
||||
else
|
||||
exports.log = new NodeLogger();
|
||||
|
||||
})(typeof exports !== 'undefined' ? exports : (window.helpers = window.helpers || {}));
|
||||
2
src/tweetnacl/test/browser/.gitignore
vendored
Normal file
2
src/tweetnacl/test/browser/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
_bundle.js
|
||||
_bundle-quick.js
|
||||
9
src/tweetnacl/test/browser/README
Normal file
9
src/tweetnacl/test/browser/README
Normal file
@ -0,0 +1,9 @@
|
||||
This directory contains test files for browsers.
|
||||
|
||||
In the root project directory:
|
||||
|
||||
$ npm run browser
|
||||
|
||||
to build new _bundle.js.
|
||||
|
||||
Then open test.html.
|
||||
11
src/tweetnacl/test/browser/index.html
Normal file
11
src/tweetnacl/test/browser/index.html
Normal file
@ -0,0 +1,11 @@
|
||||
<!doctype html>
|
||||
<title>TweetNaCl.js Tests</title>
|
||||
<body>
|
||||
<h1>Select test to run:</h1>
|
||||
<ul>
|
||||
<li><a href="test.html"><b>Full</b> nacl.min.js</a></li>
|
||||
<li><a href="test-fast.html"><b>Full</b> nacl-fast.min.js</a></li>
|
||||
<li>--</li>
|
||||
<li><a href="test-quick.html"><b>Quick</b> nacl.min.js</a></li>
|
||||
<li><a href="test-quick-fast.html"><b>Quick</b> nacl-fast.min.js</a></li>
|
||||
</body>
|
||||
1
src/tweetnacl/test/browser/init.js
Normal file
1
src/tweetnacl/test/browser/init.js
Normal file
@ -0,0 +1 @@
|
||||
var _ = require('tap-browser-color')();
|
||||
12
src/tweetnacl/test/browser/test-fast.html
Normal file
12
src/tweetnacl/test/browser/test-fast.html
Normal file
@ -0,0 +1,12 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>TweetNaCl-js Tests (fast)</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>TweetNaCl-js Tests (fast)</h1>
|
||||
<script src="../../nacl-fast.min.js"></script>
|
||||
<script src="_bundle.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
12
src/tweetnacl/test/browser/test-quick-fast.html
Normal file
12
src/tweetnacl/test/browser/test-quick-fast.html
Normal file
@ -0,0 +1,12 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>TweetNaCl-js Tests (fast)</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>TweetNaCl-js Tests (fast)</h1>
|
||||
<script src="../../nacl-fast.min.js"></script>
|
||||
<script src="_bundle-quick.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
12
src/tweetnacl/test/browser/test-quick.html
Normal file
12
src/tweetnacl/test/browser/test-quick.html
Normal file
@ -0,0 +1,12 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>TweetNaCl-js Tests</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>TweetNaCl-js Tests</h1>
|
||||
<script src="../../nacl.min.js"></script>
|
||||
<script src="_bundle-quick.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
12
src/tweetnacl/test/browser/test.html
Normal file
12
src/tweetnacl/test/browser/test.html
Normal file
@ -0,0 +1,12 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>TweetNaCl-js Tests</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>TweetNaCl-js Tests</h1>
|
||||
<script src="../../nacl.min.js"></script>
|
||||
<script src="_bundle.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
1
src/tweetnacl/test/browser/testling_init.js
Normal file
1
src/tweetnacl/test/browser/testling_init.js
Normal file
@ -0,0 +1 @@
|
||||
window.nacl = require('../../' + (process.env.NACL_SRC || 'nacl.min.js'));
|
||||
6
src/tweetnacl/test/c/.gitignore
vendored
Normal file
6
src/tweetnacl/test/c/.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
cscalarmult
|
||||
cbox
|
||||
csecretbox
|
||||
csign
|
||||
chash
|
||||
*.o
|
||||
54
src/tweetnacl/test/c/00-secretbox.js
Normal file
54
src/tweetnacl/test/c/00-secretbox.js
Normal file
@ -0,0 +1,54 @@
|
||||
var nacl = require('../../' + (process.env.NACL_SRC || 'nacl.min.js'));
|
||||
var crypto = require('crypto');
|
||||
var spawn = require('child_process').spawn;
|
||||
var path = require('path');
|
||||
var test = require('tape');
|
||||
|
||||
function csecretbox(msg, n, k, callback) {
|
||||
var hexk = (new Buffer(k)).toString('hex');
|
||||
var hexn = (new Buffer(n)).toString('hex');
|
||||
var p = spawn(path.resolve(__dirname, 'csecretbox'), [hexk, hexn]);
|
||||
var result = [];
|
||||
p.stdout.on('data', function(data) {
|
||||
result.push(data);
|
||||
});
|
||||
p.on('close', function(code) {
|
||||
return callback(Buffer.concat(result).toString('base64'));
|
||||
});
|
||||
p.on('error', function(err) {
|
||||
throw err;
|
||||
});
|
||||
p.stdin.write(msg);
|
||||
p.stdin.end();
|
||||
}
|
||||
|
||||
test('nacl.secretbox (C)', function(t) {
|
||||
var k = new Uint8Array(nacl.secretbox.keyLength),
|
||||
n = new Uint8Array(nacl.secretbox.nonceLength),
|
||||
i;
|
||||
for (i = 0; i < 32; i++) k[i] = i;
|
||||
for (i = 0; i < 24; i++) n[i] = i;
|
||||
|
||||
function check(num, maxNum, next) {
|
||||
var msg = nacl.randomBytes(num);
|
||||
var box = nacl.util.encodeBase64(nacl.secretbox(msg, n, k));
|
||||
csecretbox(new Buffer(msg), n, k, function(boxFromC) {
|
||||
t.equal(box, boxFromC, 'secretboxes should be equal');
|
||||
t.notEqual(nacl.secretbox.open(nacl.util.decodeBase64(boxFromC), n, k), false, 'opening should succeed');
|
||||
if (num >= maxNum) {
|
||||
if (next) next();
|
||||
return;
|
||||
}
|
||||
check(num+1, maxNum, next);
|
||||
});
|
||||
}
|
||||
|
||||
check(0, 1024, function() {
|
||||
check(16418, 16500, function() {
|
||||
check(1000000, 0, function() {
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
44
src/tweetnacl/test/c/01-scalarmult.js
Normal file
44
src/tweetnacl/test/c/01-scalarmult.js
Normal file
@ -0,0 +1,44 @@
|
||||
var NUMBER_OF_TESTS = 1000;
|
||||
|
||||
var nacl = require('../../' + (process.env.NACL_SRC || 'nacl.min.js'));
|
||||
var execFile = require('child_process').execFile;
|
||||
var path = require('path');
|
||||
var test = require('tape');
|
||||
|
||||
function cscalarmult(n, p, callback) {
|
||||
var hexN = (new Buffer(n)).toString('hex');
|
||||
var hexP = (new Buffer(p)).toString('hex');
|
||||
|
||||
execFile(path.resolve(__dirname, 'cscalarmult'), [hexN, hexP], function(err, stdout) {
|
||||
if (err) throw err;
|
||||
callback(stdout.toString('utf8'));
|
||||
});
|
||||
}
|
||||
|
||||
test('nacl.scalarMult (C)', function(t) {
|
||||
var k1 = {
|
||||
publicKey: nacl.util.decodeBase64('JRAWWRKVfZS2U/QiV+X2+PaabPfAB4H9p+BZkBN8ji8='),
|
||||
secretKey: nacl.util.decodeBase64('5g1pBmI3HL5GAjtt3/2FZDQVfGSMNohngN7OVSizBVE=')
|
||||
};
|
||||
|
||||
function check(num) {
|
||||
var k2 = nacl.box.keyPair();
|
||||
var q1 = nacl.scalarMult(k1.secretKey, k2.publicKey);
|
||||
var q2 = nacl.scalarMult(k2.secretKey, k1.publicKey);
|
||||
|
||||
t.equal(nacl.util.encodeBase64(q1), nacl.util.encodeBase64(q2),
|
||||
'scalarMult results should be equal');
|
||||
|
||||
hexQ = (new Buffer(q1)).toString('hex');
|
||||
cscalarmult(k1.secretKey, k2.publicKey, function(cQ) {
|
||||
t.equal(hexQ, cQ);
|
||||
if (num >= NUMBER_OF_TESTS) {
|
||||
t.end();
|
||||
return;
|
||||
}
|
||||
check(num+1);
|
||||
});
|
||||
}
|
||||
|
||||
check(0);
|
||||
});
|
||||
51
src/tweetnacl/test/c/02-box.js
Normal file
51
src/tweetnacl/test/c/02-box.js
Normal file
@ -0,0 +1,51 @@
|
||||
var nacl = require('../../' + (process.env.NACL_SRC || 'nacl.min.js'));
|
||||
var crypto = require('crypto');
|
||||
var spawn = require('child_process').spawn;
|
||||
var path = require('path');
|
||||
var test = require('tape');
|
||||
|
||||
function cbox(msg, sk, pk, n, callback) {
|
||||
var hexsk = (new Buffer(sk)).toString('hex');
|
||||
var hexpk = (new Buffer(pk)).toString('hex');
|
||||
var hexn = (new Buffer(n)).toString('hex');
|
||||
var p = spawn(path.resolve(__dirname, 'cbox'), [hexsk, hexpk, hexn]);
|
||||
var result = [];
|
||||
p.stdout.on('data', function(data) {
|
||||
result.push(data);
|
||||
});
|
||||
p.on('close', function(code) {
|
||||
return callback(Buffer.concat(result).toString('base64'));
|
||||
});
|
||||
p.on('error', function(err) {
|
||||
throw err;
|
||||
});
|
||||
p.stdin.write(msg);
|
||||
p.stdin.end();
|
||||
}
|
||||
|
||||
test('nacl.box (C)', function(t) {
|
||||
var k1 = nacl.box.keyPair();
|
||||
|
||||
function check(num, maxNum, next) {
|
||||
var sk2 = nacl.randomBytes(nacl.box.secretKeyLength);
|
||||
var msg = nacl.randomBytes(num);
|
||||
var nonce = nacl.randomBytes(24);
|
||||
var box = nacl.util.encodeBase64(nacl.box(msg, nonce, k1.publicKey, sk2));
|
||||
cbox(new Buffer(msg), sk2, k1.publicKey, nonce, function(boxFromC) {
|
||||
t.equal(box, boxFromC, 'boxes should be equal');
|
||||
t.notEqual(nacl.box.open(nacl.util.decodeBase64(boxFromC), nonce, k1.publicKey, sk2),
|
||||
false, 'opening box should succeed');
|
||||
if (num >= maxNum) {
|
||||
if (next) next();
|
||||
return;
|
||||
}
|
||||
check(num+1, maxNum, next);
|
||||
});
|
||||
}
|
||||
|
||||
check(0, 1024, function() {
|
||||
check(16417, 16500, function() {
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
});
|
||||
39
src/tweetnacl/test/c/03-hash.js
Normal file
39
src/tweetnacl/test/c/03-hash.js
Normal file
@ -0,0 +1,39 @@
|
||||
var nacl = require('../../' + (process.env.NACL_SRC || 'nacl.min.js'));
|
||||
var crypto = require('crypto');
|
||||
var spawn = require('child_process').spawn;
|
||||
var path = require('path');
|
||||
var test = require('tape');
|
||||
|
||||
function chash(msg, callback) {
|
||||
var p = spawn(path.resolve(__dirname, 'chash'));
|
||||
var result = [];
|
||||
p.stdout.on('data', function(data) {
|
||||
result.push(data);
|
||||
});
|
||||
p.on('close', function(code) {
|
||||
return callback(Buffer.concat(result).toString('utf8'));
|
||||
});
|
||||
p.on('error', function(err) {
|
||||
throw err;
|
||||
});
|
||||
p.stdin.write(msg);
|
||||
p.stdin.end();
|
||||
}
|
||||
|
||||
test('nacl.hash (C)', function(t) {
|
||||
function check(num) {
|
||||
var msg = nacl.randomBytes(num);
|
||||
var h = nacl.hash(msg);
|
||||
var hexH = (new Buffer(h)).toString('hex');
|
||||
chash(new Buffer(msg), function(hexCH) {
|
||||
t.equal(hexH, hexCH, 'hashes should be equal');
|
||||
if (num >= 1000) {
|
||||
t.end();
|
||||
return;
|
||||
}
|
||||
check(num+1);
|
||||
});
|
||||
}
|
||||
|
||||
check(0);
|
||||
});
|
||||
44
src/tweetnacl/test/c/04-sign.js
Normal file
44
src/tweetnacl/test/c/04-sign.js
Normal file
@ -0,0 +1,44 @@
|
||||
var nacl = require('../../' + (process.env.NACL_SRC || 'nacl.min.js'));
|
||||
var crypto = require('crypto');
|
||||
var spawn = require('child_process').spawn;
|
||||
var path = require('path');
|
||||
var test = require('tape');
|
||||
|
||||
function csign(sk, msg, callback) {
|
||||
var hexsk = (new Buffer(sk)).toString('hex');
|
||||
var p = spawn(path.resolve(__dirname, 'csign'), [hexsk]);
|
||||
var result = [];
|
||||
p.stdout.on('data', function(data) {
|
||||
result.push(data);
|
||||
});
|
||||
p.on('close', function(code) {
|
||||
callback(Buffer.concat(result).toString('base64'));
|
||||
});
|
||||
p.on('error', function(err) {
|
||||
throw err;
|
||||
});
|
||||
p.stdin.write(msg);
|
||||
p.stdin.end();
|
||||
}
|
||||
|
||||
test('nacl.sign (C)', function(t) {
|
||||
function check(num) {
|
||||
var keys = nacl.sign.keyPair();
|
||||
var msg = nacl.randomBytes(num);
|
||||
var signedMsg = nacl.util.encodeBase64(nacl.sign(msg, keys.secretKey));
|
||||
csign(keys.secretKey, new Buffer(msg), function(signedFromC) {
|
||||
t.equal(signedMsg, signedFromC, 'signed messages should be equal');
|
||||
var openedMsg = nacl.sign.open(nacl.util.decodeBase64(signedFromC), keys.publicKey);
|
||||
t.notEqual(openedMsg, null, 'open should succeed');
|
||||
t.equal(nacl.util.encodeBase64(openedMsg), nacl.util.encodeBase64(msg),
|
||||
'messages should be equal');
|
||||
if (num >= 100) {
|
||||
t.end();
|
||||
return;
|
||||
}
|
||||
check(num+1);
|
||||
});
|
||||
}
|
||||
|
||||
check(0);
|
||||
});
|
||||
52
src/tweetnacl/test/c/05-sign-keypair.js
Normal file
52
src/tweetnacl/test/c/05-sign-keypair.js
Normal file
@ -0,0 +1,52 @@
|
||||
var nacl = require('../../' + (process.env.NACL_SRC || 'nacl.min.js'));
|
||||
var crypto = require('crypto');
|
||||
var spawn = require('child_process').spawn;
|
||||
var execFile = require('child_process').execFile;
|
||||
var path = require('path');
|
||||
var test = require('tape');
|
||||
|
||||
function csign(sk, msg, callback) {
|
||||
var hexsk = (new Buffer(sk)).toString('hex');
|
||||
var p = spawn(path.resolve(__dirname, 'csign'), [hexsk]);
|
||||
var result = [];
|
||||
p.stdout.on('data', function(data) {
|
||||
result.push(data);
|
||||
});
|
||||
p.on('close', function(code) {
|
||||
callback(Buffer.concat(result).toString('base64'));
|
||||
});
|
||||
p.on('error', function(err) {
|
||||
throw err;
|
||||
});
|
||||
p.stdin.write(msg);
|
||||
p.stdin.end();
|
||||
}
|
||||
|
||||
function csignkeypair(callback) {
|
||||
execFile(path.resolve(__dirname, 'csign-keypair'), [], function(err, stdout) {
|
||||
if (err) throw err;
|
||||
callback(stdout.toString('utf8'));
|
||||
});
|
||||
}
|
||||
|
||||
test('nacl.sign (C) with keypair from C', function(t) {
|
||||
function check(num) {
|
||||
csignkeypair(function(hexSecretKey) {
|
||||
var secretKey = new Uint8Array(nacl.sign.secretKeyLength);
|
||||
var b = new Buffer(hexSecretKey, 'hex');
|
||||
for (var i = 0; i < b.length; i++) secretKey[i] = b[i];
|
||||
var msg = nacl.randomBytes(num);
|
||||
var signedMsg = nacl.util.encodeBase64(nacl.sign(msg, secretKey));
|
||||
csign(secretKey, new Buffer(msg), function(signedFromC) {
|
||||
t.equal(signedMsg, signedFromC, 'signed messages should be equal');
|
||||
if (num >= 100) {
|
||||
t.end();
|
||||
return;
|
||||
}
|
||||
check(num+1);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
check(0);
|
||||
});
|
||||
38
src/tweetnacl/test/c/Makefile
Normal file
38
src/tweetnacl/test/c/Makefile
Normal file
@ -0,0 +1,38 @@
|
||||
CFLAGS=-O3
|
||||
|
||||
all: csecretbox cscalarmult cbox chash csign csign-keypair
|
||||
|
||||
csecretbox: csecretbox.o tweetnacl.o
|
||||
|
||||
cscalarmult: cscalarmult.o tweetnacl.o
|
||||
|
||||
cbox: cbox.o tweetnacl.o
|
||||
|
||||
chash: chash.o tweetnacl.o
|
||||
|
||||
csign: csign.o tweetnacl.o
|
||||
|
||||
csign-keypair: csign-keypair.o tweetnacl.o
|
||||
|
||||
test: test_secretbox test_scalarmult test_box test_hash test_sign test_signkeypair clean
|
||||
|
||||
test_secretbox: csecretbox
|
||||
node ./00-secretbox.js
|
||||
|
||||
test_scalarmult: cscalarmult
|
||||
node ./01-scalarmult.js
|
||||
|
||||
test_box: cbox
|
||||
node ./02-box.js
|
||||
|
||||
test_hash: chash
|
||||
node ./03-hash.js
|
||||
|
||||
test_sign: csign
|
||||
node ./04-sign.js
|
||||
|
||||
test_signkeypair: csign csign-keypair
|
||||
node ./05-sign-keypair.js
|
||||
|
||||
clean:
|
||||
rm *.o csecretbox cscalarmult cbox chash csign csign-keypair
|
||||
8
src/tweetnacl/test/c/README
Normal file
8
src/tweetnacl/test/c/README
Normal file
@ -0,0 +1,8 @@
|
||||
Tests that call C programs based on original tweetnacl.c,
|
||||
and compare results with TweetNaCl-js.
|
||||
|
||||
Work only in Node.js.
|
||||
|
||||
To run, in this directory:
|
||||
|
||||
$ make test
|
||||
105
src/tweetnacl/test/c/cbox.c
Normal file
105
src/tweetnacl/test/c/cbox.c
Normal file
@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Written by @dchest. Public domain.
|
||||
*/
|
||||
#include <err.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "tweetnacl.h"
|
||||
|
||||
size_t
|
||||
readmsg(unsigned char **out)
|
||||
{
|
||||
unsigned char buf[4096];
|
||||
size_t n, have = 0;
|
||||
unsigned char *msg = calloc(1, crypto_box_ZEROBYTES);
|
||||
if (msg == NULL)
|
||||
err(1, NULL);
|
||||
have = crypto_box_ZEROBYTES;
|
||||
while (!feof(stdin)) {
|
||||
n = fread(buf, 1, sizeof(buf), stdin);
|
||||
if (n == 0)
|
||||
break;
|
||||
if ((msg = realloc(msg, have + n)) == NULL)
|
||||
err(1, NULL);
|
||||
memcpy(&msg[have], buf, n);
|
||||
have += n;
|
||||
}
|
||||
*out = msg;
|
||||
return have;
|
||||
}
|
||||
|
||||
unsigned char
|
||||
dechexchar(char c)
|
||||
{
|
||||
if (c >= '0' && c <= '9')
|
||||
return (c - 0x30);
|
||||
else if (c >= 'A' && c <= 'F')
|
||||
return (c - 0x37);
|
||||
else if (c >= 'a' && c <= 'f')
|
||||
return (c - 0x57);
|
||||
else
|
||||
errx(1, "not a hex char");
|
||||
|
||||
}
|
||||
|
||||
unsigned char *
|
||||
decodehex(const char *h)
|
||||
{
|
||||
unsigned char *r, *p, a, b;
|
||||
size_t i, len;
|
||||
|
||||
len = strlen(h);
|
||||
if ((r = malloc(len / 2)) == NULL)
|
||||
err(1, NULL);
|
||||
p = r;
|
||||
if (len % 2 != 0)
|
||||
errx(1, "bad hex string length");
|
||||
for (i = 0; i < len; i += 2)
|
||||
*p++ = ((dechexchar(h[i]) * 16) & 0xf0) + (dechexchar(h[i+1]) & 0xf);
|
||||
return r;
|
||||
}
|
||||
|
||||
void
|
||||
randombytes(unsigned char *x, long long y)
|
||||
{
|
||||
errx(1, "we don't use randombytes");
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, const char **argv)
|
||||
{
|
||||
unsigned char *sk, *pk, *n, *m, *c;
|
||||
size_t mlen, clen;
|
||||
|
||||
if (argc < 2) {
|
||||
puts("usage: cbox SK PK NONCE");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (strlen(argv[1]) != crypto_box_SECRETKEYBYTES * 2)
|
||||
errx(1, "bad SK length");
|
||||
sk = decodehex(argv[1]);
|
||||
|
||||
if (strlen(argv[2]) != crypto_box_PUBLICKEYBYTES * 2)
|
||||
errx(1, "bad PK length");
|
||||
pk = decodehex(argv[2]);
|
||||
|
||||
if (strlen(argv[3]) != crypto_box_NONCEBYTES * 2)
|
||||
errx(1, "bad NONCE length");
|
||||
n = decodehex(argv[3]);
|
||||
|
||||
mlen = readmsg(&m);
|
||||
if ((c = calloc(mlen, 1)) == NULL)
|
||||
err(1, NULL);
|
||||
|
||||
crypto_box(c, m, mlen, n, pk, sk);
|
||||
c += crypto_box_BOXZEROBYTES;
|
||||
clen = mlen - crypto_box_BOXZEROBYTES;
|
||||
|
||||
if (fwrite(c, 1, clen, stdout) != clen)
|
||||
err(1, NULL);
|
||||
return 0;
|
||||
}
|
||||
49
src/tweetnacl/test/c/chash.c
Normal file
49
src/tweetnacl/test/c/chash.c
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* This program sings a message using tweetnacl.c.
|
||||
* Written by @dchest. Public domain.
|
||||
*/
|
||||
#include <err.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "tweetnacl.h"
|
||||
|
||||
size_t
|
||||
readmsg(unsigned char **out)
|
||||
{
|
||||
unsigned char buf[4096];
|
||||
unsigned char *msg = NULL;
|
||||
size_t n, have = 0;
|
||||
while (!feof(stdin)) {
|
||||
n = fread(buf, 1, sizeof(buf), stdin);
|
||||
if (n == 0)
|
||||
break;
|
||||
if ((msg = realloc(msg, have + n)) == NULL)
|
||||
err(1, NULL);
|
||||
memcpy(&msg[have], buf, n);
|
||||
have += n;
|
||||
}
|
||||
*out = msg;
|
||||
return have;
|
||||
}
|
||||
|
||||
void
|
||||
randombytes(unsigned char *x, long long y)
|
||||
{
|
||||
errx(1, "we don't use randombytes");
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, const char **argv)
|
||||
{
|
||||
unsigned char *m, h[crypto_hash_BYTES];
|
||||
size_t mlen, i;
|
||||
|
||||
mlen = readmsg(&m);
|
||||
crypto_hash(h, m, mlen);
|
||||
for (i = 0; i < sizeof(h); i++)
|
||||
printf("%02x", h[i]);
|
||||
return 0;
|
||||
}
|
||||
73
src/tweetnacl/test/c/cscalarmult.c
Normal file
73
src/tweetnacl/test/c/cscalarmult.c
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Written by @dchest. Public domain.
|
||||
*/
|
||||
#include <err.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "tweetnacl.h"
|
||||
|
||||
unsigned char
|
||||
dechexchar(char c)
|
||||
{
|
||||
if (c >= '0' && c <= '9')
|
||||
return (c - 0x30);
|
||||
else if (c >= 'A' && c <= 'F')
|
||||
return (c - 0x37);
|
||||
else if (c >= 'a' && c <= 'f')
|
||||
return (c - 0x57);
|
||||
else
|
||||
errx(1, "not a hex char");
|
||||
|
||||
}
|
||||
|
||||
unsigned char *
|
||||
decodehex(const char *h)
|
||||
{
|
||||
unsigned char *r, *p, a, b;
|
||||
size_t i, len;
|
||||
|
||||
len = strlen(h);
|
||||
if (len == 0 || len % 2 != 0)
|
||||
errx(1, "bad hex string length");
|
||||
if ((r = malloc(len / 2)) == NULL)
|
||||
err(1, NULL);
|
||||
p = r;
|
||||
for (i = 0; i < len; i += 2)
|
||||
*p++ = ((dechexchar(h[i]) * 16) & 0xf0) + (dechexchar(h[i+1]) & 0xf);
|
||||
return r;
|
||||
}
|
||||
|
||||
void
|
||||
randombytes(unsigned char *x, long long y)
|
||||
{
|
||||
errx(1, "we don't use randombytes");
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, const char **argv)
|
||||
{
|
||||
unsigned char *n, *p, q[crypto_scalarmult_BYTES];
|
||||
size_t i;
|
||||
|
||||
if (argc < 2) {
|
||||
puts("usage: cscalarmult N P");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (strlen(argv[1]) != crypto_scalarmult_SCALARBYTES * 2)
|
||||
errx(1, "bad N length");
|
||||
n = decodehex(argv[1]);
|
||||
|
||||
if (strlen(argv[2]) != crypto_scalarmult_SCALARBYTES * 2)
|
||||
errx(1, "bad P length");
|
||||
p = decodehex(argv[2]);
|
||||
|
||||
crypto_scalarmult(q, n, p);
|
||||
|
||||
for (i = 0; i < sizeof(q); i++)
|
||||
printf("%02x", q[i]);
|
||||
return 0;
|
||||
}
|
||||
108
src/tweetnacl/test/c/csecretbox.c
Normal file
108
src/tweetnacl/test/c/csecretbox.c
Normal file
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Written by @dchest. Public domain.
|
||||
*/
|
||||
#include <err.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "tweetnacl.h"
|
||||
|
||||
size_t
|
||||
readmsg(unsigned char **out)
|
||||
{
|
||||
unsigned char buf[4096];
|
||||
size_t n, have = 0;
|
||||
unsigned char *msg = calloc(1, crypto_secretbox_ZEROBYTES);
|
||||
if (msg == NULL)
|
||||
err(1, NULL);
|
||||
have = crypto_secretbox_ZEROBYTES;
|
||||
while (!feof(stdin)) {
|
||||
n = fread(buf, 1, sizeof(buf), stdin);
|
||||
if (n == 0)
|
||||
break;
|
||||
if ((msg = realloc(msg, have + n)) == NULL)
|
||||
err(1, NULL);
|
||||
memcpy(&msg[have], buf, n);
|
||||
have += n;
|
||||
}
|
||||
*out = msg;
|
||||
return have;
|
||||
}
|
||||
|
||||
unsigned char
|
||||
dechexchar(char c)
|
||||
{
|
||||
if (c >= '0' && c <= '9')
|
||||
return (c - 0x30);
|
||||
else if (c >= 'A' && c <= 'F')
|
||||
return (c - 0x37);
|
||||
else if (c >= 'a' && c <= 'f')
|
||||
return (c - 0x57);
|
||||
else
|
||||
errx(1, "not a hex char");
|
||||
|
||||
}
|
||||
|
||||
unsigned char *
|
||||
decodehex(const char *h)
|
||||
{
|
||||
unsigned char *r, *p, a, b;
|
||||
size_t i, len;
|
||||
|
||||
len = strlen(h);
|
||||
if ((r = malloc(len / 2)) == NULL)
|
||||
err(1, NULL);
|
||||
p = r;
|
||||
if (len % 2 != 0)
|
||||
errx(1, "bad hex string length");
|
||||
for (i = 0; i < len; i += 2)
|
||||
*p++ = ((dechexchar(h[i]) * 16) & 0xf0) + (dechexchar(h[i+1]) & 0xf);
|
||||
return r;
|
||||
}
|
||||
|
||||
void
|
||||
randombytes(unsigned char *x, long long y)
|
||||
{
|
||||
errx(1, "we don't use randombytes");
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, const char **argv)
|
||||
{
|
||||
unsigned char *k, *n, *m, *c;
|
||||
size_t mlen, clen;
|
||||
|
||||
if (argc < 2) {
|
||||
puts("usage: csecretbox KEY NONCE");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (strlen(argv[1]) != crypto_secretbox_KEYBYTES * 2)
|
||||
errx(1, "bad KEY length");
|
||||
k = decodehex(argv[1]);
|
||||
|
||||
if (strlen(argv[2]) != crypto_secretbox_NONCEBYTES * 2)
|
||||
errx(1, "bad NONCE length");
|
||||
n = decodehex(argv[2]);
|
||||
|
||||
mlen = readmsg(&m);
|
||||
|
||||
#if 0
|
||||
FILE *f = fopen("csecretbox_debug.txt", "w");
|
||||
fwrite(m, 1, mlen, f);
|
||||
fclose(f);
|
||||
#endif
|
||||
|
||||
if ((c = calloc(mlen, 1)) == NULL)
|
||||
err(1, NULL);
|
||||
|
||||
crypto_secretbox(c, m, mlen, n, k);
|
||||
c += crypto_secretbox_BOXZEROBYTES;
|
||||
clen = mlen - crypto_secretbox_BOXZEROBYTES;
|
||||
|
||||
if (fwrite(c, 1, clen, stdout) != clen)
|
||||
err(1, NULL);
|
||||
return 0;
|
||||
}
|
||||
53
src/tweetnacl/test/c/csign-keypair.c
Normal file
53
src/tweetnacl/test/c/csign-keypair.c
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* This program generates a sign secret key using tweetnacl.c.
|
||||
* Written by @dchest. Public domain.
|
||||
*/
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "tweetnacl.h"
|
||||
|
||||
void randombytes(unsigned char *x,unsigned long long xlen) {
|
||||
static int fd = -1;
|
||||
int i;
|
||||
|
||||
if (fd == -1) {
|
||||
for (;;) {
|
||||
fd = open("/dev/urandom",O_RDONLY);
|
||||
if (fd != -1) break;
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
while (xlen > 0) {
|
||||
if (xlen < 1048576) i = xlen; else i = 1048576;
|
||||
|
||||
i = read(fd,x,i);
|
||||
if (i < 1) {
|
||||
sleep(1);
|
||||
continue;
|
||||
}
|
||||
|
||||
x += i;
|
||||
xlen -= i;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, const char **argv)
|
||||
{
|
||||
unsigned char pk[crypto_sign_PUBLICKEYBYTES],
|
||||
sk[crypto_sign_SECRETKEYBYTES];
|
||||
int i;
|
||||
|
||||
crypto_sign_keypair(pk, sk);
|
||||
for (i = 0; i < sizeof(sk); i++)
|
||||
printf("%02x", sk[i]);
|
||||
return 0;
|
||||
}
|
||||
91
src/tweetnacl/test/c/csign.c
Normal file
91
src/tweetnacl/test/c/csign.c
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* This program signs a message using tweetnacl.c.
|
||||
* Written by @dchest. Public domain.
|
||||
*/
|
||||
#include <err.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "tweetnacl.h"
|
||||
|
||||
size_t
|
||||
readmsg(unsigned char **out)
|
||||
{
|
||||
unsigned char buf[4096];
|
||||
unsigned char *msg = NULL;
|
||||
size_t n, have = 0;
|
||||
while (!feof(stdin)) {
|
||||
n = fread(buf, 1, sizeof(buf), stdin);
|
||||
if (n == 0)
|
||||
break;
|
||||
if ((msg = realloc(msg, have + n)) == NULL)
|
||||
err(1, NULL);
|
||||
memcpy(&msg[have], buf, n);
|
||||
have += n;
|
||||
}
|
||||
*out = msg;
|
||||
return have;
|
||||
}
|
||||
|
||||
unsigned char
|
||||
dechexchar(char c)
|
||||
{
|
||||
if (c >= '0' && c <= '9')
|
||||
return (c - 0x30);
|
||||
else if (c >= 'A' && c <= 'F')
|
||||
return (c - 0x37);
|
||||
else if (c >= 'a' && c <= 'f')
|
||||
return (c - 0x57);
|
||||
else
|
||||
errx(1, "not a hex char");
|
||||
|
||||
}
|
||||
|
||||
unsigned char *
|
||||
decodehex(const char *h)
|
||||
{
|
||||
unsigned char *r, *p, a, b;
|
||||
size_t i, len;
|
||||
|
||||
len = strlen(h);
|
||||
if ((r = malloc(len / 2)) == NULL)
|
||||
err(1, NULL);
|
||||
p = r;
|
||||
if (len % 2 != 0)
|
||||
errx(1, "bad hex string length");
|
||||
for (i = 0; i < len; i += 2)
|
||||
*p++ = ((dechexchar(h[i]) * 16) & 0xf0) + (dechexchar(h[i+1]) & 0xf);
|
||||
return r;
|
||||
}
|
||||
|
||||
void
|
||||
randombytes(unsigned char *x, long long y)
|
||||
{
|
||||
errx(1, "we don't use randombytes");
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, const char **argv)
|
||||
{
|
||||
unsigned char *sk, *m, *sm;
|
||||
size_t mlen, n;
|
||||
long long unsigned int smlen;
|
||||
|
||||
if (argc < 2) {
|
||||
puts("usage: csign PRIVATE_KEY");
|
||||
return 1;
|
||||
}
|
||||
if (strlen(argv[1]) != crypto_sign_SECRETKEYBYTES * 2)
|
||||
errx(1, "bad key length");
|
||||
sk = decodehex(argv[1]);
|
||||
mlen = readmsg(&m);
|
||||
if ((sm = calloc(mlen + crypto_sign_BYTES, 1)) == NULL)
|
||||
err(1, NULL);
|
||||
|
||||
crypto_sign(sm, &smlen, m, mlen, sk);
|
||||
if (fwrite(sm, 1, smlen, stdout) != smlen)
|
||||
err(1, NULL);
|
||||
return 0;
|
||||
}
|
||||
809
src/tweetnacl/test/c/tweetnacl.c
Normal file
809
src/tweetnacl/test/c/tweetnacl.c
Normal file
@ -0,0 +1,809 @@
|
||||
#include "tweetnacl.h"
|
||||
#define FOR(i,n) for (i = 0;i < n;++i)
|
||||
#define sv static void
|
||||
|
||||
typedef unsigned char u8;
|
||||
typedef unsigned long u32;
|
||||
typedef unsigned long long u64;
|
||||
typedef long long i64;
|
||||
typedef i64 gf[16];
|
||||
extern void randombytes(u8 *,u64);
|
||||
|
||||
static const u8
|
||||
_0[16],
|
||||
_9[32] = {9};
|
||||
static const gf
|
||||
gf0,
|
||||
gf1 = {1},
|
||||
_121665 = {0xDB41,1},
|
||||
D = {0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203},
|
||||
D2 = {0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 0xd130, 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406},
|
||||
X = {0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 0xdc5c, 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169},
|
||||
Y = {0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666},
|
||||
I = {0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83};
|
||||
|
||||
static u32 L32(u32 x,int c) { return (x << c) | ((x&0xffffffff) >> (32 - c)); }
|
||||
|
||||
static u32 ld32(const u8 *x)
|
||||
{
|
||||
u32 u = x[3];
|
||||
u = (u<<8)|x[2];
|
||||
u = (u<<8)|x[1];
|
||||
return (u<<8)|x[0];
|
||||
}
|
||||
|
||||
static u64 dl64(const u8 *x)
|
||||
{
|
||||
u64 i,u=0;
|
||||
FOR(i,8) u=(u<<8)|x[i];
|
||||
return u;
|
||||
}
|
||||
|
||||
sv st32(u8 *x,u32 u)
|
||||
{
|
||||
int i;
|
||||
FOR(i,4) { x[i] = u; u >>= 8; }
|
||||
}
|
||||
|
||||
sv ts64(u8 *x,u64 u)
|
||||
{
|
||||
int i;
|
||||
for (i = 7;i >= 0;--i) { x[i] = u; u >>= 8; }
|
||||
}
|
||||
|
||||
static int vn(const u8 *x,const u8 *y,int n)
|
||||
{
|
||||
u32 i,d = 0;
|
||||
FOR(i,n) d |= x[i]^y[i];
|
||||
return (1 & ((d - 1) >> 8)) - 1;
|
||||
}
|
||||
|
||||
int crypto_verify_16(const u8 *x,const u8 *y)
|
||||
{
|
||||
return vn(x,y,16);
|
||||
}
|
||||
|
||||
int crypto_verify_32(const u8 *x,const u8 *y)
|
||||
{
|
||||
return vn(x,y,32);
|
||||
}
|
||||
|
||||
sv core(u8 *out,const u8 *in,const u8 *k,const u8 *c,int h)
|
||||
{
|
||||
u32 w[16],x[16],y[16],t[4];
|
||||
int i,j,m;
|
||||
|
||||
FOR(i,4) {
|
||||
x[5*i] = ld32(c+4*i);
|
||||
x[1+i] = ld32(k+4*i);
|
||||
x[6+i] = ld32(in+4*i);
|
||||
x[11+i] = ld32(k+16+4*i);
|
||||
}
|
||||
|
||||
FOR(i,16) y[i] = x[i];
|
||||
|
||||
FOR(i,20) {
|
||||
FOR(j,4) {
|
||||
FOR(m,4) t[m] = x[(5*j+4*m)%16];
|
||||
t[1] ^= L32(t[0]+t[3], 7);
|
||||
t[2] ^= L32(t[1]+t[0], 9);
|
||||
t[3] ^= L32(t[2]+t[1],13);
|
||||
t[0] ^= L32(t[3]+t[2],18);
|
||||
FOR(m,4) w[4*j+(j+m)%4] = t[m];
|
||||
}
|
||||
FOR(m,16) x[m] = w[m];
|
||||
}
|
||||
|
||||
if (h) {
|
||||
FOR(i,16) x[i] += y[i];
|
||||
FOR(i,4) {
|
||||
x[5*i] -= ld32(c+4*i);
|
||||
x[6+i] -= ld32(in+4*i);
|
||||
}
|
||||
FOR(i,4) {
|
||||
st32(out+4*i,x[5*i]);
|
||||
st32(out+16+4*i,x[6+i]);
|
||||
}
|
||||
} else
|
||||
FOR(i,16) st32(out + 4 * i,x[i] + y[i]);
|
||||
}
|
||||
|
||||
int crypto_core_salsa20(u8 *out,const u8 *in,const u8 *k,const u8 *c)
|
||||
{
|
||||
core(out,in,k,c,0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypto_core_hsalsa20(u8 *out,const u8 *in,const u8 *k,const u8 *c)
|
||||
{
|
||||
core(out,in,k,c,1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const u8 sigma[16] = "expand 32-byte k";
|
||||
|
||||
int crypto_stream_salsa20_xor(u8 *c,const u8 *m,u64 b,const u8 *n,const u8 *k)
|
||||
{
|
||||
u8 z[16],x[64];
|
||||
u32 u,i;
|
||||
if (!b) return 0;
|
||||
FOR(i,16) z[i] = 0;
|
||||
FOR(i,8) z[i] = n[i];
|
||||
while (b >= 64) {
|
||||
crypto_core_salsa20(x,z,k,sigma);
|
||||
FOR(i,64) c[i] = (m?m[i]:0) ^ x[i];
|
||||
u = 1;
|
||||
for (i = 8;i < 16;++i) {
|
||||
u += (u32) z[i];
|
||||
z[i] = u;
|
||||
u >>= 8;
|
||||
}
|
||||
b -= 64;
|
||||
c += 64;
|
||||
if (m) m += 64;
|
||||
}
|
||||
if (b) {
|
||||
crypto_core_salsa20(x,z,k,sigma);
|
||||
FOR(i,b) c[i] = (m?m[i]:0) ^ x[i];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypto_stream_salsa20(u8 *c,u64 d,const u8 *n,const u8 *k)
|
||||
{
|
||||
return crypto_stream_salsa20_xor(c,0,d,n,k);
|
||||
}
|
||||
|
||||
int crypto_stream(u8 *c,u64 d,const u8 *n,const u8 *k)
|
||||
{
|
||||
u8 s[32];
|
||||
crypto_core_hsalsa20(s,n,k,sigma);
|
||||
return crypto_stream_salsa20(c,d,n+16,s);
|
||||
}
|
||||
|
||||
int crypto_stream_xor(u8 *c,const u8 *m,u64 d,const u8 *n,const u8 *k)
|
||||
{
|
||||
u8 s[32];
|
||||
crypto_core_hsalsa20(s,n,k,sigma);
|
||||
return crypto_stream_salsa20_xor(c,m,d,n+16,s);
|
||||
}
|
||||
|
||||
sv add1305(u32 *h,const u32 *c)
|
||||
{
|
||||
u32 j,u = 0;
|
||||
FOR(j,17) {
|
||||
u += h[j] + c[j];
|
||||
h[j] = u & 255;
|
||||
u >>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
static const u32 minusp[17] = {
|
||||
5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252
|
||||
} ;
|
||||
|
||||
int crypto_onetimeauth(u8 *out,const u8 *m,u64 n,const u8 *k)
|
||||
{
|
||||
u32 s,i,j,u,x[17],r[17],h[17],c[17],g[17];
|
||||
|
||||
FOR(j,17) r[j]=h[j]=0;
|
||||
FOR(j,16) r[j]=k[j];
|
||||
r[3]&=15;
|
||||
r[4]&=252;
|
||||
r[7]&=15;
|
||||
r[8]&=252;
|
||||
r[11]&=15;
|
||||
r[12]&=252;
|
||||
r[15]&=15;
|
||||
|
||||
while (n > 0) {
|
||||
FOR(j,17) c[j] = 0;
|
||||
for (j = 0;(j < 16) && (j < n);++j) c[j] = m[j];
|
||||
c[j] = 1;
|
||||
m += j; n -= j;
|
||||
add1305(h,c);
|
||||
FOR(i,17) {
|
||||
x[i] = 0;
|
||||
FOR(j,17) x[i] += h[j] * ((j <= i) ? r[i - j] : 320 * r[i + 17 - j]);
|
||||
}
|
||||
FOR(i,17) h[i] = x[i];
|
||||
u = 0;
|
||||
FOR(j,16) {
|
||||
u += h[j];
|
||||
h[j] = u & 255;
|
||||
u >>= 8;
|
||||
}
|
||||
u += h[16]; h[16] = u & 3;
|
||||
u = 5 * (u >> 2);
|
||||
FOR(j,16) {
|
||||
u += h[j];
|
||||
h[j] = u & 255;
|
||||
u >>= 8;
|
||||
}
|
||||
u += h[16]; h[16] = u;
|
||||
}
|
||||
|
||||
FOR(j,17) g[j] = h[j];
|
||||
add1305(h,minusp);
|
||||
s = -(h[16] >> 7);
|
||||
FOR(j,17) h[j] ^= s & (g[j] ^ h[j]);
|
||||
|
||||
FOR(j,16) c[j] = k[j + 16];
|
||||
c[16] = 0;
|
||||
add1305(h,c);
|
||||
FOR(j,16) out[j] = h[j];
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypto_onetimeauth_verify(const u8 *h,const u8 *m,u64 n,const u8 *k)
|
||||
{
|
||||
u8 x[16];
|
||||
crypto_onetimeauth(x,m,n,k);
|
||||
return crypto_verify_16(h,x);
|
||||
}
|
||||
|
||||
int crypto_secretbox(u8 *c,const u8 *m,u64 d,const u8 *n,const u8 *k)
|
||||
{
|
||||
int i;
|
||||
if (d < 32) return -1;
|
||||
crypto_stream_xor(c,m,d,n,k);
|
||||
crypto_onetimeauth(c + 16,c + 32,d - 32,c);
|
||||
FOR(i,16) c[i] = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypto_secretbox_open(u8 *m,const u8 *c,u64 d,const u8 *n,const u8 *k)
|
||||
{
|
||||
int i;
|
||||
u8 x[32];
|
||||
if (d < 32) return -1;
|
||||
crypto_stream(x,32,n,k);
|
||||
if (crypto_onetimeauth_verify(c + 16,c + 32,d - 32,x) != 0) return -1;
|
||||
crypto_stream_xor(m,c,d,n,k);
|
||||
FOR(i,32) m[i] = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
sv set25519(gf r, const gf a)
|
||||
{
|
||||
int i;
|
||||
FOR(i,16) r[i]=a[i];
|
||||
}
|
||||
|
||||
sv car25519(gf o)
|
||||
{
|
||||
int i;
|
||||
i64 c;
|
||||
FOR(i,16) {
|
||||
o[i]+=(1LL<<16);
|
||||
c=o[i]>>16;
|
||||
o[(i+1)*(i<15)]+=c-1+37*(c-1)*(i==15);
|
||||
o[i]-=c<<16;
|
||||
}
|
||||
}
|
||||
|
||||
sv sel25519(gf p,gf q,int b)
|
||||
{
|
||||
i64 t,i,c=~(b-1);
|
||||
FOR(i,16) {
|
||||
t= c&(p[i]^q[i]);
|
||||
p[i]^=t;
|
||||
q[i]^=t;
|
||||
}
|
||||
}
|
||||
|
||||
sv pack25519(u8 *o,const gf n)
|
||||
{
|
||||
int i,j,b;
|
||||
gf m,t;
|
||||
FOR(i,16) t[i]=n[i];
|
||||
car25519(t);
|
||||
car25519(t);
|
||||
car25519(t);
|
||||
FOR(j,2) {
|
||||
m[0]=t[0]-0xffed;
|
||||
for(i=1;i<15;i++) {
|
||||
m[i]=t[i]-0xffff-((m[i-1]>>16)&1);
|
||||
m[i-1]&=0xffff;
|
||||
}
|
||||
m[15]=t[15]-0x7fff-((m[14]>>16)&1);
|
||||
b=(m[15]>>16)&1;
|
||||
m[14]&=0xffff;
|
||||
sel25519(t,m,1-b);
|
||||
}
|
||||
FOR(i,16) {
|
||||
o[2*i]=t[i]&0xff;
|
||||
o[2*i+1]=t[i]>>8;
|
||||
}
|
||||
}
|
||||
|
||||
static int neq25519(const gf a, const gf b)
|
||||
{
|
||||
u8 c[32],d[32];
|
||||
pack25519(c,a);
|
||||
pack25519(d,b);
|
||||
return crypto_verify_32(c,d);
|
||||
}
|
||||
|
||||
static u8 par25519(const gf a)
|
||||
{
|
||||
u8 d[32];
|
||||
pack25519(d,a);
|
||||
return d[0]&1;
|
||||
}
|
||||
|
||||
sv unpack25519(gf o, const u8 *n)
|
||||
{
|
||||
int i;
|
||||
FOR(i,16) o[i]=n[2*i]+((i64)n[2*i+1]<<8);
|
||||
o[15]&=0x7fff;
|
||||
}
|
||||
|
||||
sv A(gf o,const gf a,const gf b)
|
||||
{
|
||||
int i;
|
||||
FOR(i,16) o[i]=a[i]+b[i];
|
||||
}
|
||||
|
||||
sv Z(gf o,const gf a,const gf b)
|
||||
{
|
||||
int i;
|
||||
FOR(i,16) o[i]=a[i]-b[i];
|
||||
}
|
||||
|
||||
sv M(gf o,const gf a,const gf b)
|
||||
{
|
||||
i64 i,j,t[31];
|
||||
FOR(i,31) t[i]=0;
|
||||
FOR(i,16) FOR(j,16) t[i+j]+=a[i]*b[j];
|
||||
FOR(i,15) t[i]+=38*t[i+16];
|
||||
FOR(i,16) o[i]=t[i];
|
||||
car25519(o);
|
||||
car25519(o);
|
||||
}
|
||||
|
||||
sv S(gf o,const gf a)
|
||||
{
|
||||
M(o,a,a);
|
||||
}
|
||||
|
||||
sv inv25519(gf o,const gf i)
|
||||
{
|
||||
gf c;
|
||||
int a;
|
||||
FOR(a,16) c[a]=i[a];
|
||||
for(a=253;a>=0;a--) {
|
||||
S(c,c);
|
||||
if(a!=2&&a!=4) M(c,c,i);
|
||||
}
|
||||
FOR(a,16) o[a]=c[a];
|
||||
}
|
||||
|
||||
sv pow2523(gf o,const gf i)
|
||||
{
|
||||
gf c;
|
||||
int a;
|
||||
FOR(a,16) c[a]=i[a];
|
||||
for(a=250;a>=0;a--) {
|
||||
S(c,c);
|
||||
if(a!=1) M(c,c,i);
|
||||
}
|
||||
FOR(a,16) o[a]=c[a];
|
||||
}
|
||||
|
||||
int crypto_scalarmult(u8 *q,const u8 *n,const u8 *p)
|
||||
{
|
||||
u8 z[32];
|
||||
i64 x[80],r,i;
|
||||
gf a,b,c,d,e,f;
|
||||
FOR(i,31) z[i]=n[i];
|
||||
z[31]=(n[31]&127)|64;
|
||||
z[0]&=248;
|
||||
unpack25519(x,p);
|
||||
FOR(i,16) {
|
||||
b[i]=x[i];
|
||||
d[i]=a[i]=c[i]=0;
|
||||
}
|
||||
a[0]=d[0]=1;
|
||||
for(i=254;i>=0;--i) {
|
||||
r=(z[i>>3]>>(i&7))&1;
|
||||
sel25519(a,b,r);
|
||||
sel25519(c,d,r);
|
||||
A(e,a,c);
|
||||
Z(a,a,c);
|
||||
A(c,b,d);
|
||||
Z(b,b,d);
|
||||
S(d,e);
|
||||
S(f,a);
|
||||
M(a,c,a);
|
||||
M(c,b,e);
|
||||
A(e,a,c);
|
||||
Z(a,a,c);
|
||||
S(b,a);
|
||||
Z(c,d,f);
|
||||
M(a,c,_121665);
|
||||
A(a,a,d);
|
||||
M(c,c,a);
|
||||
M(a,d,f);
|
||||
M(d,b,x);
|
||||
S(b,e);
|
||||
sel25519(a,b,r);
|
||||
sel25519(c,d,r);
|
||||
}
|
||||
FOR(i,16) {
|
||||
x[i+16]=a[i];
|
||||
x[i+32]=c[i];
|
||||
x[i+48]=b[i];
|
||||
x[i+64]=d[i];
|
||||
}
|
||||
inv25519(x+32,x+32);
|
||||
M(x+16,x+16,x+32);
|
||||
pack25519(q,x+16);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypto_scalarmult_base(u8 *q,const u8 *n)
|
||||
{
|
||||
return crypto_scalarmult(q,n,_9);
|
||||
}
|
||||
|
||||
int crypto_box_keypair(u8 *y,u8 *x)
|
||||
{
|
||||
randombytes(x,32);
|
||||
return crypto_scalarmult_base(y,x);
|
||||
}
|
||||
|
||||
int crypto_box_beforenm(u8 *k,const u8 *y,const u8 *x)
|
||||
{
|
||||
u8 s[32];
|
||||
crypto_scalarmult(s,x,y);
|
||||
return crypto_core_hsalsa20(k,_0,s,sigma);
|
||||
}
|
||||
|
||||
int crypto_box_afternm(u8 *c,const u8 *m,u64 d,const u8 *n,const u8 *k)
|
||||
{
|
||||
return crypto_secretbox(c,m,d,n,k);
|
||||
}
|
||||
|
||||
int crypto_box_open_afternm(u8 *m,const u8 *c,u64 d,const u8 *n,const u8 *k)
|
||||
{
|
||||
return crypto_secretbox_open(m,c,d,n,k);
|
||||
}
|
||||
|
||||
int crypto_box(u8 *c,const u8 *m,u64 d,const u8 *n,const u8 *y,const u8 *x)
|
||||
{
|
||||
u8 k[32];
|
||||
crypto_box_beforenm(k,y,x);
|
||||
return crypto_box_afternm(c,m,d,n,k);
|
||||
}
|
||||
|
||||
int crypto_box_open(u8 *m,const u8 *c,u64 d,const u8 *n,const u8 *y,const u8 *x)
|
||||
{
|
||||
u8 k[32];
|
||||
crypto_box_beforenm(k,y,x);
|
||||
return crypto_box_open_afternm(m,c,d,n,k);
|
||||
}
|
||||
|
||||
static u64 R(u64 x,int c) { return (x >> c) | (x << (64 - c)); }
|
||||
static u64 Ch(u64 x,u64 y,u64 z) { return (x & y) ^ (~x & z); }
|
||||
static u64 Maj(u64 x,u64 y,u64 z) { return (x & y) ^ (x & z) ^ (y & z); }
|
||||
static u64 Sigma0(u64 x) { return R(x,28) ^ R(x,34) ^ R(x,39); }
|
||||
static u64 Sigma1(u64 x) { return R(x,14) ^ R(x,18) ^ R(x,41); }
|
||||
static u64 sigma0(u64 x) { return R(x, 1) ^ R(x, 8) ^ (x >> 7); }
|
||||
static u64 sigma1(u64 x) { return R(x,19) ^ R(x,61) ^ (x >> 6); }
|
||||
|
||||
static const u64 K[80] =
|
||||
{
|
||||
0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
|
||||
0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
|
||||
0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
|
||||
0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
|
||||
0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
|
||||
0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
|
||||
0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
|
||||
0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
|
||||
0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
|
||||
0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
|
||||
0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
|
||||
0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
|
||||
0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
|
||||
0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
|
||||
0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
|
||||
0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
|
||||
0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
|
||||
0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
|
||||
0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
|
||||
0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
|
||||
};
|
||||
|
||||
int crypto_hashblocks(u8 *x,const u8 *m,u64 n)
|
||||
{
|
||||
u64 z[8],b[8],a[8],w[16],t;
|
||||
int i,j;
|
||||
|
||||
FOR(i,8) z[i] = a[i] = dl64(x + 8 * i);
|
||||
|
||||
while (n >= 128) {
|
||||
FOR(i,16) w[i] = dl64(m + 8 * i);
|
||||
|
||||
FOR(i,80) {
|
||||
FOR(j,8) b[j] = a[j];
|
||||
t = a[7] + Sigma1(a[4]) + Ch(a[4],a[5],a[6]) + K[i] + w[i%16];
|
||||
b[7] = t + Sigma0(a[0]) + Maj(a[0],a[1],a[2]);
|
||||
b[3] += t;
|
||||
FOR(j,8) a[(j+1)%8] = b[j];
|
||||
if (i%16 == 15)
|
||||
FOR(j,16)
|
||||
w[j] += w[(j+9)%16] + sigma0(w[(j+1)%16]) + sigma1(w[(j+14)%16]);
|
||||
}
|
||||
|
||||
FOR(i,8) { a[i] += z[i]; z[i] = a[i]; }
|
||||
|
||||
m += 128;
|
||||
n -= 128;
|
||||
}
|
||||
|
||||
FOR(i,8) ts64(x+8*i,z[i]);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
static const u8 iv[64] = {
|
||||
0x6a,0x09,0xe6,0x67,0xf3,0xbc,0xc9,0x08,
|
||||
0xbb,0x67,0xae,0x85,0x84,0xca,0xa7,0x3b,
|
||||
0x3c,0x6e,0xf3,0x72,0xfe,0x94,0xf8,0x2b,
|
||||
0xa5,0x4f,0xf5,0x3a,0x5f,0x1d,0x36,0xf1,
|
||||
0x51,0x0e,0x52,0x7f,0xad,0xe6,0x82,0xd1,
|
||||
0x9b,0x05,0x68,0x8c,0x2b,0x3e,0x6c,0x1f,
|
||||
0x1f,0x83,0xd9,0xab,0xfb,0x41,0xbd,0x6b,
|
||||
0x5b,0xe0,0xcd,0x19,0x13,0x7e,0x21,0x79
|
||||
} ;
|
||||
|
||||
int crypto_hash(u8 *out,const u8 *m,u64 n)
|
||||
{
|
||||
u8 h[64],x[256];
|
||||
u64 i,b = n;
|
||||
|
||||
FOR(i,64) h[i] = iv[i];
|
||||
|
||||
crypto_hashblocks(h,m,n);
|
||||
m += n;
|
||||
n &= 127;
|
||||
m -= n;
|
||||
|
||||
FOR(i,256) x[i] = 0;
|
||||
FOR(i,n) x[i] = m[i];
|
||||
x[n] = 128;
|
||||
|
||||
n = 256-128*(n<112);
|
||||
x[n-9] = b >> 61;
|
||||
ts64(x+n-8,b<<3);
|
||||
crypto_hashblocks(h,x,n);
|
||||
|
||||
FOR(i,64) out[i] = h[i];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
sv add(gf p[4],gf q[4])
|
||||
{
|
||||
gf a,b,c,d,t,e,f,g,h;
|
||||
|
||||
Z(a, p[1], p[0]);
|
||||
Z(t, q[1], q[0]);
|
||||
M(a, a, t);
|
||||
A(b, p[0], p[1]);
|
||||
A(t, q[0], q[1]);
|
||||
M(b, b, t);
|
||||
M(c, p[3], q[3]);
|
||||
M(c, c, D2);
|
||||
M(d, p[2], q[2]);
|
||||
A(d, d, d);
|
||||
Z(e, b, a);
|
||||
Z(f, d, c);
|
||||
A(g, d, c);
|
||||
A(h, b, a);
|
||||
|
||||
M(p[0], e, f);
|
||||
M(p[1], h, g);
|
||||
M(p[2], g, f);
|
||||
M(p[3], e, h);
|
||||
}
|
||||
|
||||
sv cswap(gf p[4],gf q[4],u8 b)
|
||||
{
|
||||
int i;
|
||||
FOR(i,4)
|
||||
sel25519(p[i],q[i],b);
|
||||
}
|
||||
|
||||
sv pack(u8 *r,gf p[4])
|
||||
{
|
||||
gf tx, ty, zi;
|
||||
inv25519(zi, p[2]);
|
||||
M(tx, p[0], zi);
|
||||
M(ty, p[1], zi);
|
||||
pack25519(r, ty);
|
||||
r[31] ^= par25519(tx) << 7;
|
||||
}
|
||||
|
||||
sv scalarmult(gf p[4],gf q[4],const u8 *s)
|
||||
{
|
||||
int i;
|
||||
set25519(p[0],gf0);
|
||||
set25519(p[1],gf1);
|
||||
set25519(p[2],gf1);
|
||||
set25519(p[3],gf0);
|
||||
for (i = 255;i >= 0;--i) {
|
||||
u8 b = (s[i/8]>>(i&7))&1;
|
||||
cswap(p,q,b);
|
||||
add(q,p);
|
||||
add(p,p);
|
||||
cswap(p,q,b);
|
||||
}
|
||||
}
|
||||
|
||||
sv scalarbase(gf p[4],const u8 *s)
|
||||
{
|
||||
gf q[4];
|
||||
set25519(q[0],X);
|
||||
set25519(q[1],Y);
|
||||
set25519(q[2],gf1);
|
||||
M(q[3],X,Y);
|
||||
scalarmult(p,q,s);
|
||||
}
|
||||
|
||||
int crypto_sign_keypair(u8 *pk, u8 *sk)
|
||||
{
|
||||
u8 d[64];
|
||||
gf p[4];
|
||||
int i;
|
||||
|
||||
randombytes(sk, 32);
|
||||
crypto_hash(d, sk, 32);
|
||||
d[0] &= 248;
|
||||
d[31] &= 127;
|
||||
d[31] |= 64;
|
||||
|
||||
scalarbase(p,d);
|
||||
pack(pk,p);
|
||||
|
||||
FOR(i,32) sk[32 + i] = pk[i];
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const u64 L[32] = {0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10};
|
||||
|
||||
sv modL(u8 *r,i64 x[64])
|
||||
{
|
||||
i64 carry,i,j;
|
||||
for (i = 63;i >= 32;--i) {
|
||||
carry = 0;
|
||||
for (j = i - 32;j < i - 12;++j) {
|
||||
x[j] += carry - 16 * x[i] * L[j - (i - 32)];
|
||||
carry = (x[j] + 128) >> 8;
|
||||
x[j] -= carry << 8;
|
||||
}
|
||||
x[j] += carry;
|
||||
x[i] = 0;
|
||||
}
|
||||
carry = 0;
|
||||
FOR(j,32) {
|
||||
x[j] += carry - (x[31] >> 4) * L[j];
|
||||
carry = x[j] >> 8;
|
||||
x[j] &= 255;
|
||||
}
|
||||
FOR(j,32) x[j] -= carry * L[j];
|
||||
FOR(i,32) {
|
||||
x[i+1] += x[i] >> 8;
|
||||
r[i] = x[i] & 255;
|
||||
}
|
||||
}
|
||||
|
||||
sv reduce(u8 *r)
|
||||
{
|
||||
i64 x[64],i;
|
||||
FOR(i,64) x[i] = (u64) r[i];
|
||||
FOR(i,64) r[i] = 0;
|
||||
modL(r,x);
|
||||
}
|
||||
|
||||
int crypto_sign(u8 *sm,u64 *smlen,const u8 *m,u64 n,const u8 *sk)
|
||||
{
|
||||
u8 d[64],h[64],r[64];
|
||||
i64 i,j,x[64];
|
||||
gf p[4];
|
||||
|
||||
crypto_hash(d, sk, 32);
|
||||
d[0] &= 248;
|
||||
d[31] &= 127;
|
||||
d[31] |= 64;
|
||||
|
||||
*smlen = n+64;
|
||||
FOR(i,n) sm[64 + i] = m[i];
|
||||
FOR(i,32) sm[32 + i] = d[32 + i];
|
||||
|
||||
crypto_hash(r, sm+32, n+32);
|
||||
reduce(r);
|
||||
scalarbase(p,r);
|
||||
pack(sm,p);
|
||||
|
||||
FOR(i,32) sm[i+32] = sk[i+32];
|
||||
crypto_hash(h,sm,n + 64);
|
||||
reduce(h);
|
||||
|
||||
FOR(i,64) x[i] = 0;
|
||||
FOR(i,32) x[i] = (u64) r[i];
|
||||
FOR(i,32) FOR(j,32) x[i+j] += h[i] * (u64) d[j];
|
||||
modL(sm + 32,x);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int unpackneg(gf r[4],const u8 p[32])
|
||||
{
|
||||
gf t, chk, num, den, den2, den4, den6;
|
||||
set25519(r[2],gf1);
|
||||
unpack25519(r[1],p);
|
||||
S(num,r[1]);
|
||||
M(den,num,D);
|
||||
Z(num,num,r[2]);
|
||||
A(den,r[2],den);
|
||||
|
||||
S(den2,den);
|
||||
S(den4,den2);
|
||||
M(den6,den4,den2);
|
||||
M(t,den6,num);
|
||||
M(t,t,den);
|
||||
|
||||
pow2523(t,t);
|
||||
M(t,t,num);
|
||||
M(t,t,den);
|
||||
M(t,t,den);
|
||||
M(r[0],t,den);
|
||||
|
||||
S(chk,r[0]);
|
||||
M(chk,chk,den);
|
||||
if (neq25519(chk, num)) M(r[0],r[0],I);
|
||||
|
||||
S(chk,r[0]);
|
||||
M(chk,chk,den);
|
||||
if (neq25519(chk, num)) return -1;
|
||||
|
||||
if (par25519(r[0]) == (p[31]>>7)) Z(r[0],gf0,r[0]);
|
||||
|
||||
M(r[3],r[0],r[1]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypto_sign_open(u8 *m,u64 *mlen,const u8 *sm,u64 n,const u8 *pk)
|
||||
{
|
||||
int i;
|
||||
u8 t[32],h[64];
|
||||
gf p[4],q[4];
|
||||
|
||||
*mlen = -1;
|
||||
if (n < 64) return -1;
|
||||
|
||||
if (unpackneg(q,pk)) return -1;
|
||||
|
||||
FOR(i,n) m[i] = sm[i];
|
||||
FOR(i,32) m[i+32] = pk[i];
|
||||
crypto_hash(h,m,n);
|
||||
reduce(h);
|
||||
scalarmult(p,q,h);
|
||||
|
||||
scalarbase(q,sm + 32);
|
||||
add(p,q);
|
||||
pack(t,p);
|
||||
|
||||
n -= 64;
|
||||
if (crypto_verify_32(sm, t)) {
|
||||
FOR(i,n) m[i] = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
FOR(i,n) m[i] = sm[i + 64];
|
||||
*mlen = n;
|
||||
return 0;
|
||||
}
|
||||
272
src/tweetnacl/test/c/tweetnacl.h
Normal file
272
src/tweetnacl/test/c/tweetnacl.h
Normal file
@ -0,0 +1,272 @@
|
||||
#ifndef TWEETNACL_H
|
||||
#define TWEETNACL_H
|
||||
#define crypto_auth_PRIMITIVE "hmacsha512256"
|
||||
#define crypto_auth crypto_auth_hmacsha512256
|
||||
#define crypto_auth_verify crypto_auth_hmacsha512256_verify
|
||||
#define crypto_auth_BYTES crypto_auth_hmacsha512256_BYTES
|
||||
#define crypto_auth_KEYBYTES crypto_auth_hmacsha512256_KEYBYTES
|
||||
#define crypto_auth_IMPLEMENTATION crypto_auth_hmacsha512256_IMPLEMENTATION
|
||||
#define crypto_auth_VERSION crypto_auth_hmacsha512256_VERSION
|
||||
#define crypto_auth_hmacsha512256_tweet_BYTES 32
|
||||
#define crypto_auth_hmacsha512256_tweet_KEYBYTES 32
|
||||
extern int crypto_auth_hmacsha512256_tweet(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *);
|
||||
extern int crypto_auth_hmacsha512256_tweet_verify(const unsigned char *,const unsigned char *,unsigned long long,const unsigned char *);
|
||||
#define crypto_auth_hmacsha512256_tweet_VERSION "-"
|
||||
#define crypto_auth_hmacsha512256 crypto_auth_hmacsha512256_tweet
|
||||
#define crypto_auth_hmacsha512256_verify crypto_auth_hmacsha512256_tweet_verify
|
||||
#define crypto_auth_hmacsha512256_BYTES crypto_auth_hmacsha512256_tweet_BYTES
|
||||
#define crypto_auth_hmacsha512256_KEYBYTES crypto_auth_hmacsha512256_tweet_KEYBYTES
|
||||
#define crypto_auth_hmacsha512256_VERSION crypto_auth_hmacsha512256_tweet_VERSION
|
||||
#define crypto_auth_hmacsha512256_IMPLEMENTATION "crypto_auth/hmacsha512256/tweet"
|
||||
#define crypto_box_PRIMITIVE "curve25519xsalsa20poly1305"
|
||||
#define crypto_box crypto_box_curve25519xsalsa20poly1305
|
||||
#define crypto_box_open crypto_box_curve25519xsalsa20poly1305_open
|
||||
#define crypto_box_keypair crypto_box_curve25519xsalsa20poly1305_keypair
|
||||
#define crypto_box_beforenm crypto_box_curve25519xsalsa20poly1305_beforenm
|
||||
#define crypto_box_afternm crypto_box_curve25519xsalsa20poly1305_afternm
|
||||
#define crypto_box_open_afternm crypto_box_curve25519xsalsa20poly1305_open_afternm
|
||||
#define crypto_box_PUBLICKEYBYTES crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES
|
||||
#define crypto_box_SECRETKEYBYTES crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES
|
||||
#define crypto_box_BEFORENMBYTES crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES
|
||||
#define crypto_box_NONCEBYTES crypto_box_curve25519xsalsa20poly1305_NONCEBYTES
|
||||
#define crypto_box_ZEROBYTES crypto_box_curve25519xsalsa20poly1305_ZEROBYTES
|
||||
#define crypto_box_BOXZEROBYTES crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES
|
||||
#define crypto_box_IMPLEMENTATION crypto_box_curve25519xsalsa20poly1305_IMPLEMENTATION
|
||||
#define crypto_box_VERSION crypto_box_curve25519xsalsa20poly1305_VERSION
|
||||
#define crypto_box_curve25519xsalsa20poly1305_tweet_PUBLICKEYBYTES 32
|
||||
#define crypto_box_curve25519xsalsa20poly1305_tweet_SECRETKEYBYTES 32
|
||||
#define crypto_box_curve25519xsalsa20poly1305_tweet_BEFORENMBYTES 32
|
||||
#define crypto_box_curve25519xsalsa20poly1305_tweet_NONCEBYTES 24
|
||||
#define crypto_box_curve25519xsalsa20poly1305_tweet_ZEROBYTES 32
|
||||
#define crypto_box_curve25519xsalsa20poly1305_tweet_BOXZEROBYTES 16
|
||||
extern int crypto_box_curve25519xsalsa20poly1305_tweet(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *,const unsigned char *);
|
||||
extern int crypto_box_curve25519xsalsa20poly1305_tweet_open(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *,const unsigned char *);
|
||||
extern int crypto_box_curve25519xsalsa20poly1305_tweet_keypair(unsigned char *,unsigned char *);
|
||||
extern int crypto_box_curve25519xsalsa20poly1305_tweet_beforenm(unsigned char *,const unsigned char *,const unsigned char *);
|
||||
extern int crypto_box_curve25519xsalsa20poly1305_tweet_afternm(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *);
|
||||
extern int crypto_box_curve25519xsalsa20poly1305_tweet_open_afternm(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *);
|
||||
#define crypto_box_curve25519xsalsa20poly1305_tweet_VERSION "-"
|
||||
#define crypto_box_curve25519xsalsa20poly1305 crypto_box_curve25519xsalsa20poly1305_tweet
|
||||
#define crypto_box_curve25519xsalsa20poly1305_open crypto_box_curve25519xsalsa20poly1305_tweet_open
|
||||
#define crypto_box_curve25519xsalsa20poly1305_keypair crypto_box_curve25519xsalsa20poly1305_tweet_keypair
|
||||
#define crypto_box_curve25519xsalsa20poly1305_beforenm crypto_box_curve25519xsalsa20poly1305_tweet_beforenm
|
||||
#define crypto_box_curve25519xsalsa20poly1305_afternm crypto_box_curve25519xsalsa20poly1305_tweet_afternm
|
||||
#define crypto_box_curve25519xsalsa20poly1305_open_afternm crypto_box_curve25519xsalsa20poly1305_tweet_open_afternm
|
||||
#define crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES crypto_box_curve25519xsalsa20poly1305_tweet_PUBLICKEYBYTES
|
||||
#define crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES crypto_box_curve25519xsalsa20poly1305_tweet_SECRETKEYBYTES
|
||||
#define crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES crypto_box_curve25519xsalsa20poly1305_tweet_BEFORENMBYTES
|
||||
#define crypto_box_curve25519xsalsa20poly1305_NONCEBYTES crypto_box_curve25519xsalsa20poly1305_tweet_NONCEBYTES
|
||||
#define crypto_box_curve25519xsalsa20poly1305_ZEROBYTES crypto_box_curve25519xsalsa20poly1305_tweet_ZEROBYTES
|
||||
#define crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES crypto_box_curve25519xsalsa20poly1305_tweet_BOXZEROBYTES
|
||||
#define crypto_box_curve25519xsalsa20poly1305_VERSION crypto_box_curve25519xsalsa20poly1305_tweet_VERSION
|
||||
#define crypto_box_curve25519xsalsa20poly1305_IMPLEMENTATION "crypto_box/curve25519xsalsa20poly1305/tweet"
|
||||
#define crypto_core_PRIMITIVE "salsa20"
|
||||
#define crypto_core crypto_core_salsa20
|
||||
#define crypto_core_OUTPUTBYTES crypto_core_salsa20_OUTPUTBYTES
|
||||
#define crypto_core_INPUTBYTES crypto_core_salsa20_INPUTBYTES
|
||||
#define crypto_core_KEYBYTES crypto_core_salsa20_KEYBYTES
|
||||
#define crypto_core_CONSTBYTES crypto_core_salsa20_CONSTBYTES
|
||||
#define crypto_core_IMPLEMENTATION crypto_core_salsa20_IMPLEMENTATION
|
||||
#define crypto_core_VERSION crypto_core_salsa20_VERSION
|
||||
#define crypto_core_salsa20_tweet_OUTPUTBYTES 64
|
||||
#define crypto_core_salsa20_tweet_INPUTBYTES 16
|
||||
#define crypto_core_salsa20_tweet_KEYBYTES 32
|
||||
#define crypto_core_salsa20_tweet_CONSTBYTES 16
|
||||
extern int crypto_core_salsa20_tweet(unsigned char *,const unsigned char *,const unsigned char *,const unsigned char *);
|
||||
#define crypto_core_salsa20_tweet_VERSION "-"
|
||||
#define crypto_core_salsa20 crypto_core_salsa20_tweet
|
||||
#define crypto_core_salsa20_OUTPUTBYTES crypto_core_salsa20_tweet_OUTPUTBYTES
|
||||
#define crypto_core_salsa20_INPUTBYTES crypto_core_salsa20_tweet_INPUTBYTES
|
||||
#define crypto_core_salsa20_KEYBYTES crypto_core_salsa20_tweet_KEYBYTES
|
||||
#define crypto_core_salsa20_CONSTBYTES crypto_core_salsa20_tweet_CONSTBYTES
|
||||
#define crypto_core_salsa20_VERSION crypto_core_salsa20_tweet_VERSION
|
||||
#define crypto_core_salsa20_IMPLEMENTATION "crypto_core/salsa20/tweet"
|
||||
#define crypto_core_hsalsa20_tweet_OUTPUTBYTES 32
|
||||
#define crypto_core_hsalsa20_tweet_INPUTBYTES 16
|
||||
#define crypto_core_hsalsa20_tweet_KEYBYTES 32
|
||||
#define crypto_core_hsalsa20_tweet_CONSTBYTES 16
|
||||
extern int crypto_core_hsalsa20_tweet(unsigned char *,const unsigned char *,const unsigned char *,const unsigned char *);
|
||||
#define crypto_core_hsalsa20_tweet_VERSION "-"
|
||||
#define crypto_core_hsalsa20 crypto_core_hsalsa20_tweet
|
||||
#define crypto_core_hsalsa20_OUTPUTBYTES crypto_core_hsalsa20_tweet_OUTPUTBYTES
|
||||
#define crypto_core_hsalsa20_INPUTBYTES crypto_core_hsalsa20_tweet_INPUTBYTES
|
||||
#define crypto_core_hsalsa20_KEYBYTES crypto_core_hsalsa20_tweet_KEYBYTES
|
||||
#define crypto_core_hsalsa20_CONSTBYTES crypto_core_hsalsa20_tweet_CONSTBYTES
|
||||
#define crypto_core_hsalsa20_VERSION crypto_core_hsalsa20_tweet_VERSION
|
||||
#define crypto_core_hsalsa20_IMPLEMENTATION "crypto_core/hsalsa20/tweet"
|
||||
#define crypto_hashblocks_PRIMITIVE "sha512"
|
||||
#define crypto_hashblocks crypto_hashblocks_sha512
|
||||
#define crypto_hashblocks_STATEBYTES crypto_hashblocks_sha512_STATEBYTES
|
||||
#define crypto_hashblocks_BLOCKBYTES crypto_hashblocks_sha512_BLOCKBYTES
|
||||
#define crypto_hashblocks_IMPLEMENTATION crypto_hashblocks_sha512_IMPLEMENTATION
|
||||
#define crypto_hashblocks_VERSION crypto_hashblocks_sha512_VERSION
|
||||
#define crypto_hashblocks_sha512_tweet_STATEBYTES 64
|
||||
#define crypto_hashblocks_sha512_tweet_BLOCKBYTES 128
|
||||
extern int crypto_hashblocks_sha512_tweet(unsigned char *,const unsigned char *,unsigned long long);
|
||||
#define crypto_hashblocks_sha512_tweet_VERSION "-"
|
||||
#define crypto_hashblocks_sha512 crypto_hashblocks_sha512_tweet
|
||||
#define crypto_hashblocks_sha512_STATEBYTES crypto_hashblocks_sha512_tweet_STATEBYTES
|
||||
#define crypto_hashblocks_sha512_BLOCKBYTES crypto_hashblocks_sha512_tweet_BLOCKBYTES
|
||||
#define crypto_hashblocks_sha512_VERSION crypto_hashblocks_sha512_tweet_VERSION
|
||||
#define crypto_hashblocks_sha512_IMPLEMENTATION "crypto_hashblocks/sha512/tweet"
|
||||
#define crypto_hashblocks_sha256_tweet_STATEBYTES 32
|
||||
#define crypto_hashblocks_sha256_tweet_BLOCKBYTES 64
|
||||
extern int crypto_hashblocks_sha256_tweet(unsigned char *,const unsigned char *,unsigned long long);
|
||||
#define crypto_hashblocks_sha256_tweet_VERSION "-"
|
||||
#define crypto_hashblocks_sha256 crypto_hashblocks_sha256_tweet
|
||||
#define crypto_hashblocks_sha256_STATEBYTES crypto_hashblocks_sha256_tweet_STATEBYTES
|
||||
#define crypto_hashblocks_sha256_BLOCKBYTES crypto_hashblocks_sha256_tweet_BLOCKBYTES
|
||||
#define crypto_hashblocks_sha256_VERSION crypto_hashblocks_sha256_tweet_VERSION
|
||||
#define crypto_hashblocks_sha256_IMPLEMENTATION "crypto_hashblocks/sha256/tweet"
|
||||
#define crypto_hash_PRIMITIVE "sha512"
|
||||
#define crypto_hash crypto_hash_sha512
|
||||
#define crypto_hash_BYTES crypto_hash_sha512_BYTES
|
||||
#define crypto_hash_IMPLEMENTATION crypto_hash_sha512_IMPLEMENTATION
|
||||
#define crypto_hash_VERSION crypto_hash_sha512_VERSION
|
||||
#define crypto_hash_sha512_tweet_BYTES 64
|
||||
extern int crypto_hash_sha512_tweet(unsigned char *,const unsigned char *,unsigned long long);
|
||||
#define crypto_hash_sha512_tweet_VERSION "-"
|
||||
#define crypto_hash_sha512 crypto_hash_sha512_tweet
|
||||
#define crypto_hash_sha512_BYTES crypto_hash_sha512_tweet_BYTES
|
||||
#define crypto_hash_sha512_VERSION crypto_hash_sha512_tweet_VERSION
|
||||
#define crypto_hash_sha512_IMPLEMENTATION "crypto_hash/sha512/tweet"
|
||||
#define crypto_hash_sha256_tweet_BYTES 32
|
||||
extern int crypto_hash_sha256_tweet(unsigned char *,const unsigned char *,unsigned long long);
|
||||
#define crypto_hash_sha256_tweet_VERSION "-"
|
||||
#define crypto_hash_sha256 crypto_hash_sha256_tweet
|
||||
#define crypto_hash_sha256_BYTES crypto_hash_sha256_tweet_BYTES
|
||||
#define crypto_hash_sha256_VERSION crypto_hash_sha256_tweet_VERSION
|
||||
#define crypto_hash_sha256_IMPLEMENTATION "crypto_hash/sha256/tweet"
|
||||
#define crypto_onetimeauth_PRIMITIVE "poly1305"
|
||||
#define crypto_onetimeauth crypto_onetimeauth_poly1305
|
||||
#define crypto_onetimeauth_verify crypto_onetimeauth_poly1305_verify
|
||||
#define crypto_onetimeauth_BYTES crypto_onetimeauth_poly1305_BYTES
|
||||
#define crypto_onetimeauth_KEYBYTES crypto_onetimeauth_poly1305_KEYBYTES
|
||||
#define crypto_onetimeauth_IMPLEMENTATION crypto_onetimeauth_poly1305_IMPLEMENTATION
|
||||
#define crypto_onetimeauth_VERSION crypto_onetimeauth_poly1305_VERSION
|
||||
#define crypto_onetimeauth_poly1305_tweet_BYTES 16
|
||||
#define crypto_onetimeauth_poly1305_tweet_KEYBYTES 32
|
||||
extern int crypto_onetimeauth_poly1305_tweet(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *);
|
||||
extern int crypto_onetimeauth_poly1305_tweet_verify(const unsigned char *,const unsigned char *,unsigned long long,const unsigned char *);
|
||||
#define crypto_onetimeauth_poly1305_tweet_VERSION "-"
|
||||
#define crypto_onetimeauth_poly1305 crypto_onetimeauth_poly1305_tweet
|
||||
#define crypto_onetimeauth_poly1305_verify crypto_onetimeauth_poly1305_tweet_verify
|
||||
#define crypto_onetimeauth_poly1305_BYTES crypto_onetimeauth_poly1305_tweet_BYTES
|
||||
#define crypto_onetimeauth_poly1305_KEYBYTES crypto_onetimeauth_poly1305_tweet_KEYBYTES
|
||||
#define crypto_onetimeauth_poly1305_VERSION crypto_onetimeauth_poly1305_tweet_VERSION
|
||||
#define crypto_onetimeauth_poly1305_IMPLEMENTATION "crypto_onetimeauth/poly1305/tweet"
|
||||
#define crypto_scalarmult_PRIMITIVE "curve25519"
|
||||
#define crypto_scalarmult crypto_scalarmult_curve25519
|
||||
#define crypto_scalarmult_base crypto_scalarmult_curve25519_base
|
||||
#define crypto_scalarmult_BYTES crypto_scalarmult_curve25519_BYTES
|
||||
#define crypto_scalarmult_SCALARBYTES crypto_scalarmult_curve25519_SCALARBYTES
|
||||
#define crypto_scalarmult_IMPLEMENTATION crypto_scalarmult_curve25519_IMPLEMENTATION
|
||||
#define crypto_scalarmult_VERSION crypto_scalarmult_curve25519_VERSION
|
||||
#define crypto_scalarmult_curve25519_tweet_BYTES 32
|
||||
#define crypto_scalarmult_curve25519_tweet_SCALARBYTES 32
|
||||
extern int crypto_scalarmult_curve25519_tweet(unsigned char *,const unsigned char *,const unsigned char *);
|
||||
extern int crypto_scalarmult_curve25519_tweet_base(unsigned char *,const unsigned char *);
|
||||
#define crypto_scalarmult_curve25519_tweet_VERSION "-"
|
||||
#define crypto_scalarmult_curve25519 crypto_scalarmult_curve25519_tweet
|
||||
#define crypto_scalarmult_curve25519_base crypto_scalarmult_curve25519_tweet_base
|
||||
#define crypto_scalarmult_curve25519_BYTES crypto_scalarmult_curve25519_tweet_BYTES
|
||||
#define crypto_scalarmult_curve25519_SCALARBYTES crypto_scalarmult_curve25519_tweet_SCALARBYTES
|
||||
#define crypto_scalarmult_curve25519_VERSION crypto_scalarmult_curve25519_tweet_VERSION
|
||||
#define crypto_scalarmult_curve25519_IMPLEMENTATION "crypto_scalarmult/curve25519/tweet"
|
||||
#define crypto_secretbox_PRIMITIVE "xsalsa20poly1305"
|
||||
#define crypto_secretbox crypto_secretbox_xsalsa20poly1305
|
||||
#define crypto_secretbox_open crypto_secretbox_xsalsa20poly1305_open
|
||||
#define crypto_secretbox_KEYBYTES crypto_secretbox_xsalsa20poly1305_KEYBYTES
|
||||
#define crypto_secretbox_NONCEBYTES crypto_secretbox_xsalsa20poly1305_NONCEBYTES
|
||||
#define crypto_secretbox_ZEROBYTES crypto_secretbox_xsalsa20poly1305_ZEROBYTES
|
||||
#define crypto_secretbox_BOXZEROBYTES crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES
|
||||
#define crypto_secretbox_IMPLEMENTATION crypto_secretbox_xsalsa20poly1305_IMPLEMENTATION
|
||||
#define crypto_secretbox_VERSION crypto_secretbox_xsalsa20poly1305_VERSION
|
||||
#define crypto_secretbox_xsalsa20poly1305_tweet_KEYBYTES 32
|
||||
#define crypto_secretbox_xsalsa20poly1305_tweet_NONCEBYTES 24
|
||||
#define crypto_secretbox_xsalsa20poly1305_tweet_ZEROBYTES 32
|
||||
#define crypto_secretbox_xsalsa20poly1305_tweet_BOXZEROBYTES 16
|
||||
extern int crypto_secretbox_xsalsa20poly1305_tweet(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *);
|
||||
extern int crypto_secretbox_xsalsa20poly1305_tweet_open(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *);
|
||||
#define crypto_secretbox_xsalsa20poly1305_tweet_VERSION "-"
|
||||
#define crypto_secretbox_xsalsa20poly1305 crypto_secretbox_xsalsa20poly1305_tweet
|
||||
#define crypto_secretbox_xsalsa20poly1305_open crypto_secretbox_xsalsa20poly1305_tweet_open
|
||||
#define crypto_secretbox_xsalsa20poly1305_KEYBYTES crypto_secretbox_xsalsa20poly1305_tweet_KEYBYTES
|
||||
#define crypto_secretbox_xsalsa20poly1305_NONCEBYTES crypto_secretbox_xsalsa20poly1305_tweet_NONCEBYTES
|
||||
#define crypto_secretbox_xsalsa20poly1305_ZEROBYTES crypto_secretbox_xsalsa20poly1305_tweet_ZEROBYTES
|
||||
#define crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES crypto_secretbox_xsalsa20poly1305_tweet_BOXZEROBYTES
|
||||
#define crypto_secretbox_xsalsa20poly1305_VERSION crypto_secretbox_xsalsa20poly1305_tweet_VERSION
|
||||
#define crypto_secretbox_xsalsa20poly1305_IMPLEMENTATION "crypto_secretbox/xsalsa20poly1305/tweet"
|
||||
#define crypto_sign_PRIMITIVE "ed25519"
|
||||
#define crypto_sign crypto_sign_ed25519
|
||||
#define crypto_sign_open crypto_sign_ed25519_open
|
||||
#define crypto_sign_keypair crypto_sign_ed25519_keypair
|
||||
#define crypto_sign_BYTES crypto_sign_ed25519_BYTES
|
||||
#define crypto_sign_PUBLICKEYBYTES crypto_sign_ed25519_PUBLICKEYBYTES
|
||||
#define crypto_sign_SECRETKEYBYTES crypto_sign_ed25519_SECRETKEYBYTES
|
||||
#define crypto_sign_IMPLEMENTATION crypto_sign_ed25519_IMPLEMENTATION
|
||||
#define crypto_sign_VERSION crypto_sign_ed25519_VERSION
|
||||
#define crypto_sign_ed25519_tweet_BYTES 64
|
||||
#define crypto_sign_ed25519_tweet_PUBLICKEYBYTES 32
|
||||
#define crypto_sign_ed25519_tweet_SECRETKEYBYTES 64
|
||||
extern int crypto_sign_ed25519_tweet(unsigned char *,unsigned long long *,const unsigned char *,unsigned long long,const unsigned char *);
|
||||
extern int crypto_sign_ed25519_tweet_open(unsigned char *,unsigned long long *,const unsigned char *,unsigned long long,const unsigned char *);
|
||||
extern int crypto_sign_ed25519_tweet_keypair(unsigned char *,unsigned char *);
|
||||
#define crypto_sign_ed25519_tweet_VERSION "-"
|
||||
#define crypto_sign_ed25519 crypto_sign_ed25519_tweet
|
||||
#define crypto_sign_ed25519_open crypto_sign_ed25519_tweet_open
|
||||
#define crypto_sign_ed25519_keypair crypto_sign_ed25519_tweet_keypair
|
||||
#define crypto_sign_ed25519_BYTES crypto_sign_ed25519_tweet_BYTES
|
||||
#define crypto_sign_ed25519_PUBLICKEYBYTES crypto_sign_ed25519_tweet_PUBLICKEYBYTES
|
||||
#define crypto_sign_ed25519_SECRETKEYBYTES crypto_sign_ed25519_tweet_SECRETKEYBYTES
|
||||
#define crypto_sign_ed25519_VERSION crypto_sign_ed25519_tweet_VERSION
|
||||
#define crypto_sign_ed25519_IMPLEMENTATION "crypto_sign/ed25519/tweet"
|
||||
#define crypto_stream_PRIMITIVE "xsalsa20"
|
||||
#define crypto_stream crypto_stream_xsalsa20
|
||||
#define crypto_stream_xor crypto_stream_xsalsa20_xor
|
||||
#define crypto_stream_KEYBYTES crypto_stream_xsalsa20_KEYBYTES
|
||||
#define crypto_stream_NONCEBYTES crypto_stream_xsalsa20_NONCEBYTES
|
||||
#define crypto_stream_IMPLEMENTATION crypto_stream_xsalsa20_IMPLEMENTATION
|
||||
#define crypto_stream_VERSION crypto_stream_xsalsa20_VERSION
|
||||
#define crypto_stream_xsalsa20_tweet_KEYBYTES 32
|
||||
#define crypto_stream_xsalsa20_tweet_NONCEBYTES 24
|
||||
extern int crypto_stream_xsalsa20_tweet(unsigned char *,unsigned long long,const unsigned char *,const unsigned char *);
|
||||
extern int crypto_stream_xsalsa20_tweet_xor(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *);
|
||||
#define crypto_stream_xsalsa20_tweet_VERSION "-"
|
||||
#define crypto_stream_xsalsa20 crypto_stream_xsalsa20_tweet
|
||||
#define crypto_stream_xsalsa20_xor crypto_stream_xsalsa20_tweet_xor
|
||||
#define crypto_stream_xsalsa20_KEYBYTES crypto_stream_xsalsa20_tweet_KEYBYTES
|
||||
#define crypto_stream_xsalsa20_NONCEBYTES crypto_stream_xsalsa20_tweet_NONCEBYTES
|
||||
#define crypto_stream_xsalsa20_VERSION crypto_stream_xsalsa20_tweet_VERSION
|
||||
#define crypto_stream_xsalsa20_IMPLEMENTATION "crypto_stream/xsalsa20/tweet"
|
||||
#define crypto_stream_salsa20_tweet_KEYBYTES 32
|
||||
#define crypto_stream_salsa20_tweet_NONCEBYTES 8
|
||||
extern int crypto_stream_salsa20_tweet(unsigned char *,unsigned long long,const unsigned char *,const unsigned char *);
|
||||
extern int crypto_stream_salsa20_tweet_xor(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *);
|
||||
#define crypto_stream_salsa20_tweet_VERSION "-"
|
||||
#define crypto_stream_salsa20 crypto_stream_salsa20_tweet
|
||||
#define crypto_stream_salsa20_xor crypto_stream_salsa20_tweet_xor
|
||||
#define crypto_stream_salsa20_KEYBYTES crypto_stream_salsa20_tweet_KEYBYTES
|
||||
#define crypto_stream_salsa20_NONCEBYTES crypto_stream_salsa20_tweet_NONCEBYTES
|
||||
#define crypto_stream_salsa20_VERSION crypto_stream_salsa20_tweet_VERSION
|
||||
#define crypto_stream_salsa20_IMPLEMENTATION "crypto_stream/salsa20/tweet"
|
||||
#define crypto_verify_PRIMITIVE "16"
|
||||
#define crypto_verify crypto_verify_16
|
||||
#define crypto_verify_BYTES crypto_verify_16_BYTES
|
||||
#define crypto_verify_IMPLEMENTATION crypto_verify_16_IMPLEMENTATION
|
||||
#define crypto_verify_VERSION crypto_verify_16_VERSION
|
||||
#define crypto_verify_16_tweet_BYTES 16
|
||||
extern int crypto_verify_16_tweet(const unsigned char *,const unsigned char *);
|
||||
#define crypto_verify_16_tweet_VERSION "-"
|
||||
#define crypto_verify_16 crypto_verify_16_tweet
|
||||
#define crypto_verify_16_BYTES crypto_verify_16_tweet_BYTES
|
||||
#define crypto_verify_16_VERSION crypto_verify_16_tweet_VERSION
|
||||
#define crypto_verify_16_IMPLEMENTATION "crypto_verify/16/tweet"
|
||||
#define crypto_verify_32_tweet_BYTES 32
|
||||
extern int crypto_verify_32_tweet(const unsigned char *,const unsigned char *);
|
||||
#define crypto_verify_32_tweet_VERSION "-"
|
||||
#define crypto_verify_32 crypto_verify_32_tweet
|
||||
#define crypto_verify_32_BYTES crypto_verify_32_tweet_BYTES
|
||||
#define crypto_verify_32_VERSION crypto_verify_32_tweet_VERSION
|
||||
#define crypto_verify_32_IMPLEMENTATION "crypto_verify/32/tweet"
|
||||
#endif
|
||||
12
src/tweetnacl/test/data/README
Normal file
12
src/tweetnacl/test/data/README
Normal file
@ -0,0 +1,12 @@
|
||||
Test vectors.
|
||||
|
||||
*.random.js are randomly generated by programs from ../generate_data/.
|
||||
*.spec.js are specifically chosen or taken from somewhere.
|
||||
|
||||
There is no specific format or order of arguments in test data: test
|
||||
implementors should study the files or generator programs to learn about
|
||||
the particular the format.
|
||||
|
||||
Usage in tests:
|
||||
|
||||
var blaVectors = require('./data/bla.random.js');
|
||||
1
src/tweetnacl/test/data/base64.random.js
Normal file
1
src/tweetnacl/test/data/base64.random.js
Normal file
File diff suppressed because one or more lines are too long
1538
src/tweetnacl/test/data/box.random.js
Normal file
1538
src/tweetnacl/test/data/box.random.js
Normal file
File diff suppressed because it is too large
Load Diff
4282
src/tweetnacl/test/data/hash.random.js
Normal file
4282
src/tweetnacl/test/data/hash.random.js
Normal file
File diff suppressed because it is too large
Load Diff
34
src/tweetnacl/test/data/hash.spec.js
Normal file
34
src/tweetnacl/test/data/hash.spec.js
Normal file
@ -0,0 +1,34 @@
|
||||
// taken from https://code.google.com/p/go/source/browse/src/pkg/crypto/sha512/sha512_test.go
|
||||
module.exports = [
|
||||
[[207,131,225,53,126,239,184,189,241,84,40,80,214,109,128,7,214,32,228,5,11,87,21,220,131,244,169,33,211,108,233,206,71,208,209,60,93,133,242,176,255,131,24,210,135,126,236,47,99,185,49,189,71,65,122,129,165,56,50,122,249,39,218,62 ],[]],
|
||||
[[31,64,252,146,218,36,22,148,117,9,121,238,108,245,130,242,213,215,210,142,24,51,93,224,90,188,84,208,86,14,15,83,2,134,12,101,43,240,141,86,2,82,170,94,116,33,5,70,243,105,251,187,206,140,18,207,199,149,123,38,82,254,154,117 ],[ 97]],
|
||||
[[45,64,138,7,23,236,24,129,88,39,138,121,108,104,144,68,54,29,198,253,222,40,214,240,73,115,184,8,150,225,130,57,117,205,191,18,235,99,249,224,89,19,40,238,35,93,128,233,181,191,26,166,164,79,70,23,255,60,175,100,0,235,23,45 ],[ 97,98]],
|
||||
[[221,175,53,161,147,97,122,186,204,65,115,73,174,32,65,49,18,230,250,78,137,169,126,162,10,158,238,230,75,85,211,154,33,146,153,42,39,79,193,168,54,186,60,35,163,254,235,189,69,77,68,35,100,60,232,14,42,154,201,79,165,76,164,159 ],[ 97,98,99]],
|
||||
[[216,2,47,32,96,173,110,253,41,122,183,61,204,83,85,201,178,20,5,75,13,23,118,161,54,166,105,210,106,125,59,20,247,58,160,208,235,255,25,238,51,51,104,240,22,75,100,25,169,109,164,158,62,72,23,83,231,233,107,113,107,220,203,111 ],[ 97,98,99,100]],
|
||||
[[135,138,230,90,146,232,108,172,1,26,87,13,76,48,167,234,236,68,43,133,206,142,202,12,41,82,181,227,204,6,40,194,231,157,136,154,212,213,199,198,38,152,109,69,45,216,99,116,182,255,170,124,216,182,118,101,190,242,40,154,92,112,176,161 ],[ 97,98,99,100,101]],
|
||||
[[227,46,241,150,35,232,237,157,38,127,101,122,129,148,75,61,7,173,187,118,133,24,6,142,136,67,87,69,86,78,141,65,80,160,167,3,190,42,125,136,182,30,61,57,12,43,185,126,45,76,49,31,220,105,214,177,38,127,5,245,154,169,32,231 ],[ 97,98,99,100,101,102]],
|
||||
[[215,22,164,24,133,105,182,138,177,182,223,172,23,142,87,1,20,205,240,234,58,28,192,227,20,134,195,228,18,65,188,106,118,66,78,140,55,171,38,240,150,252,133,239,152,134,200,203,99,65,135,244,253,223,246,69,251,9,159,31,245,76,107,140 ],[ 97,98,99,100,101,102,103]],
|
||||
[[163,168,200,27,201,124,37,96,1,13,115,137,188,136,170,201,116,161,4,224,226,56,18,32,198,224,132,196,220,205,29,45,23,212,248,109,179,28,42,133,29,200,14,102,129,215,71,51,197,93,205,3,221,150,246,6,44,221,161,42,41,26,230,206 ],[ 97,98,99,100,101,102,103,104]],
|
||||
[[242,45,81,210,82,146,202,29,15,104,246,154,237,199,137,112,25,48,140,201,219,70,239,183,90,3,221,73,79,199,241,38,192,16,232,173,230,160,10,12,26,95,27,117,216,30,14,213,169,60,233,141,201,184,51,219,120,57,36,123,29,156,36,254 ],[ 97,98,99,100,101,102,103,104,105]],
|
||||
[[239,107,151,50,31,52,177,254,162,22,154,125,185,225,150,11,71,26,161,51,2,169,136,8,115,87,197,32,190,149,124,161,25,195,186,104,230,180,152,44,1,158,200,157,227,134,92,207,106,60,218,31,225,30,89,249,141,153,241,80,44,139,151,69 ],[ 97,98,99,100,101,102,103,104,105,106]],
|
||||
[[34,16,217,154,249,200,189,236,218,27,75,239,248,34,19,103,83,216,52,37,5,221,206,55,241,49,78,44,219,180,136,198,1,107,218,169,189,47,250,81,61,213,222,46,75,80,240,49,57,61,138,182,31,119,59,14,1,48,215,56,30,15,138,29 ],[ 68,105,115,99,97,114,100,32,109,101,100,105,99,105,110,101,32,109,111,114,101,32,116,104,97,110,32,116,119,111,32,121,101,97,114,115,32,111,108,100,46]],
|
||||
[[166,135,168,152,91,77,141,10,36,241,21,254,39,34,85,198,175,175,57,9,34,88,56,84,97,89,193,237,104,92,33,26,32,55,150,174,142,204,76,129,165,182,49,89,25,179,166,79,16,113,61,160,126,52,31,205,187,8,84,27,240,48,102,206 ],[ 72,101,32,119,104,111,32,104,97,115,32,97,32,115,104,97,100,121,32,112,97,115,116,32,107,110,111,119,115,32,116,104,97,116,32,110,105,99,101,32,103,117,121,115,32,102,105,110,105,115,104,32,108,97,115,116,46]],
|
||||
[[141,219,3,146,232,24,183,213,133,171,34,118,154,80,223,102,13,159,109,85,156,202,58,252,86,145,184,202,145,184,69,19,116,228,43,205,171,214,69,137,237,124,145,216,95,98,101,150,34,138,92,133,114,103,126,185,139,198,182,36,190,251,122,248 ],[ 73,32,119,111,117,108,100,110,39,116,32,109,97,114,114,121,32,104,105,109,32,119,105,116,104,32,97,32,116,101,110,32,102,111,111,116,32,112,111,108,101,46]],
|
||||
[[38,237,143,108,167,248,212,75,106,138,84,174,57,100,15,168,173,92,103,63,112,238,156,224,116,186,78,240,212,131,238,160,11,171,47,97,216,105,93,107,52,223,156,108,72,174,54,36,99,98,32,14,216,32,68,139,220,3,167,32,54,106,135,198 ],[ 70,114,101,101,33,32,70,114,101,101,33,47,65,32,116,114,105,112,47,116,111,32,77,97,114,115,47,102,111,114,32,57,48,48,47,101,109,112,116,121,32,106,97,114,115,47,66,117,114,109,97,32,83,104,97,118,101]],
|
||||
[[229,161,75,240,68,190,105,97,90,173,232,154,252,241,171,3,137,213,252,48,42,136,77,64,53,121,209,56,106,36,0,192,137,176,219,179,135,237,15,70,63,158,227,66,248,36,77,90,56,207,188,14,129,157,169,82,159,191,247,131,104,201,169,130 ],[ 84,104,101,32,100,97,121,115,32,111,102,32,116,104,101,32,100,105,103,105,116,97,108,32,119,97,116,99,104,32,97,114,101,32,110,117,109,98,101,114,101,100,46,32,32,45,84,111,109,32,83,116,111,112,112,97,114,100]],
|
||||
[[66,10,31,170,72,145,158,20,101,27,237,69,114,90,190,15,122,88,224,240,153,66,76,78,90,73,25,73,70,227,139,70,193,248,3,75,24,239,22,155,46,49,5,13,22,72,224,185,130,56,101,149,247,223,71,218,75,111,209,142,85,51,48,21 ],[ 78,101,112,97,108,32,112,114,101,109,105,101,114,32,119,111,110,39,116,32,114,101,115,105,103,110,46]],
|
||||
[[217,38,168,99,190,173,178,1,52,219,7,104,53,53,199,32,7,176,230,149,4,88,118,37,79,52,29,220,204,222,19,42,144,140,90,245,123,170,106,106,156,99,230,100,155,186,12,33,61,192,95,173,207,154,188,206,160,159,35,220,251,99,127,190 ],[ 70,111,114,32,101,118,101,114,121,32,97,99,116,105,111,110,32,116,104,101,114,101,32,105,115,32,97,110,32,101,113,117,97,108,32,97,110,100,32,111,112,112,111,115,105,116,101,32,103,111,118,101,114,110,109,101,110,116,32,112,114,111,103,114,97,109,46]],
|
||||
[[154,152,221,155,182,125,13,167,191,131,218,83,19,223,244,253,96,164,186,192,9,79,27,5,99,54,144,255,167,246,214,29,233,161,212,248,97,121,55,213,96,131,58,154,170,156,202,254,63,210,77,180,24,208,231,40,131,53,69,202,221,58,217,45 ],[ 72,105,115,32,109,111,110,101,121,32,105,115,32,116,119,105,99,101,32,116,97,105,110,116,101,100,58,32,39,116,97,105,110,116,32,121,111,117,114,115,32,97,110,100,32,39,116,97,105,110,116,32,109,105,110,101,46]],
|
||||
[[215,253,226,210,53,30,250,222,82,244,33,29,55,70,160,120,10,38,238,195,223,155,46,213,117,54,138,138,28,9,236,69,36,2,41,58,142,164,236,235,90,79,96,6,78,162,155,19,205,216,105,24,205,122,79,175,54,97,96,176,9,128,65,7 ],[ 84,104,101,114,101,32,105,115,32,110,111,32,114,101,97,115,111,110,32,102,111,114,32,97,110,121,32,105,110,100,105,118,105,100,117,97,108,32,116,111,32,104,97,118,101,32,97,32,99,111,109,112,117,116,101,114,32,105,110,32,116,104,101,105,114,32,104,111,109,101,46,32,45,75,101,110,32,79,108,115,101,110,44,32,49,57,55,55]],
|
||||
[[176,243,95,250,38,151,53,156,51,165,111,92,12,247,21,199,174,237,150,218,153,5,202,38,152,172,173,176,143,188,158,102,155,245,102,182,189,93,97,163,232,109,194,41,153,188,201,242,34,78,51,209,212,243,42,34,140,249,208,52,158,45,181,24 ],[ 73,116,39,115,32,97,32,116,105,110,121,32,99,104,97,110,103,101,32,116,111,32,116,104,101,32,99,111,100,101,32,97,110,100,32,110,111,116,32,99,111,109,112,108,101,116,101,108,121,32,100,105,115,103,117,115,116,105,110,103,46,32,45,32,66,111,98,32,77,97,110,99,104,101,107]],
|
||||
[[61,46,95,145,119,140,158,102,247,224,97,41,58,170,138,143,199,66,221,59,46,79,72,55,114,70,75,17,68,24,155,73,39,62,97,14,92,204,215,168,26,25,202,31,167,15,22,177,15,26,16,10,77,140,19,114,51,107,232,72,76,100,179,17 ],[ 115,105,122,101,58,32,32,97,46,111,117,116,58,32,32,98,97,100,32,109,97,103,105,99]],
|
||||
[[178,246,143,245,138,192,21,239,177,201,76,144,139,13,140,43,240,111,73,30,77,232,230,48,44,73,1,111,127,138,51,234,195,233,89,133,108,127,221,188,70,77,230,24,112,19,56,164,180,111,118,219,250,249,161,229,38,43,95,64,99,151,113,199 ],[ 84,104,101,32,109,97,106,111,114,32,112,114,111,98,108,101,109,32,105,115,32,119,105,116,104,32,115,101,110,100,109,97,105,108,46,32,32,45,77,97,114,107,32,72,111,114,116,111,110]],
|
||||
[[216,201,45,181,253,245,44,248,33,94,77,243,180,144,157,41,32,63,244,208,14,154,208,182,74,106,78,4,222,197,231,79,98,231,195,92,127,184,129,189,93,233,84,66,18,61,248,245,122,72,155,10,230,22,189,50,111,132,209,0,33,18,28,87 ],[ 71,105,118,101,32,109,101,32,97,32,114,111,99,107,44,32,112,97,112,101,114,32,97,110,100,32,115,99,105,115,115,111,114,115,32,97,110,100,32,73,32,119,105,108,108,32,109,111,118,101,32,116,104,101,32,119,111,114,108,100,46,32,32,67,67,70,101,115,116,111,111,110]],
|
||||
[[25,169,248,220,10,35,62,70,78,133,102,173,60,169,185,30,69,154,123,140,71,128,152,91,1,87,118,225,191,35,154,25,188,35,61,5,86,52,62,43,10,155,194,32,144,11,78,191,79,139,223,137,255,142,254,175,121,96,45,104,73,230,247,46 ],[ 73,102,32,116,104,101,32,101,110,101,109,121,32,105,115,32,119,105,116,104,105,110,32,114,97,110,103,101,44,32,116,104,101,110,32,115,111,32,97,114,101,32,121,111,117,46]],
|
||||
[[0,180,196,31,48,123,222,135,48,28,220,91,90,177,174,154,89,46,142,203,178,2,29,215,188,75,52,226,172,230,7,65,204,54,37,96,190,197,102,186,53,23,133,149,169,25,50,184,213,53,126,44,156,236,146,211,147,176,250,120,49,133,36,118 ],[ 73,116,39,115,32,119,101,108,108,32,119,101,32,99,97,110,110,111,116,32,104,101,97,114,32,116,104,101,32,115,99,114,101,97,109,115,47,84,104,97,116,32,119,101,32,99,114,101,97,116,101,32,105,110,32,111,116,104,101,114,115,39,32,100,114,101,97,109,115,46]],
|
||||
[[145,236,204,61,83,117,253,2,110,77,103,135,135,75,29,206,32,28,236,216,162,125,189,237,80,101,114,140,178,208,156,88,163,212,103,187,31,175,53,59,247,186,86,126,0,82,69,213,50,27,85,188,52,79,124,7,185,28,182,242,108,149,155,231 ],[ 89,111,117,32,114,101,109,105,110,100,32,109,101,32,111,102,32,97,32,84,86,32,115,104,111,119,44,32,98,117,116,32,116,104,97,116,39,115,32,97,108,108,32,114,105,103,104,116,58,32,73,32,119,97,116,99,104,32,105,116,32,97,110,121,119,97,121,46]],
|
||||
[[250,187,190,34,24,15,31,19,124,253,201,85,109,37,112,231,117,209,174,2,165,151,222,212,58,114,164,15,155,72,93,80,0,67,183,190,18,143,185,252,217,130,184,49,89,160,217,154,168,85,169,231,204,66,64,192,13,192,26,155,223,130,24,215 ],[ 67,32,105,115,32,97,115,32,112,111,114,116,97,98,108,101,32,97,115,32,83,116,111,110,101,104,101,100,103,101,33,33]],
|
||||
[[46,205,236,35,92,31,164,252,42,21,77,143,186,29,221,184,167,42,26,215,56,56,181,29,121,35,49,209,67,248,185,106,159,111,203,15,52,215,202,163,81,254,109,136,119,28,79,16,80,64,224,57,47,6,224,98,22,137,211,59,47,59,169,46 ],[ 69,118,101,110,32,105,102,32,73,32,99,111,117,108,100,32,98,101,32,83,104,97,107,101,115,112,101,97,114,101,44,32,73,32,116,104,105,110,107,32,73,32,115,104,111,117,108,100,32,115,116,105,108,108,32,99,104,111,111,115,101,32,116,111,32,98,101,32,70,97,114,97,100,97,121,46,32,45,32,65,46,32,72,117,120,108,101,121]],
|
||||
[[122,214,129,246,249,111,130,247,171,250,126,204,3,52,232,250,22,211,220,28,220,69,182,11,122,244,63,228,7,93,35,87,192,193,214,14,152,53,15,26,251,31,47,231,164,215,205,42,213,91,136,228,88,224,107,115,196,11,67,115,49,245,218,180 ],[ 84,104,101,32,102,117,103,97,99,105,116,121,32,111,102,32,97,32,99,111,110,115,116,105,116,117,101,110,116,32,105,110,32,97,32,109,105,120,116,117,114,101,32,111,102,32,103,97,115,101,115,32,97,116,32,97,32,103,105,118,101,110,32,116,101,109,112,101,114,97,116,117,114,101,32,105,115,32,112,114,111,112,111,114,116,105,111,110,97,108,32,116,111,32,105,116,115,32,109,111,108,101,32,102,114,97,99,116,105,111,110,46,32,32,76,101,119,105,115,45,82,97,110,100,97,108,108,32,82,117,108,101]],
|
||||
[[131,63,146,72,171,74,59,158,81,49,247,69,253,161,255,210,221,67,91,48,233,101,149,126,120,41,28,122,183,54,5,253,25,18,176,121,78,92,35,58,176,161,45,32,90,57,119,141,25,184,53,21,214,164,112,3,241,156,222,229,29,152,199,224 ],[ 72,111,119,32,99,97,110,32,121,111,117,32,119,114,105,116,101,32,97,32,98,105,103,32,115,121,115,116,101,109,32,119,105,116,104,111,117,116,32,67,43,43,63,32,32,45,80,97,117,108,32,71,108,105,99,107]],
|
||||
];
|
||||
28
src/tweetnacl/test/data/onetimeauth.spec.js
Normal file
28
src/tweetnacl/test/data/onetimeauth.spec.js
Normal file
@ -0,0 +1,28 @@
|
||||
module.exports = [
|
||||
{
|
||||
m: new Uint8Array([72,101,108,108,111,32,119,111,114,108,100,33]),
|
||||
k: new Uint8Array([116, 104, 105, 115, 32, 105, 115, 32, 51, 50, 45, 98, 121, 116, 101,
|
||||
32, 107, 101, 121, 32, 102, 111, 114, 32, 80, 111, 108, 121, 49, 51,
|
||||
48, 53]),
|
||||
out: new Uint8Array([166,247,69,0,143,129,201,22,162,13,204,116,238,242,178,240]),
|
||||
},
|
||||
{
|
||||
m: new Uint8Array(32),
|
||||
k: new Uint8Array([116, 104, 105, 115, 32, 105, 115, 32, 51, 50, 45, 98, 121, 116, 101,
|
||||
32, 107, 101, 121, 32, 102, 111, 114, 32, 80, 111, 108, 121, 49, 51,
|
||||
48, 53]),
|
||||
out: new Uint8Array([73,236,120,9,14,72,30,198,194,107,51,185,28,204,3,7])
|
||||
},
|
||||
{
|
||||
m: new Uint8Array(2007),
|
||||
k: new Uint8Array([116, 104, 105, 115, 32, 105, 115, 32, 51, 50, 45, 98, 121, 116, 101,
|
||||
32, 107, 101, 121, 32, 102, 111, 114, 32, 80, 111, 108, 121, 49, 51,
|
||||
48, 53]),
|
||||
out: new Uint8Array([218,132,188,171,2,103,108,56,205,176,21,96,66,116,194,170])
|
||||
},
|
||||
{
|
||||
m: new Uint8Array(2007),
|
||||
k: new Uint8Array(32),
|
||||
out: new Uint8Array(16)
|
||||
}
|
||||
];
|
||||
1794
src/tweetnacl/test/data/scalarmult.random.js
Normal file
1794
src/tweetnacl/test/data/scalarmult.random.js
Normal file
File diff suppressed because it is too large
Load Diff
4610
src/tweetnacl/test/data/secretbox.random.js
Normal file
4610
src/tweetnacl/test/data/secretbox.random.js
Normal file
File diff suppressed because it is too large
Load Diff
5123
src/tweetnacl/test/data/sign.spec.js
Normal file
5123
src/tweetnacl/test/data/sign.spec.js
Normal file
File diff suppressed because it is too large
Load Diff
10
src/tweetnacl/test/generate_data/README
Normal file
10
src/tweetnacl/test/generate_data/README
Normal file
@ -0,0 +1,10 @@
|
||||
Go programs to generate random test vectors for TweetNaCl.js.
|
||||
|
||||
Install dependencies:
|
||||
|
||||
$ go get code.google.com/p/go.crypto/nacl/box
|
||||
$ go get github.com/agl/ed25519
|
||||
|
||||
Generate required test vectors:
|
||||
|
||||
$ go run FILENAME.go > ../OUTPUT_FILENAME.random.js
|
||||
31
src/tweetnacl/test/generate_data/base64.go
Normal file
31
src/tweetnacl/test/generate_data/base64.go
Normal file
@ -0,0 +1,31 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var rs [128][2]interface{}
|
||||
fmt.Print("module.exports = ")
|
||||
for i := range rs {
|
||||
m := make([]byte, i)
|
||||
if _, err := io.ReadFull(rand.Reader, m[:]); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
im := make([]int, len(m))
|
||||
for i := range m {
|
||||
im[i] = int(m[i])
|
||||
}
|
||||
rs[i][0] = im
|
||||
rs[i][1] = m
|
||||
}
|
||||
out, err := json.Marshal(rs)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Print(string(out))
|
||||
fmt.Println(";")
|
||||
}
|
||||
41
src/tweetnacl/test/generate_data/box.go
Normal file
41
src/tweetnacl/test/generate_data/box.go
Normal file
@ -0,0 +1,41 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"code.google.com/p/go.crypto/nacl/box"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var rs [256][4][]byte
|
||||
for i := range rs {
|
||||
pk1, _, err := box.GenerateKey(rand.Reader)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_, sk2, err := box.GenerateKey(rand.Reader)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
var n [24]byte // zero nonce
|
||||
m := make([]byte, i)
|
||||
if _, err := io.ReadFull(rand.Reader, m[:]); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
b := box.Seal(nil, m, &n, pk1, sk2)
|
||||
rs[i][0] = pk1[:]
|
||||
rs[i][1] = sk2[:]
|
||||
rs[i][2] = m
|
||||
rs[i][3] = b
|
||||
}
|
||||
out, err := json.MarshalIndent(rs, "", "")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Print("module.exports = ");
|
||||
fmt.Print(string(out))
|
||||
fmt.Println(";")
|
||||
}
|
||||
29
src/tweetnacl/test/generate_data/hash.go
Normal file
29
src/tweetnacl/test/generate_data/hash.go
Normal file
@ -0,0 +1,29 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/sha512"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var rs [1070][2][]byte
|
||||
for i := range rs {
|
||||
m := make([]byte, i)
|
||||
if _, err := io.ReadFull(rand.Reader, m[:]); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
h := sha512.Sum512(m)
|
||||
rs[i][0] = m
|
||||
rs[i][1] = h[:]
|
||||
}
|
||||
out, err := json.MarshalIndent(rs, "", "")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Print("module.exports = ")
|
||||
fmt.Print(string(out))
|
||||
fmt.Println(";")
|
||||
}
|
||||
42
src/tweetnacl/test/generate_data/scalarmult.go
Normal file
42
src/tweetnacl/test/generate_data/scalarmult.go
Normal file
@ -0,0 +1,42 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"code.google.com/p/go.crypto/curve25519"
|
||||
"code.google.com/p/go.crypto/nacl/box"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var rs [256][5][]byte
|
||||
for i := range rs {
|
||||
pk1, sk1, err := box.GenerateKey(rand.Reader)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
pk2, sk2, err := box.GenerateKey(rand.Reader)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
var out1, out2 [32]byte
|
||||
curve25519.ScalarMult(&out1, sk1, pk2)
|
||||
curve25519.ScalarMult(&out2, sk2, pk1)
|
||||
if out1 != out2 {
|
||||
panic("differ")
|
||||
}
|
||||
rs[i][0] = pk1[:]
|
||||
rs[i][1] = sk1[:]
|
||||
rs[i][2] = pk2[:]
|
||||
rs[i][3] = sk2[:]
|
||||
rs[i][4] = out1[:]
|
||||
}
|
||||
out, err := json.MarshalIndent(rs, "", "")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Print("module.exports = ")
|
||||
fmt.Print(string(out))
|
||||
fmt.Println(";")
|
||||
}
|
||||
40
src/tweetnacl/test/generate_data/secretbox.go
Normal file
40
src/tweetnacl/test/generate_data/secretbox.go
Normal file
@ -0,0 +1,40 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"code.google.com/p/go.crypto/nacl/secretbox"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var rs [768][4][]byte
|
||||
for i := range rs {
|
||||
var k [32]byte
|
||||
var n [24]byte
|
||||
if _, err := io.ReadFull(rand.Reader, k[:]); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if _, err := io.ReadFull(rand.Reader, n[:]); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
m := make([]byte, i)
|
||||
if _, err := io.ReadFull(rand.Reader, m[:]); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
b := secretbox.Seal(nil, m, &n, &k)
|
||||
rs[i][0] = k[:]
|
||||
rs[i][1] = n[:]
|
||||
rs[i][2] = m
|
||||
rs[i][3] = b
|
||||
}
|
||||
out, err := json.MarshalIndent(rs, "", "")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Print("module.exports = ");
|
||||
fmt.Print(string(out))
|
||||
fmt.Println(";")
|
||||
}
|
||||
35
src/tweetnacl/test/generate_data/sign.go
Normal file
35
src/tweetnacl/test/generate_data/sign.go
Normal file
@ -0,0 +1,35 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/agl/ed25519"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var rs [1024][3][]byte
|
||||
for i := range rs {
|
||||
_, sk, err := ed25519.GenerateKey(rand.Reader)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
m := make([]byte, i)
|
||||
if _, err := io.ReadFull(rand.Reader, m[:]); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
s := ed25519.Sign(sk, m)
|
||||
rs[i][0] = sk[:] // already includes pk as sk[32:]
|
||||
rs[i][1] = m
|
||||
rs[i][2] = s[:]
|
||||
}
|
||||
out, err := json.MarshalIndent(rs, "", "")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Print("module.exports = ")
|
||||
fmt.Print(string(out))
|
||||
fmt.Println(";")
|
||||
}
|
||||
@ -514,6 +514,7 @@ const factory = (ApiConfig = {}, Sortify, UserObject, ProxyManager,
|
||||
if (e) { return void cb({error: e}); }
|
||||
|
||||
store.rpc = call;
|
||||
|
||||
store.onRpcReadyEvt.fire();
|
||||
|
||||
Store.getPinLimit(null, null, function (obj) {
|
||||
@ -994,7 +995,6 @@ const factory = (ApiConfig = {}, Sortify, UserObject, ProxyManager,
|
||||
nThen(function (waitFor) {
|
||||
removeOwnedPads(waitFor);
|
||||
}).nThen(function () {
|
||||
// XXX TODO DRIVE
|
||||
store.proxy.drive = store.userObject.getStructure();
|
||||
sendDriveEvent('DRIVE_CHANGE', {
|
||||
path: ['drive', 'filesData']
|
||||
@ -1237,7 +1237,7 @@ const factory = (ApiConfig = {}, Sortify, UserObject, ProxyManager,
|
||||
}
|
||||
|
||||
// Check if the pad is already stored in the specified drive (data.teamId)
|
||||
if ((!s.id && !data.teamId) || Number(s.id) === data.teamId) {
|
||||
if ((!s.id && (!data.teamId || data.teamId === -1)) || Number(s.id) === data.teamId) {
|
||||
if (!inTargetDrive) {
|
||||
inTargetDrive = res.length;
|
||||
}
|
||||
@ -1865,11 +1865,9 @@ const factory = (ApiConfig = {}, Sortify, UserObject, ProxyManager,
|
||||
postMessage(clientId, "PAD_CACHE");
|
||||
},
|
||||
onCacheReady: function () {
|
||||
console.error('PAD CACHE READY');
|
||||
postMessage(clientId, "PAD_CACHE_READY");
|
||||
},
|
||||
onReady: function (pad) {
|
||||
console.error('PAD READY');
|
||||
var padData = pad.metadata || {};
|
||||
channel.data = padData;
|
||||
if (padData && padData.validateKey && store.messenger) {
|
||||
@ -2438,7 +2436,6 @@ const factory = (ApiConfig = {}, Sortify, UserObject, ProxyManager,
|
||||
proxy.on('change', ['drive', UserObject.SHARED_FOLDERS], function (o, n, p) {
|
||||
if (p.length > 3 && p[3] === 'password') {
|
||||
var id = p[2];
|
||||
// XXX DRIVE
|
||||
var data = proxy.drive[UserObject.SHARED_FOLDERS][id];
|
||||
var href = store.manager.user.userObject.getHref ?
|
||||
store.manager.user.userObject.getHref(data) : data.href;
|
||||
@ -2781,7 +2778,6 @@ const factory = (ApiConfig = {}, Sortify, UserObject, ProxyManager,
|
||||
addSharedFolderHandler();
|
||||
userObject.migrate(waitFor());
|
||||
}).nThen(function (waitFor) {
|
||||
console.error('START LOADING SF');
|
||||
var network = store.network || store.networkPromise;
|
||||
SF.loadSharedFolders(Store, network, store,
|
||||
drive.proxy, userObject, waitFor, obj => {
|
||||
@ -2792,11 +2788,8 @@ const factory = (ApiConfig = {}, Sortify, UserObject, ProxyManager,
|
||||
postMessage(clientId, 'LOADING_DRIVE', data);
|
||||
}, true);
|
||||
}).nThen(function (waitFor) {
|
||||
console.error('SF CACHE READY');
|
||||
|
||||
loadUniversal(Team, 'team', waitFor, clientId);
|
||||
}).nThen(function (waitFor) {
|
||||
console.error('TEAM CACHE READY');
|
||||
loadUniversal(Calendar, 'calendar', waitFor);
|
||||
}).nThen(function () {
|
||||
cb();
|
||||
@ -2876,10 +2869,12 @@ const factory = (ApiConfig = {}, Sortify, UserObject, ProxyManager,
|
||||
loadSyncModules(waitFor);
|
||||
loadUniversal(Profile, 'profile', waitFor);
|
||||
loadUniversal(Calendar, 'calendar', waitFor);
|
||||
if (store.modules['team']) { store.modules['team'].onReady(waitFor); }
|
||||
loadUniversal(Support, 'support', waitFor);
|
||||
nThen(waitFor => {
|
||||
// Make teams non-blocking
|
||||
if (store.modules['team']) { store.modules['team'].onReady(waitFor); }
|
||||
});
|
||||
}).nThen(function () {
|
||||
console.error('SF & TEAM READY');
|
||||
var requestLogin = function () {
|
||||
broadcast([], "REQUEST_LOGIN");
|
||||
};
|
||||
@ -3005,7 +3000,7 @@ const factory = (ApiConfig = {}, Sortify, UserObject, ProxyManager,
|
||||
|
||||
store.driveChannel = channel;
|
||||
|
||||
// XXX don't always call onCacheReady and onReady?
|
||||
// don't always call onCacheReady and onReady?
|
||||
// it depends on what was required by the first tab
|
||||
onAccountCacheReady(returned => {
|
||||
store.returned ||= returned;
|
||||
@ -3015,7 +3010,6 @@ const factory = (ApiConfig = {}, Sortify, UserObject, ProxyManager,
|
||||
store.returned ||= returned;
|
||||
cb(returned);
|
||||
});
|
||||
// XXX move to drive
|
||||
onDisconnect(() => {
|
||||
sendDriveEvent('NETWORK_DISCONNECT');
|
||||
});
|
||||
@ -3079,7 +3073,6 @@ const factory = (ApiConfig = {}, Sortify, UserObject, ProxyManager,
|
||||
cb(store.returned);
|
||||
});
|
||||
|
||||
// XXX TODO
|
||||
onDisconnect(() => {
|
||||
});
|
||||
onReconnect(() => {
|
||||
@ -3256,7 +3249,7 @@ const factory = (ApiConfig = {}, Sortify, UserObject, ProxyManager,
|
||||
return void onNoDrive(clientId, function (obj) {
|
||||
if (obj && obj.error) {
|
||||
// handle error
|
||||
return; // XXX
|
||||
return;
|
||||
}
|
||||
// Callback now to unfreeze the loading screen
|
||||
// Pad can now start to be loaded
|
||||
@ -3279,7 +3272,7 @@ const factory = (ApiConfig = {}, Sortify, UserObject, ProxyManager,
|
||||
return void onNoDrive(clientId, function (obj) {
|
||||
if (obj && obj.error) {
|
||||
// handle error
|
||||
return; // XXX
|
||||
return;
|
||||
}
|
||||
// Callback now to unfreeze the loading screen
|
||||
// Pad can now start to be loaded
|
||||
@ -3293,22 +3286,36 @@ const factory = (ApiConfig = {}, Sortify, UserObject, ProxyManager,
|
||||
}
|
||||
|
||||
if (requires === 'team') {
|
||||
const initTeams = Util.once(ret => {
|
||||
// On cache ready (if cache enabled)
|
||||
// or on ready (if cache disabled)
|
||||
nThen(w => {
|
||||
loadUniversal(Team, 'team', w, clientId);
|
||||
}).nThen(() => {
|
||||
cb(ret);
|
||||
loadDrive(clientId, data, ret => {
|
||||
startCacheModules(clientId, ret, onInit);
|
||||
}, ret => {
|
||||
startModules(clientId, ret, onInit);
|
||||
let called = false;
|
||||
const initTeams = cache => {
|
||||
return ret => {
|
||||
if (called) { return; }
|
||||
called = true;
|
||||
// On cache ready (if cache enabled)
|
||||
// or on ready (if cache disabled)
|
||||
nThen(w => {
|
||||
if (cache) { return; }
|
||||
initAnonRpc(null, null, w());
|
||||
}).nThen(w => {
|
||||
loadUniversal(Team, 'team', w, clientId);
|
||||
}).nThen(w => {
|
||||
// Sync teams before other modules
|
||||
// when cache is empty
|
||||
if (!cache && store.modules['team']) {
|
||||
store.modules['team'].onReady(w);
|
||||
}
|
||||
}).nThen(() => {
|
||||
cb(ret);
|
||||
loadDrive(clientId, data, ret => {
|
||||
startCacheModules(clientId, ret, onInit);
|
||||
}, ret => {
|
||||
startModules(clientId, ret, onInit);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
};
|
||||
return void loadAccount(clientId, data,
|
||||
initTeams, initTeams);
|
||||
initTeams(true), initTeams(false));
|
||||
}
|
||||
|
||||
if (requires === 'drive') {
|
||||
@ -3322,7 +3329,6 @@ const factory = (ApiConfig = {}, Sortify, UserObject, ProxyManager,
|
||||
// TODO
|
||||
}
|
||||
|
||||
// XXX load drive too
|
||||
let done = ret => {
|
||||
onInit(ret);
|
||||
const redirect = Constants.prefersDriveRedirectKey;
|
||||
@ -3393,7 +3399,6 @@ const factory = (ApiConfig = {}, Sortify, UserObject, ProxyManager,
|
||||
Cache.disable();
|
||||
}
|
||||
|
||||
// XXX replace noDrive
|
||||
if (data.noDrive && !data.requires) {
|
||||
data.requires = 'pad';
|
||||
}
|
||||
@ -3401,7 +3406,7 @@ const factory = (ApiConfig = {}, Sortify, UserObject, ProxyManager,
|
||||
start(clientId, data, Util.once(obj => {
|
||||
if (obj.error === 'GET_HK') {
|
||||
return void callback({
|
||||
error: 'ERROR' // XXX
|
||||
error: 'ERROR'
|
||||
});
|
||||
}
|
||||
callback(obj);
|
||||
@ -3462,8 +3467,8 @@ if (typeof(module) !== 'undefined' && module.exports) {
|
||||
require('./components/merge-drive'),
|
||||
require('../common/cache-store'),
|
||||
require('./components/sharedfolder'),
|
||||
require('./components/account'), // XXX
|
||||
require('./components/drive'), // XXX
|
||||
require('./components/account'), // .ts
|
||||
require('./components/drive'), // .ts
|
||||
require('./modules/cursor'),
|
||||
require('./modules/support'),
|
||||
require('./modules/integration'),
|
||||
@ -3485,45 +3490,6 @@ if (typeof(module) !== 'undefined' && module.exports) {
|
||||
require('netflux-websocket'),
|
||||
require('nthen')
|
||||
);
|
||||
} else if ((typeof(define) !== 'undefined' && define !== null) && (define.amd !== null)) {
|
||||
define([
|
||||
'/api/config', // From outside
|
||||
'json.sortify',
|
||||
'/common/user-object.js', // OK
|
||||
'/common/proxy-manager.js', // OK
|
||||
'/common/migrate-user-object.js', // OK
|
||||
'/common/common-hash.js', // OK
|
||||
'/common/common-util.js', // OK
|
||||
'/common/common-constants.js', // OK
|
||||
'/common/common-feedback.js', // OK
|
||||
'/common/common-realtime.js', // OK
|
||||
'/common/outer/messaging.js', // OK
|
||||
'/common/pinpad.js', // OK
|
||||
'/common/rpc.js', // OK
|
||||
'/common/merge-drive.js', // OK
|
||||
'/common/outer/cache-store.js', // OK
|
||||
'/common/outer/sharedfolder.js', // OK
|
||||
'/common/outer/cursor.js', // OK
|
||||
'/common/outer/support.js', // OK
|
||||
'/common/outer/integration.js', // OK
|
||||
'/common/outer/onlyoffice.js', // OK
|
||||
'/common/outer/mailbox.js', // OK
|
||||
'/common/outer/profile.js', // OK
|
||||
'/common/outer/team.js', // OK
|
||||
'/common/outer/messenger.js', // OK
|
||||
'/common/outer/history.js', // OK
|
||||
'/common/outer/calendar.js', // OK
|
||||
'/common/outer/login-block.js', // OK
|
||||
'/common/outer/network-config.js', // OK
|
||||
'/customize/application_config.js', // OK
|
||||
|
||||
'/components/chainpad-crypto/crypto.js',
|
||||
'/components/chainpad/chainpad.dist.js',
|
||||
'chainpad-netflux',
|
||||
'chainpad-listmap',
|
||||
'netflux-client',
|
||||
'/components/nthen/index.js',
|
||||
], factory);
|
||||
} else {
|
||||
// unsupported initialization
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user