Merge branch 'staging' into badges

This commit is contained in:
yflory 2025-04-09 15:47:32 +02:00
commit e8fd44f1e9
178 changed files with 23999 additions and 5693 deletions

1
.gitignore vendored
View File

@ -32,6 +32,7 @@ www/common/onlyoffice/v*
/onlyoffice-conf/
/onlyoffice-dist/
www/common/worker.bundle.js
_build
# ---> Node

View File

@ -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

View File

@ -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
View 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
View 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"

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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 "*"; }

View File

@ -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;

View File

@ -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"],

View File

@ -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

View File

@ -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;

View File

@ -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,

View File

@ -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);

View File

@ -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'));

View File

@ -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);
};

View File

@ -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);
});

View File

@ -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) {

View File

@ -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,

View File

@ -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
View File

@ -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"
}
}
}

View File

@ -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",

View File

@ -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 */ )
]
}

View File

@ -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');

View File

@ -36,6 +36,7 @@ const factory = (Util, localForage) => {
disabled = true;
allowed = supported && !disabled;
};
S.isEnabled = () => allowed;
var cache = localForage.createInstance({
driver: localForage.INDEXEDDB,

View File

@ -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: []
};
};

View File

@ -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
};
};

View File

@ -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),

View File

@ -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

View File

@ -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
View File

@ -0,0 +1 @@
node_modules

View 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
View 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"
]
}

File diff suppressed because it is too large Load Diff

View File

@ -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"
}

View 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();
});

View 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);
});

View 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();
});

View 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');
});

View 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();
});

View 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();
});

View 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();
});

View 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();
});

View 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();
});

View 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();
});

View 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();
});

View 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();
});

View 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();
});

View 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();
});

View 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.

View 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>

View 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>

View 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();

View 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 = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
"'": '&#39;',
'/': '&#x2F;'
};
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
View File

@ -0,0 +1,2 @@
_bundle.js
_bundle-quick.js

View 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.

View 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>

View File

@ -0,0 +1 @@
var _ = require('tap-browser-color')();

View 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>

View 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>

View 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>

View 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>

View File

@ -0,0 +1 @@
window.nacl = require('../../' + (process.env.NACL_SRC || 'nacl.min.js'));

6
src/tweetnacl/test/c/.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
cscalarmult
cbox
csecretbox
csign
chash
*.o

View 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();
});
});
});
});

View 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);
});

View 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();
});
});
});

View 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);
});

View 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);
});

View 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);
});

View 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

View 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
View 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;
}

View 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;
}

View 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;
}

View 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;
}

View 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;
}

View 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;
}

View 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;
}

View 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

View 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');

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View 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]],
];

View 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)
}
];

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View 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

View 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(";")
}

View 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(";")
}

View 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(";")
}

View 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(";")
}

View 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(";")
}

View 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(";")
}

View File

@ -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