Compare commits

..

43 Commits

Author SHA1 Message Date
mx 61610d5838 removed broken file link + updated link to correct line for default SURB amount 2023-06-30 15:43:13 +02:00
mx e31d0b27d4 pulled in renamed example file 2023-06-30 15:38:05 +02:00
Pierre Dommerc 7a1a7c003e feat(nc-desktop): add matrix and monero to providers list (ui) (#3623) 2023-06-30 12:13:52 +02:00
Jon Häggblad 2953837f25 Add medium toggle to socks5 client (#3615)
* Add medium toggle to socks5 client

* rustfmt
2023-06-28 23:47:00 +02:00
Jon Häggblad ee98820bb4 Use different service provider directory when medium toggle enabled (#3617) 2023-06-28 23:45:45 +02:00
mx efd8ba5978 hotfix on broken releases page link 2023-06-27 16:09:59 +02:00
mx 0c7181a211 * updated libwasmvm.so linking instructions
* added note on upgrading to v0.31.1
2023-06-27 16:09:53 +02:00
Jon Häggblad f47a111640 Merge remote-tracking branch 'origin/release/v1.1.23' into develop 2023-06-27 15:52:03 +02:00
mx ae5a9ccc50 Merge pull request #3601 from nymtech/revert-3593-feature/release-1-1-22-docs
Revert "Feature/release 1 1 22 docs"
2023-06-27 09:29:14 +00:00
mx 40465665f0 Revert "Feature/release 1 1 22 docs" 2023-06-27 09:28:49 +00:00
mx 8c437ac964 Merge pull request #3593 from nymtech/feature/release-1-1-22-docs
Feature/release 1 1 22 docs
2023-06-27 09:28:33 +00:00
benedettadavico f3b17ad2f8 Revert contract version 2023-06-27 09:57:17 +02:00
benedettadavico 9121078576 Update versions and changelog for release v1.1.23 2023-06-27 09:48:35 +02:00
mx c505a00fac pulled in renamed example file 2023-06-26 17:37:01 +02:00
mx 09bad9c6b4 * updated libwasmvm.so linking instructions
* added note on upgrading to v0.31.1
2023-06-26 17:36:22 +02:00
pierre 597f5e9545 ci: fix typescript-lint.yml workflow 2023-06-26 16:21:37 +02:00
pierre 54cb7be1e1 chore: update copyright notice in comment headers 2023-06-26 16:09:24 +02:00
pierre 431c98e591 chore: update copyright notice date 2023-06-26 15:46:11 +02:00
Jon Häggblad 35f2e71202 Don't fully turn off background task when cover traffic is disabled (#3596)
* Don't fully turn off background task when cover traffic is disabled

* Leave no_cover function alone

* Add methods on config struct instead of explicitly setting options

* Add medium toggle to network-requester run command

* clippy

* rustfmt

* Unused
2023-06-26 15:36:07 +02:00
pierre 0134030341 build(nc-android): fix release build (sentry) 2023-06-26 12:08:41 +02:00
pierre 97c775bc68 build(nc-android): fix release build (sentry) 2023-06-26 11:59:59 +02:00
mx 62ba6b30ae updated link to releases page: now wallet version specific 2023-06-26 10:50:03 +02:00
mx 24354275d3 version bumps 2023-06-26 10:49:36 +02:00
mx 76335e9adc removed --wallet-address from commands 2023-06-26 10:32:28 +02:00
mx bab8eb746e version bump + included new wallet version var 2023-06-26 10:32:02 +02:00
Jon Häggblad f298f5d4fa Auto-upgrade nym-connect config files (#3589)
* nym-connect: auto-upgrade old config files

* Move upgrade functions to separate file
2023-06-26 10:09:45 +02:00
mx 85b078a3e8 Merge branches 'release/v1.1.21' and 'release/v1.1.22' of github.com:nymtech/nym into release/v1.1.22 2023-06-26 09:54:31 +02:00
Fouad 0115b02be3 Wallet - Node Tester (#3551)
* error handling + edge cases + types

* use bonded node id

* add UI and move feature to node-settings dir

* use error modal

* add type for postMessage arg

* add timeout for node test

* update storybook ci

* fix CI for typescript linting

* fix print node test results

* replace react-to-print lib with vanilla solution

* async print

* update wallet changelog
2023-06-23 14:00:28 +01:00
Jon Häggblad a4ffd135e7 Fix the medium toggle in nym-connect (#3590) 2023-06-22 16:30:25 +02:00
pierre bbce67902b ci(nc-android): disable release apk (unused) 2023-06-22 15:36:30 +02:00
pierre e6930046c4 ci(nc-android): disable release apk (unused) 2023-06-22 15:18:36 +02:00
pierre 0c9402503a Merge branch 'feature/nyms5-android-sentry' into develop 2023-06-22 14:23:33 +02:00
pierre 81e133b789 feat(nc-android): sentry integration and topbar navigation 2023-06-22 14:21:24 +02:00
Jon Häggblad 7be07c29c1 Cargo.lock 2023-06-22 10:59:59 +02:00
Jon Häggblad 31bc439f65 Cargo.lock 2023-06-22 10:59:08 +02:00
Jon Häggblad 6479480cf7 Merge remote-tracking branch 'origin/release/v1.1.23' into develop 2023-06-22 10:57:52 +02:00
Jon Häggblad 4af70ef255 nym-connect: medium speed setting (#3585)
* Lock files

* Add flag to disable cover traffic

* Add flag to disable per hop delays

* Add flag to enable mixed size packets

* Add meta flag to set medium speed

* Special case zero averge hop delay to be exactly zero

* Extract out generate_hop_delays function
2023-06-22 10:55:35 +02:00
Jędrzej Stuczyński eba58f6451 NC: load old gateway configuration if we're not registering (#3586) 2023-06-22 08:49:00 +01:00
Jon Häggblad 35206655e0 Lock files 2023-06-21 09:01:47 +02:00
Jon Häggblad e14db00fc2 nym-cli: client identity signing support (#3575)
* Add client identity key signing to nym-cli

* Only load private key

* rustfmt

* Rename to identity key since it's generic

* Rename client_key to identity_key
2023-06-20 14:48:53 +02:00
mx 4caa9390cf Merge pull request #3546 from twofaktor/patch-2
[UPDATE DOCS] socks5-client
2023-06-14 14:08:16 +00:00
⚡️2FakTor⚡️ 92e902c81e Update socks5-client.md 2023-06-12 15:54:13 +02:00
⚡️2FakTor⚡️ c47bc174bc Update socks5-client.md 2023-06-12 15:47:28 +02:00
1823 changed files with 3988 additions and 339363 deletions
@@ -19,6 +19,16 @@ jobs:
node-version: 16
- name: Setup yarn
run: npm install -g yarn
- name: Install Rust stable
uses: actions-rs/toolchain@v1
with:
toolchain: stable
- name: Install wasm-pack
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
working-directory: clients/webassembly
- name: Build WASM
run: wasm-pack build
working-directory: clients/webassembly
- name: Build dependencies
run: yarn && yarn build
- name: Build storybook
+2 -1
View File
@@ -68,8 +68,10 @@ jobs:
working-directory: nym-connect/native/android
env:
ANDROID_SDK_ROOT: ${{ env.ANDROID_HOME }}
SENTRY_AUTH_TOKEN: ${{ secrets.NYMS5_ANDROID_SENTRY_AUTH_TOKEN }}
# build for arm64 and x86_64
run: |
echo "auth.token=$SENTRY_AUTH_TOKEN" | tee -a sentry.properties
./gradlew :app:assembleArch64Debug
./gradlew :app:assembleArch64Release
@@ -107,4 +109,3 @@ jobs:
files: |
apk/nyms5-arch64-debug.apk
apk/nyms5-arch64-release.apk
+10
View File
@@ -36,6 +36,16 @@ jobs:
node-version: 16
- name: Setup yarn
run: npm install -g yarn
- name: Install Rust stable
uses: actions-rs/toolchain@v1
with:
toolchain: stable
- name: Install wasm-pack
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
working-directory: clients/webassembly
- name: Build WASM
run: wasm-pack build
working-directory: clients/webassembly
- name: Install
run: yarn
- name: Build packages
+8
View File
@@ -4,6 +4,14 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
## [Unreleased]
## [1.1.23] (2023-06-27)
- nym-cli: add client identity key signing support ([#3576])
- Don't fully turn off background task when cover traffic is disabled ([#3596])
[#3576]: https://github.com/nymtech/nym/issues/3576
[#3596]: https://github.com/nymtech/nym/pull/3596
## [v1.1.22] (2023-06-20)
- CLI tool for querying network-requesters ([#3539])
Generated
+14 -9
View File
@@ -1732,7 +1732,7 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
[[package]]
name = "explorer-api"
version = "1.1.22"
version = "1.1.23"
dependencies = [
"chrono",
"clap 4.2.7",
@@ -3322,7 +3322,7 @@ dependencies = [
[[package]]
name = "nym-api"
version = "1.1.23"
version = "1.1.24"
dependencies = [
"anyhow",
"async-trait",
@@ -3459,7 +3459,7 @@ dependencies = [
[[package]]
name = "nym-cli"
version = "1.1.22"
version = "1.1.23"
dependencies = [
"anyhow",
"base64 0.13.1",
@@ -3507,8 +3507,10 @@ dependencies = [
"nym-multisig-contract-common",
"nym-name-service-common",
"nym-network-defaults",
"nym-pemstore",
"nym-service-provider-directory-common",
"nym-sphinx",
"nym-types",
"nym-validator-client",
"nym-vesting-contract-common",
"rand 0.6.5",
@@ -3523,7 +3525,7 @@ dependencies = [
[[package]]
name = "nym-client"
version = "1.1.22"
version = "1.1.23"
dependencies = [
"clap 4.2.7",
"dirs 4.0.0",
@@ -3797,7 +3799,7 @@ dependencies = [
[[package]]
name = "nym-gateway"
version = "1.1.22"
version = "1.1.23"
dependencies = [
"anyhow",
"async-trait",
@@ -3948,7 +3950,7 @@ dependencies = [
[[package]]
name = "nym-mixnode"
version = "1.1.23"
version = "1.1.24"
dependencies = [
"anyhow",
"bs58",
@@ -4058,7 +4060,7 @@ dependencies = [
[[package]]
name = "nym-network-requester"
version = "1.1.22"
version = "1.1.23"
dependencies = [
"anyhow",
"async-file-watcher",
@@ -4104,7 +4106,7 @@ dependencies = [
[[package]]
name = "nym-network-statistics"
version = "1.1.22"
version = "1.1.23"
dependencies = [
"dirs 4.0.0",
"log",
@@ -4263,7 +4265,7 @@ dependencies = [
[[package]]
name = "nym-socks5-client"
version = "1.1.22"
version = "1.1.23"
dependencies = [
"clap 4.2.7",
"lazy_static",
@@ -4402,6 +4404,7 @@ dependencies = [
"nym-pemstore",
"nym-sphinx-addressing",
"nym-sphinx-params",
"nym-sphinx-routing",
"nym-sphinx-types",
"nym-topology",
"rand 0.7.3",
@@ -4429,6 +4432,7 @@ dependencies = [
"nym-crypto",
"nym-sphinx-addressing",
"nym-sphinx-params",
"nym-sphinx-routing",
"nym-sphinx-types",
"nym-topology",
"rand 0.7.3",
@@ -4460,6 +4464,7 @@ dependencies = [
"nym-sphinx-chunking",
"nym-sphinx-forwarding",
"nym-sphinx-params",
"nym-sphinx-routing",
"nym-sphinx-types",
"nym-topology",
"rand 0.7.3",
+1 -1
View File
@@ -102,7 +102,7 @@ default-members = [
"explorer-api",
]
exclude = ["explorer", "contracts", "clients/webassembly", "nym-wallet", "nym-connect/mobile/src-tauri", "nym-connect/desktop", "cpu-cycles", "lib-25519"]
exclude = ["explorer", "contracts", "clients/webassembly", "nym-wallet", "nym-connect/mobile/src-tauri", "nym-connect/desktop", "cpu-cycles"]
[workspace.package]
authors = ["Nym Technologies SA"]
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "nym-client"
version = "1.1.22"
version = "1.1.23"
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>"]
description = "Implementation of the Nym Client"
edition = "2021"
@@ -1,4 +1,4 @@
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
// all variable size data is always prefixed with u64 length
@@ -1,4 +1,4 @@
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
// all variable size data is always prefixed with u64 length
@@ -1,4 +1,4 @@
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::error::ErrorKind;
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "nym-socks5-client"
version = "1.1.22"
version = "1.1.23"
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
description = "A SOCKS5 localhost proxy that converts incoming messages to Sphinx and sends them to a Nym address"
edition = "2021"
+1
View File
@@ -94,6 +94,7 @@ impl From<Init> for OverrideConfig {
use_anonymous_replies: init_config.use_reply_surbs,
fastmode: init_config.fastmode,
no_cover: init_config.no_cover,
medium_toggle: false,
nyxd_urls: init_config.nyxd_urls,
enabled_credentials_mode: init_config.enabled_credentials_mode,
outfox: false,
+17 -1
View File
@@ -19,7 +19,7 @@ use nym_client_core::client::key_manager::persistence::OnDiskKeys;
use nym_client_core::config::GatewayEndpointConfig;
use nym_client_core::error::ClientCoreError;
use nym_config::OptionalSet;
use nym_sphinx::params::PacketType;
use nym_sphinx::params::{PacketSize, PacketType};
use std::error::Error;
pub mod init;
@@ -72,6 +72,7 @@ pub(crate) struct OverrideConfig {
use_anonymous_replies: Option<bool>,
fastmode: bool,
no_cover: bool,
medium_toggle: bool,
nyxd_urls: Option<Vec<url::Url>>,
enabled_credentials_mode: Option<bool>,
outfox: bool,
@@ -91,6 +92,10 @@ pub(crate) async fn execute(args: &Cli) -> Result<(), Box<dyn Error + Send + Syn
}
pub(crate) fn override_config(config: Config, args: OverrideConfig) -> Config {
let disable_cover_traffic_with_keepalive = args.medium_toggle;
let secondary_packet_size = args.medium_toggle.then_some(PacketSize::ExtendedPacket16);
let no_per_hop_delays = args.medium_toggle;
let packet_type = if args.outfox {
PacketType::Outfox
} else {
@@ -101,6 +106,17 @@ pub(crate) fn override_config(config: Config, args: OverrideConfig) -> Config {
BaseClientConfig::with_high_default_traffic_volume,
args.fastmode,
)
.with_base(
// NOTE: This interacts with disabling cover traffic fully, so we want to this to be set before
BaseClientConfig::with_disabled_cover_traffic_with_keepalive,
disable_cover_traffic_with_keepalive,
)
.with_base(
BaseClientConfig::with_secondary_packet_size,
secondary_packet_size,
)
.with_base(BaseClientConfig::with_no_per_hop_delays, no_per_hop_delays)
// NOTE: see comment above about the order of the other disble cover traffic config
.with_base(BaseClientConfig::with_disabled_cover_traffic, args.no_cover)
.with_base(BaseClientConfig::with_packet_type, packet_type)
.with_optional(Config::with_anonymous_replies, args.use_anonymous_replies)
+6
View File
@@ -60,6 +60,11 @@ pub(crate) struct Run {
#[clap(long, hide = true)]
no_cover: bool,
/// Enable medium mixnet traffic, for experiments only.
/// This includes things like disabling cover traffic, no per hop delays, etc.
#[clap(long, hide = true)]
medium_toggle: bool,
/// Set this client to work in a enabled credentials mode that would attempt to use gateway
/// with bandwidth credential requirement.
#[clap(long, hide = true)]
@@ -77,6 +82,7 @@ impl From<Run> for OverrideConfig {
use_anonymous_replies: run_config.use_anonymous_replies,
fastmode: run_config.fastmode,
no_cover: run_config.no_cover,
medium_toggle: run_config.medium_toggle,
nyxd_urls: run_config.nyxd_urls,
enabled_credentials_mode: run_config.enabled_credentials_mode,
outfox: run_config.outfox,
+17 -3
View File
@@ -2240,7 +2240,7 @@ dependencies = [
[[package]]
name = "nym-bin-common"
version = "0.5.0"
version = "0.6.0"
dependencies = [
"atty",
"clap",
@@ -2255,7 +2255,7 @@ dependencies = [
[[package]]
name = "nym-client-core"
version = "1.1.14"
version = "1.1.15"
dependencies = [
"async-trait",
"base64 0.21.2",
@@ -2300,7 +2300,7 @@ dependencies = [
[[package]]
name = "nym-client-wasm"
version = "1.1.0"
version = "1.1.1"
dependencies = [
"anyhow",
"async-trait",
@@ -2697,6 +2697,7 @@ dependencies = [
"nym-pemstore",
"nym-sphinx-addressing",
"nym-sphinx-params",
"nym-sphinx-routing",
"nym-sphinx-types",
"nym-topology",
"rand 0.7.3",
@@ -2723,6 +2724,7 @@ dependencies = [
"nym-crypto",
"nym-sphinx-addressing",
"nym-sphinx-params",
"nym-sphinx-routing",
"nym-sphinx-types",
"nym-topology",
"rand 0.7.3",
@@ -2753,6 +2755,7 @@ dependencies = [
"nym-sphinx-chunking",
"nym-sphinx-forwarding",
"nym-sphinx-params",
"nym-sphinx-routing",
"nym-sphinx-types",
"nym-topology",
"rand 0.7.3",
@@ -2884,6 +2887,7 @@ dependencies = [
"nym-service-provider-directory-common",
"nym-vesting-contract",
"nym-vesting-contract-common",
"openssl",
"prost",
"reqwest",
"serde",
@@ -2974,6 +2978,15 @@ version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
[[package]]
name = "openssl-src"
version = "111.26.0+1.1.1u"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "efc62c9f12b22b8f5208c23a7200a442b2e5999f8bdf80233852122b5a4f6f37"
dependencies = [
"cc",
]
[[package]]
name = "openssl-sys"
version = "0.9.87"
@@ -2982,6 +2995,7 @@ checksum = "8e17f59264b2809d77ae94f0e1ebabc434773f370d6ca667bd223ea10e06cc7e"
dependencies = [
"cc",
"libc",
"openssl-src",
"pkg-config",
"vcpkg",
]
+3
View File
@@ -3,3 +3,6 @@ clippy:
test:
wasm-pack test --node
wasm-build:
wasm-pack build
@@ -8,6 +8,7 @@
},
"scripts": {
"build": "webpack --config webpack.config.js",
"build:wasm": "cd ../ && make wasm-build",
"start": "webpack-dev-server --port 8001"
},
"repository": {
@@ -36,4 +37,4 @@
"dependencies": {
"@nymproject/nym-client-wasm": "file:../pkg"
}
}
}
+293 -292
View File
@@ -12,370 +12,371 @@
// See the License for the specific language governing permissions and
// limitations under the License.
importScripts('nym_client_wasm.js');
importScripts("nym_client_wasm.js");
console.log('Initializing worker');
console.log("Initializing worker");
// wasm_bindgen creates a global variable (with the exports attached) that is in scope after `importScripts`
const {
NymNodeTester,
WasmGateway,
WasmMixNode,
WasmNymTopology,
default_debug,
NymClientBuilder,
NymClient,
set_panic_hook,
Config,
GatewayEndpointConfig,
ClientStorage,
current_network_topology,
make_key,
make_key2
NymNodeTester,
WasmGateway,
WasmMixNode,
WasmNymTopology,
default_debug,
NymClientBuilder,
NymClient,
set_panic_hook,
Config,
GatewayEndpointConfig,
ClientStorage,
current_network_topology,
make_key,
make_key2,
} = wasm_bindgen;
let client = null;
let tester = null;
const preferredGateway = "336yuXAeGEgedRfqTJZsG2YV7P13QH1bHv1SjCZYarc9";
function dummyTopology() {
const l1Mixnode = new WasmMixNode(
1,
'n1fzv4jc7fanl9s0qj02ge2ezk3kts545kjtek47',
'178.79.143.65',
1789,
'4Yr4qmEHd9sgsuQ83191FR2hD88RfsbMmB4tzhhZWriz',
'8ndjk5oZ6HxUZNScLJJ7hk39XtUqGexdKgW7hSX6kpWG',
1,
'1.10.0',
);
const l2Mixnode = new WasmMixNode(
2,
'n1z93z44vf8ssvdhujjvxcj4rd5e3lz0l60wdk70',
'109.74.197.180',
1789,
'7sVjiMrPYZrDWRujku9QLxgE8noT7NTgBAqizCsu7AoK',
'GepXwRnKZDd8x2nBWAajGGBVvF3mrpVMQBkgfrGuqRCN',
2,
'1.10.0',
);
const l3Mixnode = new WasmMixNode(
3,
'n1ptg680vnmef2cd8l0s9uyc4f0hgf3x8sed6w77',
'176.58.101.80',
1789,
'FoM5Mx9Pxk1g3zEqkS3APgtBeTtTo3M8k7Yu4bV6kK1R',
'DeYjrDC2AcQRVFshiKnbUo6bRvPyZ33QGYR2DLeFJ9qD',
3,
'1.10.0',
);
const l1Mixnode = new WasmMixNode(
1,
"n1fzv4jc7fanl9s0qj02ge2ezk3kts545kjtek47",
"178.79.143.65",
1789,
"4Yr4qmEHd9sgsuQ83191FR2hD88RfsbMmB4tzhhZWriz",
"8ndjk5oZ6HxUZNScLJJ7hk39XtUqGexdKgW7hSX6kpWG",
1,
"1.10.0"
);
const l2Mixnode = new WasmMixNode(
2,
"n1z93z44vf8ssvdhujjvxcj4rd5e3lz0l60wdk70",
"109.74.197.180",
1789,
"7sVjiMrPYZrDWRujku9QLxgE8noT7NTgBAqizCsu7AoK",
"GepXwRnKZDd8x2nBWAajGGBVvF3mrpVMQBkgfrGuqRCN",
2,
"1.10.0"
);
const l3Mixnode = new WasmMixNode(
3,
"n1ptg680vnmef2cd8l0s9uyc4f0hgf3x8sed6w77",
"176.58.101.80",
1789,
"FoM5Mx9Pxk1g3zEqkS3APgtBeTtTo3M8k7Yu4bV6kK1R",
"DeYjrDC2AcQRVFshiKnbUo6bRvPyZ33QGYR2DLeFJ9qD",
3,
"1.10.0"
);
const gateway = new WasmGateway(
'n16evnn8glr0sham3matj8rg2s24m6x56ayk87ts',
'85.159.212.96',
1789,
9000,
'336yuXAeGEgedRfqTJZsG2YV7P13QH1bHv1SjCZYarc9',
'BtYjoWihiuFihGKQypmpSspbhmWDPxzqeTVSd8ciCpWL',
'1.10.1',
);
const gateway = new WasmGateway(
"n16evnn8glr0sham3matj8rg2s24m6x56ayk87ts",
"85.159.212.96",
1789,
9000,
"336yuXAeGEgedRfqTJZsG2YV7P13QH1bHv1SjCZYarc9",
"BtYjoWihiuFihGKQypmpSspbhmWDPxzqeTVSd8ciCpWL",
"1.10.1"
);
const mixnodes = new Map();
mixnodes.set(1, [l1Mixnode]);
mixnodes.set(2, [l2Mixnode]);
mixnodes.set(3, [l3Mixnode]);
const mixnodes = new Map();
mixnodes.set(1, [l1Mixnode]);
mixnodes.set(2, [l2Mixnode]);
mixnodes.set(3, [l3Mixnode]);
const gateways = [gateway];
const gateways = [gateway];
return new WasmNymTopology(mixnodes, gateways)
return new WasmNymTopology(mixnodes, gateways);
}
function printAndDisplayTestResult(result) {
result.log_details();
result.log_details();
self.postMessage({
kind: 'DisplayTesterResults',
args: {
score: result.score(),
sentPackets: result.sent_packets,
receivedPackets: result.received_packets,
receivedAcks: result.received_acks,
duplicatePackets: result.duplicate_packets,
duplicateAcks: result.duplicate_acks,
},
});
self.postMessage({
kind: "DisplayTesterResults",
args: {
score: result.score(),
sentPackets: result.sent_packets,
receivedPackets: result.received_packets,
receivedAcks: result.received_acks,
duplicatePackets: result.duplicate_packets,
duplicateAcks: result.duplicate_acks,
},
});
}
async function testWithTester() {
const preferredGateway = "336yuXAeGEgedRfqTJZsG2YV7P13QH1bHv1SjCZYarc9";
// A) construct with hardcoded topology
const topology = dummyTopology();
const nodeTester = await new NymNodeTester(topology, preferredGateway);
// A) construct with hardcoded topology
const topology = dummyTopology()
const nodeTester = await new NymNodeTester(topology, preferredGateway);
// B) first get topology directly from nym-api
// const validator = 'https://qwerty-validator-api.qa.nymte.ch/api';
// const topology = await current_network_topology(validator)
// const nodeTester = await new NymNodeTester(topology, preferredGateway);
//
// C) use nym-api in the constructor (note: it does no filtering for 'good' nodes on other layers)
// const validator = 'https://qwerty-validator-api.qa.nymte.ch/api';
// const nodeTester = await NymNodeTester.new_with_api(validator, preferredGateway)
// B) first get topology directly from nym-api
// const validator = 'https://qwerty-validator-api.qa.nymte.ch/api';
// const topology = await current_network_topology(validator)
// const nodeTester = await new NymNodeTester(topology, undefined, preferredGateway);
//
// C) use nym-api in the constructor (note: it does no filtering for 'good' nodes on other layers)
// const validator = 'https://qwerty-validator-api.qa.nymte.ch/api';
// const nodeTester = await NymNodeTester.new_with_api(validator, undefined, preferredGateway)
// B) first get topology directly from nym-api
// const validator = 'https://qwerty-validator-api.qa.nymte.ch/api';
// const topology = await current_network_topology(validator)
// const nodeTester = await new NymNodeTester(topology, undefined, preferredGateway);
//
// C) use nym-api in the constructor (note: it does no filtering for 'good' nodes on other layers)
// const validator = 'https://qwerty-validator-api.qa.nymte.ch/api';
// const nodeTester = await NymNodeTester.new_with_api(validator, undefined, preferredGateway)
// D, E, F) you also don't have to specify the gateway. if you don't, a random one (from your topology) will be used
// const topology = dummyTopology()
// const nodeTester = await new NymNodeTester(topology);
// D, E, F) you also don't have to specify the gateway. if you don't, a random one (from your topology) will be used
// const topology = dummyTopology()
// const nodeTester = await new NymNodeTester(topology);
self.onmessage = async (event) => {
if (event.data && event.data.kind) {
switch (event.data.kind) {
case "TestPacket": {
const { mixnodeIdentity } = event.data.args;
console.log("starting node test...");
self.onmessage = async event => {
if (event.data && event.data.kind) {
switch (event.data.kind) {
case 'TestPacket': {
const {mixnodeIdentity} = event.data.args;
console.log("starting node test...");
let result = await nodeTester.test_node(mixnodeIdentity);
printAndDisplayTestResult(result)
}
}
let result = await nodeTester.test_node(mixnodeIdentity);
printAndDisplayTestResult(result);
}
};
}
}
};
}
async function testerReconnection() {
const validator = 'https://qwerty-validator-api.qa.nymte.ch/api';
const nodeTester = await NymNodeTester.new_with_api(validator);
const validator = "https://qwerty-validator-api.qa.nymte.ch/api";
const nodeTester = await NymNodeTester.new_with_api(validator);
self.onmessage = async event => {
if (event.data && event.data.kind) {
switch (event.data.kind) {
case 'TestPacket': {
const {mixnodeIdentity} = event.data.args;
console.log("starting node test...");
self.onmessage = async (event) => {
if (event.data && event.data.kind) {
switch (event.data.kind) {
case "TestPacket": {
const { mixnodeIdentity } = event.data.args;
console.log("starting node test...");
let result1 = await nodeTester.test_node(mixnodeIdentity);
console.log("sleeping for 5s");
await new Promise(r => setTimeout(r, 5000));
await nodeTester.disconnect_from_gateway();
let result1 = await nodeTester.test_node(mixnodeIdentity);
console.log("sleeping for 5s");
await new Promise((r) => setTimeout(r, 5000));
await nodeTester.disconnect_from_gateway();
console.log("sleeping for 5s");
await new Promise(r => setTimeout(r, 5000));
console.log("sleeping for 5s");
await new Promise((r) => setTimeout(r, 5000));
await nodeTester.reconnect_to_gateway();
let result2 = await nodeTester.test_node(mixnodeIdentity);
await nodeTester.reconnect_to_gateway();
let result2 = await nodeTester.test_node(mixnodeIdentity);
printAndDisplayTestResult(result1)
printAndDisplayTestResult(result2)
}
}
printAndDisplayTestResult(result1);
printAndDisplayTestResult(result2);
}
};
}
}
};
}
async function testWithNymClient() {
const preferredGateway = "336yuXAeGEgedRfqTJZsG2YV7P13QH1bHv1SjCZYarc9";
const topology = dummyTopology()
const topology = dummyTopology();
let received = 0
let received = 0;
const onMessageHandler = (message) => {
received += 1;
self.postMessage({
kind: 'ReceiveMessage',
args: {
message,
senderTag: undefined,
isTestPacket: true,
},
});
// it's really up to the user to create proper callback here...
console.log(`received ${received} packets so far`)
};
console.log('Instantiating WASM client...');
let clientBuilder = NymClientBuilder.new_tester(topology, onMessageHandler, preferredGateway)
console.log('Web worker creating WASM client...');
let local_client = await clientBuilder.start_client();
console.log('WASM client running!');
const selfAddress = local_client.self_address();
// set the global (I guess we don't have to anymore?)
client = local_client;
console.log(`Client address is ${selfAddress}`);
const onMessageHandler = (message) => {
received += 1;
self.postMessage({
kind: 'Ready',
args: {
selfAddress,
},
kind: "ReceiveMessage",
args: {
message,
senderTag: undefined,
isTestPacket: true,
},
});
// Set callback to handle messages passed to the worker.
self.onmessage = async event => {
console.log(event)
if (event.data && event.data.kind) {
switch (event.data.kind) {
case 'SendMessage': {
const {message, recipient} = event.data.args;
let uint8Array = new TextEncoder().encode(message);
await client.send_regular_message(uint8Array, recipient);
break;
}
case 'TestPacket': {
const {mixnodeIdentity} = event.data.args;
const req = await client.try_construct_test_packet_request(mixnodeIdentity);
await client.change_hardcoded_topology(req.injectable_topology());
await client.try_send_test_packets(req);
break;
}
}
// it's really up to the user to create proper callback here...
console.log(`received ${received} packets so far`);
};
console.log("Instantiating WASM client...");
let clientBuilder = NymClientBuilder.new_tester(
topology,
onMessageHandler,
preferredGateway
);
console.log("Web worker creating WASM client...");
let local_client = await clientBuilder.start_client();
console.log("WASM client running!");
const selfAddress = local_client.self_address();
// set the global (I guess we don't have to anymore?)
client = local_client;
console.log(`Client address is ${selfAddress}`);
self.postMessage({
kind: "Ready",
args: {
selfAddress,
},
});
// Set callback to handle messages passed to the worker.
self.onmessage = async (event) => {
console.log(event);
if (event.data && event.data.kind) {
switch (event.data.kind) {
case "SendMessage": {
const { message, recipient } = event.data.args;
let uint8Array = new TextEncoder().encode(message);
await client.send_regular_message(uint8Array, recipient);
break;
}
};
case "TestPacket": {
const { mixnodeIdentity } = event.data.args;
const req = await client.try_construct_test_packet_request(
mixnodeIdentity
);
await client.change_hardcoded_topology(req.injectable_topology());
await client.try_send_test_packets(req);
break;
}
}
}
};
}
async function normalNymClientUsage() {
self.postMessage({kind: 'DisableMagicTestButton'});
self.postMessage({ kind: "DisableMagicTestButton" });
// only really useful if you want to adjust some settings like traffic rate
// (if not needed you can just pass a null)
const debug = default_debug();
// only really useful if you want to adjust some settings like traffic rate
// (if not needed you can just pass a null)
const debug = default_debug();
debug.disable_main_poisson_packet_distribution = true;
debug.disable_loop_cover_traffic_stream = true;
debug.use_extended_packet_size = false;
// debug.average_packet_delay_ms = BigInt(10);
// debug.average_ack_delay_ms = BigInt(10);
// debug.ack_wait_addition_ms = BigInt(3000);
// debug.ack_wait_multiplier = 10;
debug.disable_main_poisson_packet_distribution = true;
debug.disable_loop_cover_traffic_stream = true;
debug.use_extended_packet_size = false;
// debug.average_packet_delay_ms = BigInt(10);
// debug.average_ack_delay_ms = BigInt(10);
// debug.ack_wait_addition_ms = BigInt(3000);
// debug.ack_wait_multiplier = 10;
debug.topology_refresh_rate_ms = BigInt(60000)
debug.topology_refresh_rate_ms = BigInt(60000);
const preferredGateway = "336yuXAeGEgedRfqTJZsG2YV7P13QH1bHv1SjCZYarc9";
const validator = 'https://qwerty-validator-api.qa.nymte.ch/api';
const preferredGateway = "336yuXAeGEgedRfqTJZsG2YV7P13QH1bHv1SjCZYarc9";
const validator = "https://qwerty-validator-api.qa.nymte.ch/api";
const config = new Config('my-awesome-wasm-client', validator, debug);
const config = new Config("my-awesome-wasm-client", validator, debug);
const onMessageHandler = (message) => {
console.log(message);
self.postMessage({
kind: 'ReceiveMessage',
args: {
message,
},
});
};
console.log('Instantiating WASM client...');
let localClient = await new NymClient(config, onMessageHandler)
console.log('WASM client running!');
const selfAddress = localClient.self_address();
// set the global (I guess we don't have to anymore?)
client = localClient;
console.log(`Client address is ${selfAddress}`);
const onMessageHandler = (message) => {
console.log(message);
self.postMessage({
kind: 'Ready',
args: {
selfAddress,
},
kind: "ReceiveMessage",
args: {
message,
},
});
};
// Set callback to handle messages passed to the worker.
self.onmessage = async event => {
console.log(event)
if (event.data && event.data.kind) {
switch (event.data.kind) {
case 'SendMessage': {
const {message, recipient} = event.data.args;
let uint8Array = new TextEncoder().encode(message);
await client.send_regular_message(uint8Array, recipient);
break;
}
}
console.log("Instantiating WASM client...");
let localClient = await new NymClient(config, onMessageHandler);
console.log("WASM client running!");
const selfAddress = localClient.self_address();
// set the global (I guess we don't have to anymore?)
client = localClient;
console.log(`Client address is ${selfAddress}`);
self.postMessage({
kind: "Ready",
args: {
selfAddress,
},
});
// Set callback to handle messages passed to the worker.
self.onmessage = async (event) => {
console.log(event);
if (event.data && event.data.kind) {
switch (event.data.kind) {
case "SendMessage": {
const { message, recipient } = event.data.args;
let uint8Array = new TextEncoder().encode(message);
await client.send_regular_message(uint8Array, recipient);
break;
}
};
}
}
};
}
async function messWithStorage() {
self.onmessage = async event => {
if (event.data && event.data.kind) {
switch (event.data.kind) {
case 'TestPacket': {
const { mixnodeIdentity } = event.data.args;
console.log("button clicked...", mixnodeIdentity);
self.onmessage = async (event) => {
if (event.data && event.data.kind) {
switch (event.data.kind) {
case "TestPacket": {
const { mixnodeIdentity } = event.data.args;
console.log("button clicked...", mixnodeIdentity);
let id1 = "one";
let id2 = "two";
let id1 = "one";
let id2 = "two";
console.log("making store1 NO-ENC");
let _storage1 = await ClientStorage.new_unencrypted(id1);
console.log("making store1 NO-ENC");
let _storage1 = await ClientStorage.new_unencrypted(id1);
console.log("making store2 ENC")
let _storage2 = await new ClientStorage(id2, "my-secret-password");
//
//
//
// console.log("attempting to use store1 WITH PASSWORD")
// let _storage1_alt = await new ClientStorage(id1, "password");
//
//
//
// console.log("attempting to use store2 WITHOUT PASSWORD")
// let _storage2_alt = await ClientStorage.new_unencrypted(id2);
//
//
//
// console.log("attempting to use store2 with WRONG PASSWORD")
// let _storage2_bad = await new ClientStorage(id2, "bad-password")
console.log("making store2 ENC");
let _storage2 = await new ClientStorage(id2, "my-secret-password");
//
//
//
// console.log("attempting to use store1 WITH PASSWORD")
// let _storage1_alt = await new ClientStorage(id1, "password");
//
//
//
// console.log("attempting to use store2 WITHOUT PASSWORD")
// let _storage2_alt = await ClientStorage.new_unencrypted(id2);
//
//
//
// console.log("attempting to use store2 with WRONG PASSWORD")
// let _storage2_bad = await new ClientStorage(id2, "bad-password")
//
// console.log("read1: ", await storage1.read());
// console.log("read2: ", await storage2.read());
//
// console.log("store1: ", await storage1.store("FOOMP"));
//
// console.log("read1: ", await storage1.read());
// console.log("read2: ", await storage2.read());
}
}
//
// console.log("read1: ", await storage1.read());
// console.log("read2: ", await storage2.read());
//
// console.log("store1: ", await storage1.store("FOOMP"));
//
// console.log("read1: ", await storage1.read());
// console.log("read2: ", await storage2.read());
}
};
}
}
};
}
async function main() {
// load WASM package
await wasm_bindgen('nym_client_wasm_bg.wasm');
console.log('Loaded WASM');
// load WASM package
await wasm_bindgen("nym_client_wasm_bg.wasm");
console.log("Loaded WASM");
// sets up better stack traces in case of in-rust panics
set_panic_hook();
// sets up better stack traces in case of in-rust panics
set_panic_hook();
// show reconnection capabilities
// await testerReconnection()
// show reconnection capabilities
// await testerReconnection()
// run test on simplified and dedicated tester:
await testWithTester()
// run test on simplified and dedicated tester:
await testWithTester();
// hook-up the whole client for testing
// await testWithNymClient()
// 'Normal' client setup (to send 'normal' messages)
// await normalNymClientUsage()
// 'Normal' client setup (to send 'normal' messages)
// await normalNymClientUsage()
}
// Let's get started!
main();
main();
@@ -1,4 +1,4 @@
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::client::inbound_messages::{InputMessage, InputMessageReceiver};
@@ -1,4 +1,4 @@
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use super::{
+36 -4
View File
@@ -137,14 +137,46 @@ impl Config {
self
}
pub fn set_no_cover_traffic(&mut self) {
self.debug.cover_traffic.disable_loop_cover_traffic_stream = true;
self.debug.traffic.disable_main_poisson_packet_distribution = true;
}
pub fn with_disabled_cover_traffic_with_keepalive(mut self, disabled: bool) -> Self {
if disabled {
self.set_no_cover_traffic_with_keepalive()
}
self
}
pub fn set_no_cover_traffic_with_keepalive(&mut self) {
self.debug.traffic.disable_main_poisson_packet_distribution = true;
self.debug.cover_traffic.loop_cover_traffic_average_delay = Duration::from_secs(5);
}
pub fn with_disabled_topology_refresh(mut self, disable_topology_refresh: bool) -> Self {
self.debug.topology.disable_refreshing = disable_topology_refresh;
self
}
pub fn set_no_cover_traffic(&mut self) {
self.debug.cover_traffic.disable_loop_cover_traffic_stream = true;
self.debug.traffic.disable_main_poisson_packet_distribution = true;
pub fn with_no_per_hop_delays(mut self, no_per_hop_delays: bool) -> Self {
if no_per_hop_delays {
self.set_no_per_hop_delays()
}
self
}
pub fn set_no_per_hop_delays(&mut self) {
self.debug.traffic.average_packet_delay = Duration::ZERO;
self.debug.acknowledgements.average_ack_delay = Duration::ZERO;
}
pub fn with_secondary_packet_size(mut self, secondary_packet_size: Option<PacketSize>) -> Self {
self.set_secondary_packet_size(secondary_packet_size);
self
}
pub fn set_secondary_packet_size(&mut self, secondary_packet_size: Option<PacketSize>) {
self.debug.traffic.secondary_packet_size = secondary_packet_size;
}
pub fn set_custom_version(&mut self, version: &str) {
@@ -282,7 +314,7 @@ impl Client {
}
#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)]
#[serde(default)]
#[serde(default, deny_unknown_fields)]
pub struct Traffic {
/// The parameter of Poisson distribution determining how long, on average,
/// sent packet is going to be delayed at any given mix node.
@@ -1,4 +1,4 @@
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::error::GatewayClientError;
@@ -1,4 +1,4 @@
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::{nym_api, ValidatorClientError};
@@ -1,4 +1,4 @@
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::nym_api::error::NymAPIError;
@@ -1,4 +1,4 @@
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
// TODO: There's a significant argument to pull those out of the package and make a PR on https://github.com/cosmos/cosmos-rust/
@@ -1,4 +1,4 @@
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
// TODO: expose query-related capabilities to wasm client...
+3
View File
@@ -41,3 +41,6 @@ nym-multisig-contract-common = { path = "../cosmwasm-smart-contracts/multisig-co
nym-service-provider-directory-common = { path = "../cosmwasm-smart-contracts/service-provider-directory" }
nym-name-service-common = { path = "../cosmwasm-smart-contracts/name-service" }
nym-sphinx = { path = "../../common/nymsphinx" }
nym-pemstore = { path = "../../common/pemstore", version = "0.3.0" }
nym-types = { path = "../../common/types" }
@@ -0,0 +1,68 @@
use clap::{Args, Parser, Subcommand};
use nym_bin_common::output_format::OutputFormat;
use nym_crypto::asymmetric::identity;
use nym_types::helpers::ConsoleSigningOutput;
use nym_validator_client::nyxd::error::NyxdError;
use std::path::PathBuf;
#[derive(Debug, Args)]
#[clap(args_conflicts_with_subcommands = true, subcommand_required = true)]
pub struct MixnetOperatorsIdentityKey {
#[clap(subcommand)]
pub command: MixnetOperatorsIdentityKeyCommands,
}
#[derive(Debug, Subcommand)]
pub enum MixnetOperatorsIdentityKeyCommands {
/// Register a name alias for a nym address
Sign(SignArgs),
}
#[derive(Debug, Parser)]
pub struct SignArgs {
/// Path to private identity key (example: private_identity_key.pem)
#[clap(long)]
private_key: PathBuf,
/// Base58 encoded message to sign
#[clap(long)]
base58_msg: String,
#[clap(short, long, default_value_t = OutputFormat::default())]
output: OutputFormat,
}
pub async fn sign(args: SignArgs) -> Result<(), NyxdError> {
eprintln!(">>> loading: {}", args.private_key.display());
let private_identity_key: identity::PrivateKey =
nym_pemstore::load_key(args.private_key).expect("failed to load key");
print_signed_msg(&private_identity_key, &args.base58_msg, args.output);
Ok(())
}
fn print_signed_msg(private_key: &identity::PrivateKey, raw_msg: &str, output: OutputFormat) {
let trimmed = raw_msg.trim();
eprintln!(">>> attempting to sign: {trimmed}");
let Ok(decoded) = bs58::decode(trimmed).into_vec() else {
println!("failed to base58 decode the message, did you copy it correctly?");
return;
};
eprintln!(">>> decoding the message...");
// we don't really care about what particular information is embedded inside of it,
// we just want to know if user correctly copied the string, i.e. whether it's a valid bs58 encoded json
if serde_json::from_slice::<serde_json::Value>(&decoded).is_err() {
println!("failed to parse the message after decoding, did you copy it correctly?");
return;
};
// if this is a valid json, it MUST be a valid string
let decoded_string = String::from_utf8(decoded.clone()).unwrap();
let signature = private_key.sign(&decoded).to_base58_string();
let sign_output = ConsoleSigningOutput::new(decoded_string, signature);
println!("{}", output.format(&sign_output));
}
@@ -4,6 +4,7 @@
use clap::{Args, Subcommand};
pub mod gateway;
pub mod identity_key;
pub mod mixnode;
pub mod name;
pub mod service;
@@ -26,4 +27,6 @@ pub enum MixnetOperatorsCommands {
ServiceProvider(service::MixnetOperatorsService),
/// Manage your registered name
Name(name::MixnetOperatorsName),
/// Sign messages using your private identity key
IdentityKey(identity_key::MixnetOperatorsIdentityKey),
}
@@ -1,4 +1,4 @@
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
// due to code generated by JsonSchema
@@ -1,4 +1,4 @@
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
// due to code generated by JsonSchema
@@ -1,4 +1,4 @@
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
// due to code generated by JsonSchema
@@ -88,7 +88,7 @@ impl MixNodeDetails {
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)]
pub struct MixNodeRewarding {
/// Information provided by the operator that influence the cost function.
/// Information provided by the operator that influence the cost function.
pub cost_params: MixNodeCostParams,
/// Total pledge and compounded reward earned by the node operator.
@@ -1,4 +1,4 @@
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::delegation::OwnerProxySubKey;
@@ -1,4 +1,4 @@
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::error::MixnetContractError;
+3 -2
View File
@@ -15,11 +15,12 @@ thiserror = { workspace = true }
zeroize = { workspace = true }
nym-crypto = { path = "../../crypto", features = ["symmetric", "rand"] }
nym-pemstore = { path = "../../pemstore" }
nym-sphinx-addressing = { path = "../addressing" }
nym-sphinx-params = { path = "../params" }
nym-sphinx-routing = { path = "../routing" }
nym-sphinx-types = { path = "../types" }
nym-pemstore = { path = "../../pemstore" }
nym-topology = { path = "../../topology" }
[features]
serde = ["serde_crate", "generic-array"]
serde = ["serde_crate", "generic-array"]
@@ -9,7 +9,7 @@ use nym_sphinx_addressing::nodes::{
};
use nym_sphinx_params::packet_sizes::PacketSize;
use nym_sphinx_params::{PacketType, DEFAULT_NUM_MIX_HOPS};
use nym_sphinx_types::delays::{self, Delay};
use nym_sphinx_types::delays::Delay;
use nym_sphinx_types::{NymPacket, NymPacketError, MIN_PACKET_SIZE};
use nym_topology::{NymTopology, NymTopologyError};
use rand::{CryptoRng, RngCore};
@@ -51,7 +51,7 @@ impl SurbAck {
{
let route =
topology.random_route_to_gateway(rng, DEFAULT_NUM_MIX_HOPS, recipient.gateway())?;
let delays = delays::generate_from_average_duration(route.len(), average_delay);
let delays = nym_sphinx_routing::generate_hop_delays(average_delay, route.len());
let destination = recipient.as_sphinx_destination();
let surb_ack_payload = prepare_identifier(rng, ack_key, marshaled_fragment_id);
@@ -16,6 +16,7 @@ thiserror = "1"
nym-crypto = { path = "../../crypto", features = ["symmetric", "rand"] }
nym-sphinx-addressing = { path = "../addressing" }
nym-sphinx-params = { path = "../params" }
nym-sphinx-routing = { path = "../routing" }
nym-sphinx-types = { path = "../types" }
nym-topology = { path = "../../topology" }
@@ -1,4 +1,4 @@
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::encryption_key::{SurbEncryptionKey, SurbEncryptionKeyError, SurbEncryptionKeySize};
@@ -7,7 +7,7 @@ use nym_sphinx_addressing::clients::Recipient;
use nym_sphinx_addressing::nodes::{NymNodeRoutingAddress, MAX_NODE_ADDRESS_UNPADDED_LEN};
use nym_sphinx_params::packet_sizes::PacketSize;
use nym_sphinx_params::{PacketType, ReplySurbKeyDigestAlgorithm, DEFAULT_NUM_MIX_HOPS};
use nym_sphinx_types::{delays, NymPacket, SURBMaterial, SphinxError, SURB};
use nym_sphinx_types::{NymPacket, SURBMaterial, SphinxError, SURB};
use nym_topology::{NymTopology, NymTopologyError};
use rand::{CryptoRng, RngCore};
use serde::de::{Error as SerdeError, Visitor};
@@ -96,7 +96,7 @@ impl ReplySurb {
{
let route =
topology.random_route_to_gateway(rng, DEFAULT_NUM_MIX_HOPS, recipient.gateway())?;
let delays = delays::generate_from_average_duration(route.len(), average_delay);
let delays = nym_sphinx_routing::generate_hop_delays(average_delay, route.len());
let destination = recipient.as_sphinx_destination();
let surb_material = SURBMaterial::new(route, delays, destination);
+1 -1
View File
@@ -1,4 +1,4 @@
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::ChunkingError;
+2 -1
View File
@@ -15,7 +15,8 @@ nym-crypto = { path = "../../crypto" }
nym-sphinx-acknowledgements = { path = "../acknowledgements" }
nym-sphinx-addressing = { path = "../addressing" }
nym-sphinx-chunking = { path = "../chunking" }
nym-sphinx-params = { path = "../params" }
nym-sphinx-forwarding = { path = "../forwarding" }
nym-sphinx-params = { path = "../params" }
nym-sphinx-routing = { path = "../routing" }
nym-sphinx-types = { path = "../types" }
nym-topology = { path = "../../topology" }
+2 -2
View File
@@ -13,7 +13,7 @@ use nym_sphinx_params::packet_sizes::PacketSize;
use nym_sphinx_params::{
PacketEncryptionAlgorithm, PacketHkdfAlgorithm, PacketType, DEFAULT_NUM_MIX_HOPS,
};
use nym_sphinx_types::{delays, NymPacket};
use nym_sphinx_types::NymPacket;
use nym_topology::{NymTopology, NymTopologyError};
use rand::{CryptoRng, RngCore};
use std::convert::TryFrom;
@@ -120,7 +120,7 @@ where
let route =
topology.random_route_to_gateway(rng, DEFAULT_NUM_MIX_HOPS, full_address.gateway())?;
let delays = delays::generate_from_average_duration(route.len(), average_packet_delay);
let delays = nym_sphinx_routing::generate_hop_delays(average_packet_delay, route.len());
let destination = full_address.as_sphinx_destination();
let first_hop_address =
+1 -1
View File
@@ -1,4 +1,4 @@
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::packet::{FramedNymPacket, Header};
+1 -1
View File
@@ -1,4 +1,4 @@
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
#![allow(deprecated)]
+11 -1
View File
@@ -1,8 +1,10 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use std::time::Duration;
use nym_sphinx_addressing::clients::Recipient;
use nym_sphinx_types::Node;
use nym_sphinx_types::{delays, Delay, Node};
use thiserror::Error;
pub trait SphinxRouteMaker {
@@ -41,3 +43,11 @@ impl SphinxRouteMaker for Vec<Node> {
}
}
}
pub fn generate_hop_delays(average_packet_delay: Duration, num_hops: usize) -> Vec<Delay> {
if average_packet_delay.is_zero() {
vec![nym_sphinx_types::Delay::new_from_millis(0); num_hops]
} else {
delays::generate_from_average_duration(num_hops, average_packet_delay)
}
}
+3 -3
View File
@@ -1,4 +1,4 @@
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::message::{NymMessage, ACK_OVERHEAD, OUTFOX_ACK_OVERHEAD};
@@ -14,7 +14,7 @@ use nym_sphinx_chunking::fragment::{Fragment, FragmentIdentifier};
use nym_sphinx_forwarding::packet::MixPacket;
use nym_sphinx_params::packet_sizes::PacketSize;
use nym_sphinx_params::{PacketType, ReplySurbKeyDigestAlgorithm, DEFAULT_NUM_MIX_HOPS};
use nym_sphinx_types::{delays, Delay, NymPacket};
use nym_sphinx_types::{Delay, NymPacket};
use nym_topology::{NymTopology, NymTopologyError};
use rand::{CryptoRng, Rng};
use std::convert::TryFrom;
@@ -233,7 +233,7 @@ pub trait FragmentPreparer {
// including set of delays
let delays =
delays::generate_from_average_duration(route.len(), self.average_packet_delay());
nym_sphinx_routing::generate_hop_delays(self.average_packet_delay(), route.len());
// create the actual sphinx packet here. With valid route and correct payload size,
// there's absolutely no reason for this call to fail.
+1 -1
View File
@@ -1,4 +1,4 @@
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use super::storage;
+1 -1
View File
@@ -1,4 +1,4 @@
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::constants::{
@@ -1,4 +1,4 @@
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use super::storage;
+1 -1
View File
@@ -1,4 +1,4 @@
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use super::storage;
@@ -1,4 +1,4 @@
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use super::helpers::must_get_gateway_bond_by_owner;
@@ -1,4 +1,4 @@
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
pub mod queries;
@@ -1,4 +1,4 @@
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use super::storage;
@@ -1,4 +1,4 @@
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::constants::CONTRACT_STATE_KEY;
@@ -1,4 +1,4 @@
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use super::storage;
+1 -1
View File
@@ -1,4 +1,4 @@
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use super::storage;
@@ -1,4 +1,4 @@
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use cosmwasm_std::{coin, Addr, Coin, DepsMut, Env, MessageInfo, Response, Storage};
+1 -1
View File
@@ -1,4 +1,4 @@
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use super::storage;
+1 -1
View File
@@ -1,4 +1,4 @@
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::constants::{
+1 -1
View File
@@ -1,4 +1,4 @@
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
#[cfg(test)]
+13 -32
View File
@@ -61,6 +61,7 @@ The validator binary can be compiled by running the following commands:
```
git clone https://github.com/nymtech/nyxd.git
cd nyxd
git checkout release/<nyxd_version>
# Mainnet
make build
@@ -77,43 +78,17 @@ At this point, you will have a copy of the `nyxd` binary in your `build/` direct
You should see help text print out.
The `nyxd` binary and the `libwasmvm.so` shared object library binary have been compiled. `libwasmvm.so` is the wasm virtual machine which is needed to execute smart contracts.
### Linking `nyxd` to `libwasmvm.so`
```admonish caution title=""
If you have compiled these files locally and need to upload both of them to the server on which the validator will run, **or** downloaded a pre-compiled binary from Github, you need to locate and link these files in slightly different ways, outlined below. If you have instead compiled them on the server skip to the step outlining setting `LD_LIBRARY PATH` below.
```
`libwasmvm.so` is the wasm virtual machine which is needed to execute smart contracts in `v0.26.1`. This file is renamed in `libwasmvm.x86_64.so` in `v0.31.1`.
To locate these files on your system **if you downloaded a pre-compiled binary from Github** run:
If you downloaded your `nyxd` binary from Github, you will have seen this file when un-`tar`-ing the `.tar.gz` file from the releases page.
```
WASMVM_SO=$(ldd path/to/nyxd/binary | grep libwasmvm.so | awk '{ print $3 }')
ls ${WASMVM_SO}
```
If you are seeing an error concerning this file when trying to run `nyxd`, then you need to move the `libwasmvm.so` file to correct location.
e.g. if you downloaded your `nyxd` binary to `/root` then you would replace `ldd path/to/nyxd/binary` with `ldd nyxd` in the above command.
To locate these files on your system **if you uploaded your validator after compiling it on a local machine** run:
```
WASMVM_SO=$(ldd build/nyxd | grep libwasmvm.so | awk '{ print $3 }')
ls ${WASMVM_SO}
```
The above commands will output something like:
```
'/home/username/go/pkg/mod/github.com/!cosm!wasm/wasmvm@v0.13.0/api/libwasmvm.so'
```
When you upload your `nyxd` binary, you'll need to tell it where `libwasmvm.so` is when you start your validator, or it will not run. If you have compiled them on your server then this is not necessary, as the compiled `nyxd` already has access to `libwasmvm.so`.
Upload both `nyxd` and `libwasmvm.so` to your validator machine. If `nyxd` can't find `libwasmvm.so` you will see an error like the following:
```
./nyxd: error while loading shared libraries: libwasmvm.so: cannot open shared object file: No such file or directory
```
Simply `cp` or `mv` that file to `/lib/x86_64-linux-gnu/` and re-run `nyxd`.
### Adding `nyxd` to your `$PATH`
You'll need to set `LD_LIBRARY_PATH` in your user's `~/.bashrc` file, and add that to our path. Replace `/home/youruser/path/to/nym/binaries` in the command below to the locations of `nyxd` and `libwasmvm.so` and run it. If you have compiled these on the server, they will be in the `build/` folder:
```
@@ -616,6 +591,12 @@ nyxd tx slashing unjail
--fees=7000unyxt
```
### Upgrading your validator
Upgrading from `v0.26.0` -> `v0.31.1` doesn't require many modifications, simply grab a binary from the [`nyxd` releases page](https://github.com/nymtech/nyxd/releases) and once the chain has halted at the decided upon haltheight, stop your `nyxd` process, replace your binaries, and restart your process.
You can also use something like [Cosmovisor](https://github.com/cosmos/cosmos-sdk/tree/main/tools/cosmovisor) - grab the relevant information from the current upgrade proposal [here](https://nym.explorers.guru/proposal/8).
#### Common reasons for your validator being jailed
The most common reason for your validator being jailed is that your validator is out of memory because of bloated syslogs.
+3 -7
View File
@@ -47,20 +47,16 @@ The example above involves ephemeral keys - if we want to create and then mainta
As seen in the example above, the `mixnet::MixnetClientBuilder::new()` function handles checking for keys in a storage location, loading them if present, or creating them and storing them if not, making client key management very simple.
### Manually handling storage
If you're integrating mixnet functionality into an existing app and want to integrate saving client configs and keys into your existing storage logic, you can manually perform the actions taken automatically above (`examples/manually_handle_keys_and_config.rs`)
If you're integrating mixnet functionality into an existing app and want to integrate saving client configs and keys into your existing storage logic, you can manually perform the actions taken automatically above (`examples/manually_handle_storage.rs`)
```rust,noplayground
{{#include ../../../../sdk/rust/nym-sdk/examples/manually_handle_keys_and_config.rs}}
{{#include ../../../../sdk/rust/nym-sdk/examples/manually_handle_storage.rs}}
```
### Anonymous replies with SURBs
Both functions used to send messages through the mixnet (`send_str` and `send_bytes`) send a pre-determined number of SURBs along with their messages by default.
The number of SURBs is set [here](https://github.com/nymtech/nym/blob/release/{{platform_release_version}}/sdk/rust/nym-sdk/src/mixnet/client.rs#L35):
```rust,noplayground
{{#include ../../../../sdk/rust/nym-sdk/src/mixnet/client.rs:30}}
```
The number of SURBs is set [here](https://github.com/nymtech/nym/blob/release/{{platform_release_version}}/sdk/rust/nym-sdk/src/mixnet/client.rs#L36).
You can read more about how SURBs function under the hood [here](../architecture/traffic-flow.md#private-replies-using-surbs).
+20 -24
View File
@@ -5,23 +5,23 @@ The Nym Desktop Wallet lets you interact with your Nym node and to delegate stak
You can download it for Mac, Windows, or Linux.
[![download nym wallet](../images/download-wallet.png)](https://github.com/nymtech/nym/releases/tag/nym-wallet-{{platform_release_version}})
[![download nym wallet](../images/download-wallet.png)](https://github.com/nymtech/nym/releases/tag/nym-wallet-v1.2.4)
### Bypassing security warnings
On Windows you will see a security warning pop up when you attempt to run the wallet. We are in the process of getting app store keys from Microsoft so that this doesn't happen. See the section below for details on steps to bypass these.
On Windows you will see a security warning pop up when you attempt to run the wallet. We are in the process of getting app store keys from Microsoft so that this doesn't happen. See the section below for details on steps to bypass these.
#### Linux
#### Linux
You will need to `chmod +x` the AppImage in the terminal (or give it execute permission in your file browser) before it will run.
You will need to `chmod +x` the AppImage in the terminal (or give it execute permission in your file browser) before it will run.
#### Windows
#### Windows
_You will still encounter warnings when opening the wallet on Windows. This is because - although the wallet is approved by Microsoft - it has less than 10 thousand downloads at the current time. Once the wallet has passed this threshold, this warning will disappear._
Follow the steps below to bypass the warnings.
Follow the steps below to bypass the warnings.
* Select more-info after clicking the msi installer app:
* Select more-info after clicking the msi installer app:
![Windows Warning](../images/wallet-warnings/windows_warningv1-0-2.png)
@@ -29,7 +29,7 @@ Follow the steps below to bypass the warnings.
![Windows Warning](../images/wallet-warnings/windows_warning2.png)
* Follow the installer instructions:
* Follow the installer instructions:
![Windows Warning](../images/wallet-warnings/windows_warning3.png)
@@ -39,7 +39,7 @@ Follow the steps below to bypass the warnings.
### For developers
If you would like to the compile the wallet yourself, follow the instructions below.
If you would like to the compile the wallet yourself, follow the instructions below.
> Please note that the wallet has currently only been built on the operating systems for which there are binaries as listed above. If you find an issue or any additional prerequisties, please create an issue or PR against `develop` on [Github](https://github.com/nymtech/docs).
@@ -85,22 +85,22 @@ sudo apt install pkg-config build-essential libssl-dev curl jq
### Removing signing errors when building in development mode
If you're wanting to build the wallet yourself, you will need to make a few modifications to the file located at `nym-wallet/src-tauri/tauri.conf.json` before doing so. These relate to the wallet being accepted by Mac and Windows app stores, and so aren't relevant to you when building and running the wallet yourself.
If you're wanting to build the wallet yourself, you will need to make a few modifications to the file located at `nym-wallet/src-tauri/tauri.conf.json` before doing so. These relate to the wallet being accepted by Mac and Windows app stores, and so aren't relevant to you when building and running the wallet yourself.
On **all** operating systems:
On **all** operating systems:
* set the value of line 49 to `false`
* remove lines 50 to 54
* remove lines 50 to 54
As well as these modifications for MacOS and Windows users:
* MacOS users must also remove line 39
* Windows users must remove lines 42 to 46
As well as these modifications for MacOS and Windows users:
* MacOS users must also remove line 39
* Windows users must remove lines 42 to 46
### Installation
Once you have made these modifications to `tauri.conf.json`, inside of the `nym-wallet` folder, run:
```
yarn install
```
```
### Running in Development Mode
@@ -112,7 +112,7 @@ You can run the wallet without having to install it in development mode by runni
yarn dev
```
This will then start the Wallet GUI and produce a binary in `nym-wallet/target/debug/` named `nym-wallet`.
This will then start the Wallet GUI and produce a binary in `nym-wallet/target/debug/` named `nym-wallet`.
### Running in Production Mode
@@ -165,25 +165,21 @@ To import or create a new account, first you need to create a password for your
6. Come back to this page to import or create new accounts
### Importing or creating account(s) when you have signed in with mnemonic but a password already exists on your machine
To import or create a new account, you need to log in with your existing password or create a new password.
To import or create a new account, you need to log in with your existing password or create a new password.
> Creating a new password will overwrite any old one stored on your machine. Make sure you have saved any mnemonics associated with the password before creating a new one.
1. Log out
2. Click on “Forgot password”
2. Click on “Forgot password”
3. On the next screen select “Create new password”
4. Follow the instructions and create a new password
5. Sign in using your new password
### CLI tool for wallet encrypted file (password) recovery:
The mnemonics that are stored in the local password protected file can also be decrypted and recovered through a simple CLI tool, `nym-wallet-recovery-cli`.
The mnemonics that are stored in the local password protected file can also be decrypted and recovered through a simple CLI tool, `nym-wallet-recovery-cli`.
```
nym-wallet-recovery file saved-wallet.json password foo
```
The saved wallet file can be found in `$XDG_DATA_HOME` or `$HOME/.local/share` on Linux, `$HOME/Library/Application Support` on Mac, and `C:\Users\username\AppData\Local` on Windows.
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "explorer-api"
version = "1.1.22"
version = "1.1.23"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+1 -1
View File
@@ -1,4 +1,4 @@
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use nym_mixnet_contract_common::{MixId, MixNode};
+1 -1
View File
@@ -3,7 +3,7 @@
[package]
name = "nym-gateway"
version = "1.1.22"
version = "1.1.23"
authors = [
"Dave Hrycyszyn <futurechimp@users.noreply.github.com>",
"Jędrzej Stuczyński <andrew@nymtech.net>",
-23
View File
@@ -1,23 +0,0 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "lib_25519"
version = "0.1.0"
dependencies = [
"cfg-if",
"libc",
]
[[package]]
name = "libc"
version = "0.2.146"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b"
-12
View File
@@ -1,12 +0,0 @@
[package]
name = "lib_25519"
version = "0.1.0"
edition = "2021"
build = "build.rs"
links = "25519"
[dependencies]
libc = "0.2.140"
[build-dependencies]
cfg-if = "1"
-69
View File
@@ -1,69 +0,0 @@
use std::{env, path::PathBuf, process::Command};
fn main() {
let out_dir = env::var("OUT_DIR").unwrap();
let out_path = PathBuf::from(&out_dir);
let source_path = PathBuf::from("lib25519")
.canonicalize()
.expect("cannot canonicalize path");
cfg_if::cfg_if! {
if #[cfg(not(any(target_arch = "x86", target_arch = "x86_64", target_arch = "mips", target_arch = "powerpc", target_arch = "powerpc64", target_arch = "arm")))] {
panic!("Unsupported architecture - {}!", env::var("CARGO_CFG_TARGET_ARCH").unwrap(), )
}
};
let mut compile_o_command = Command::new("./configure");
let compile_o_command = compile_o_command
.current_dir(&source_path)
.arg(format!("--prefix={out_dir}"));
match compile_o_command.output() {
Ok(output) => {
if !output.status.success() {
panic!("{:?}", unsafe {
std::str::from_utf8_unchecked(&output.stderr)
})
}
}
Err(e) => panic!("{e}"),
}
let mut compile_o_command = Command::new("make");
let compile_o_command = compile_o_command
.current_dir(&source_path)
.arg("-j8")
.arg("install");
match compile_o_command.output() {
Ok(output) => {
if !output.status.success() {
panic!("{:?}", unsafe {
std::str::from_utf8_unchecked(&output.stderr)
})
}
}
Err(e) => panic!("{e}"),
}
println!(
"cargo:rustc-link-search=native={}",
out_path.join("lib").to_str().unwrap()
);
println!("cargo:rustc-link-lib=static=25519");
println!("cargo:rustc-link-lib=static=randombytes_kernel");
let mut compile_o_command = Command::new("make");
let compile_o_command = compile_o_command.current_dir(source_path).arg("clean");
match compile_o_command.output() {
Ok(output) => {
if !output.status.success() {
panic!("{:?}", unsafe {
std::str::from_utf8_unchecked(&output.stderr)
})
}
}
Err(e) => panic!("{e}"),
}
}
-9
View File
@@ -1,9 +0,0 @@
Files: *
Copyright: 2022 Kaushik Nath
Copyright: 2011-2022 Daniel J. Bernstein
Copyright: 2015 Tung Chou
Copyright: 2011-2014 Peter Schwabe
Copyright: 2011 Niels Duif
Copyright: 2011 Tanja Lange
Copyright: 2011 Bo-Yin Yang
License: CC0-1.0
-297
View File
@@ -1,297 +0,0 @@
lib25519 draws on many previous implementations listed below, plus new
speedups from Kaushik Nath and new infrastructure work and factoring
from Daniel J. Bernstein. All software is in the public domain. Since
some organizations require licenses, lib25519 is also CC0-licensed.
Some code was originally copied from public-domain code in the SUPERCOP
benchmarking framework. See https://bench.cr.yp.to/supercop.html for
SUPERCOP releases. The following small changes from code available in
SUPERCOP are made in lib25519 without further comment:
* Returning void rather than int for functions that never fail in
lib25519.
* Message lengths long long rather than unsigned long long.
* Defining various constants in .c files (to simplify PIC handling)
instead of .S files.
* Moving some C files to shared-*.c (which in lib25519 means that
these files are compiled by only one compiler).
* Using CRYPTO_SHARED_NAMESPACE rather than CRYPTO_NAMESPACE for
symbols defined in *.S and shared-*.c.
* Adding various "linker define" and "linker use" lines.
Larger changes from code in SUPERCOP, such as new code divisions across
lib25519 primitives, are indicated below.
Sources of Curve25519 software (this is not a comprehensive list, just
the software that lib25519 is derived from):
* Daniel J. Bernstein. "Curve25519: new Diffie-Hellman speed
records." Pages 207228 in Public key cryptography—PKC 2006, 9th
international conference on theory and practice in public-key
cryptography, New York, NY, USA, April 2426, 2006, proceedings,
edited by Moti Yung, Yevgeniy Dodis, Aggelos Kiayias, Tal Malkin,
Lecture Notes in Computer Science 3958, Springer, 2006, ISBN
3-540-33851-9.
This is the source of the Curve25519 design, the X25519 design, and
various speedups. Most of the software from that paper is specific
to a variety of 32-bit platforms (radix 2^25.5 or radix 2^21.25),
but the portable supercop/crypto_scalarmult/curve25519/ref10 (radix
2^25.5) is derived from this.
lib25519/crypto_nP/montgomery25519/ref10 starts with
supercop/crypto_scalarmult/curve25519/ref10, and tweaks the API to
provide crypto_nP instead of crypto_scalarmult. Inversion is
factored out, producing crypto_pow/inv25519/ref10. The trivial
crypto_scalarmult_base wrapper is factored out, producing
crypto_nG/montgomery25519/ref/base.c; lib25519 has faster nG
functions, but intentionally provides ref for situations where
speed is outweighed by simplicity, assurance, code size, etc.
* supercop/crypto_scalarmult/curve25519/donna_c64 (radix 2^51) from
Adam Langley.
lib25519/crypto_nP/montgomery25519/donna_c64 starts from this and
tweaks the API to provide crypto_nP instead of crypto_scalarmult
(and removes crypto_scalarmult_base). crypto_pow/inv25519/donna_c64
is factored out.
* Daniel J. Bernstein, Niels Duif, Tanja Lange, Peter Schwabe, Bo-Yin
Yang. "High-speed high-security signatures." Pages 124142 in
Cryptographic hardware and embedded systems—CHES 2011, 13th
international workshop, Nara, Japan, September 28October 1, 2011,
proceedings, edited by Bart Preneel, Tsuyoshi Takagi, Lecture Notes
in Computer Science 6917, Springer, 2011, ISBN 978-3-642-23950-2.
Journal version: Journal of Cryptographic Engineering 2 (2012),
7789.
This is the source of the Ed25519 design and various X25519/Ed25519
speedups for 64-bit Intel/AMD platforms, in particular producing
supercop/crypto_{scalarmult/curve,sign/ed}25519/amd64-{51,64}*
(radix 2^51 and radix 2^64 respectively). Peter Schwabe led the
implementation work.
lib25519/crypto_nP/montgomery25519/amd64-51 starts from
supercop/crypto_scalarmult/curve25519/amd64-51 and tweaks the API
to provide crypto_nP instead of crypto_scalarmult (and removes
crypto_scalarmult_base). crypto_nG/merged25519/amd64-51 (for
fixed-base-point multiplication), crypto_mGnP/ed25519/amd64-51 (for
double-scalar multiplication), and crypto_sign/ed25519/amd64 (for
the remaining signing components) factor
supercop/crypto_sign/ed25519/amd64-51 into smaller pieces.
crypto_pow/inv25519/amd64-51 is also factored out. "SMALLTABLES"
support is removed. Support for batch verification is removed,
although it could reappear in a subsequent lib25519 release.
Similar comments apply to amd64-64 and ref10. A compiler warning
is eliminated (window size 64 in amd64-64-24k/sc25519.h).
* Tung Chou. "Sandy2x: New Curve25519 Speed Records." SAC 2015.
This is the source of various X25519 speedups using 256-bit vector
instructions, specifically AVX vector instructions in Intel's Sandy
Bridge, in particular producing
supercop/crypto_scalarmult/curve25519/sandy2x (radix 2^25.5).
lib25519/crypto_{nP,nG}/montgomery25519/sandy2x start from
supercop/crypto_scalarmult/curve25519/sandy2x, and tweak the API to
provide crypto_nP and crypto_nG instead of crypto_scalarmult and
crypto_scalarmult_base respectively. The top bit of the incoming
point is cleared. crypto_pow/inv25519/sandy2x is factored out.
* Kaushik Nath and Palash Sarkar, "Efficient arithmetic in
(pseudo-)Mersenne prime order fields", Advances in Mathematics of
Communications 16 (2022), pages 303348.
Original release:
https://github.com/kn-cs/pmp-farith/tree/master/gf-p2-255-19/SL
https://github.com/kn-cs/pmp-farith/tree/master/gf-p2-255-19/USL1
The "SL" software is the source of various speedups to the amd64-64
software, producing the "maa4" versions of fe25519_mul.S,
fe25519_square.S, and fe25519_nsquare.S. These .S files are used
inside the following lib25519 directories:
crypto_mGnP/ed25519/amd64-avx2-10l-maa4
crypto_mGnP/ed25519/amd64-avx2-9l-maa4
crypto_mGnP/ed25519/amd64-maa4
crypto_nG/merged25519/amd64-avx2-10l-maa4
crypto_nG/merged25519/amd64-avx2-9l-maa4
crypto_nG/merged25519/amd64-maa4
crypto_nP/montgomery25519/amd64-avx2-hey10l-maa4
crypto_nP/montgomery25519/amd64-avx2-hey9l-maa4
crypto_nP/montgomery25519/amd64-avx2-ns10l-maa4
crypto_nP/montgomery25519/amd64-avx2-ns9l-maa4
crypto_nP/montgomery25519/amd64-maa4
crypto_pow/inv25519/amd64-maa4
The "USL" software is the source of various speedups to the
amd64-51 software, producing the "maa5" versions of fe25519_mul.S
and fe25519_nsquare.S. These .S files are used inside the following
lib25519 directories:
crypto_nP/montgomery25519/amd64-avx2-hey10l-maa5
crypto_nP/montgomery25519/amd64-avx2-hey9l-maa5
crypto_nP/montgomery25519/amd64-avx2-ns10l-maa5
crypto_nP/montgomery25519/amd64-avx2-ns9l-maa5
crypto_pow/inv25519/amd64-maa5
* Kaushik Nath and Palash Sarkar, "Security and efficiency trade-offs
for elliptic curve Diffie-Hellman at the 128-bit and 224-bit
security levels." J. Cryptogr. Eng. 12(1): 107-121 (2022).
Original release:
https://github.com/kn-cs/x25519/tree/master/intel64-mxaa-4limb
https://github.com/kn-cs/x25519
This "mxaa-4limb" software is the source of various speedups to
"maa4" on CPUs supporting BMI2 instructions (e.g., Intel Haswell
from 2013), in particular producing the "mxaa" versions of
fe25519_mul.S and fe25519_nsquare.S. These .S files are used inside
the following lib25519 directories:
crypto_mGnP/ed25519/amd64-avx2-10l-mxaa
crypto_mGnP/ed25519/amd64-avx2-9l-mxaa
crypto_mGnP/ed25519/amd64-mxaa
crypto_nG/merged25519/amd64-avx2-10l-mxaa
crypto_nG/merged25519/amd64-avx2-9l-mxaa
crypto_nG/merged25519/amd64-mxaa
crypto_nP/montgomery25519/amd64-avx2-hey10l-mxaa
crypto_nP/montgomery25519/amd64-avx2-hey9l-mxaa
crypto_nP/montgomery25519/amd64-avx2-ns10l-mxaa
crypto_nP/montgomery25519/amd64-avx2-ns9l-mxaa
crypto_nP/montgomery25519/amd64-mxaa
crypto_pow/inv25519/amd64-mxaa
This software is also the source of the following three different
Montgomery-ladder functions, where the third also builds on the
"maax" work listed below:
crypto_nP/montgomery25519/amd64-maa4/mladder.S
crypto_nP/montgomery25519/amd64-mxaa/mladder.S
crypto_nP/montgomery25519/amd64-maax/mladder.S
* Kaushik Nath and Palash Sarkar, "Efficient arithmetic in
(pseudo-)Mersenne prime order fields", Advances in Mathematics of
Communications 16 (2022), pages 303348. Original release:
https://github.com/kn-cs/pmp-farith/tree/master/gf-p2-255-19/SLDCC
This is the source of various speedups to "mxaa" on CPUs that also
support ADX instructions (e.g., Intel Broadwell from 2014), in
particular producing the "maax" versions of fe25519_mul.S,
fe25519_square.S, and fe25519_nsquare.S. These .S files are used
inside the following lib25519 directories:
crypto_mGnP/ed25519/amd64-avx2-10l-maax
crypto_mGnP/ed25519/amd64-avx2-9l-maax
crypto_mGnP/ed25519/amd64-avx512ifma-5l-maax
crypto_mGnP/ed25519/amd64-maax
crypto_nG/merged25519/amd64-avx2-10l-maax
crypto_nG/merged25519/amd64-avx2-9l-maax
crypto_nG/merged25519/amd64-avx512ifma-5l-maax
crypto_nG/merged25519/amd64-maax
crypto_nP/montgomery25519/amd64-avx2-hey10l-maax
crypto_nP/montgomery25519/amd64-avx2-hey9l-maax
crypto_nP/montgomery25519/amd64-avx2-ns10l-maax
crypto_nP/montgomery25519/amd64-avx2-ns9l-maax
crypto_nP/montgomery25519/amd64-avx512-hey10l-maax
crypto_nP/montgomery25519/amd64-avx512-hey9l-maax
crypto_nP/montgomery25519/amd64-avx512-ns10l-maax
crypto_nP/montgomery25519/amd64-avx512-ns9l-maax
crypto_nP/montgomery25519/amd64-avx512ifma-hey5l-maax
crypto_nP/montgomery25519/amd64-avx512ifma-ns5l-maax
crypto_nP/montgomery25519/amd64-maax
crypto_pow/inv25519/amd64-maax
* Kaushik Nath and Palash Sarkar, "Efficient 4-Way Vectorizations of
the Montgomery Ladder". IEEE Trans. Computers 71(3): 712-723
(2022). Original release:
https://github.com/kn-cs/vec-ladder/tree/master/Curve25519
This is the source of the "hey10l" (radix 2^25.5), "hey9l" (radix
2^29), "ns10l" (radix 2^25.5), and "ns9l" (radix 2^29) versions of
mladder.S for CPUs that also support 256-bit AVX2 instructions
(e.g., Intel Haswell from 2013). In lib25519, these four .S files
are used in 16 directories:
crypto_nP/montgomery25519/amd64-avx2-hey10l-{maa4,maa5,maax,mxaa}
crypto_nP/montgomery25519/amd64-avx2-hey9l-{maa4,maa5,maax,mxaa}
crypto_nP/montgomery25519/amd64-avx2-ns10l-{maa4,maa5,maax,mxaa}
crypto_nP/montgomery25519/amd64-avx2-ns9l-{maa4,maa5,maax,mxaa}
* Kaushik Nath, new Montgomery-ladder code new in lib25519 (no paper
yet) for CPUs supporting AVX-512 instructions (e.g., Intel
Skylake-X from 2017). These are six files in lib25519:
crypto_nP/montgomery25519/amd64-avx512-hey10l-maax
crypto_nP/montgomery25519/amd64-avx512-hey9l-maax
crypto_nP/montgomery25519/amd64-avx512-ns10l-maax
crypto_nP/montgomery25519/amd64-avx512-ns9l-maax
crypto_nP/montgomery25519/amd64-avx512ifma-hey5l-maax
crypto_nP/montgomery25519/amd64-avx512ifma-ns5l-maax
* Kaushik Nath, nine versions of fixed-base-point
scalar-multiplication code new in lib25519 (no paper yet) for
various platforms:
crypto_nG/merged25519/amd64-avx2-10l-maa4/ge25519_base.S
crypto_nG/merged25519/amd64-avx2-10l-maax/ge25519_base.S
crypto_nG/merged25519/amd64-avx2-10l-mxaa/ge25519_base.S
crypto_nG/merged25519/amd64-avx2-9l-maa4/ge25519_base.S
crypto_nG/merged25519/amd64-avx2-9l-maax/ge25519_base.S
crypto_nG/merged25519/amd64-avx2-9l-mxaa/ge25519_base.S
crypto_nG/merged25519/amd64-avx512ifma-5l-maax/ge25519_base.S
crypto_nG/merged25519/amd64-maa4/ge25519_base.S
crypto_nG/merged25519/amd64-maax/ge25519_base.S
crypto_nG/merged25519/amd64-mxaa/ge25519_base.S
* Kaushik Nath, ten versions of double-scalar-multiplication code new
in lib25519 (no paper yet) for various platforms. Each version has
precompute.S and process.S:
crypto_mGnP/ed25519/amd64-avx2-10l-maa4/ge25519_double_scalarmult_precompute.S
crypto_mGnP/ed25519/amd64-avx2-10l-maax/ge25519_double_scalarmult_precompute.S
crypto_mGnP/ed25519/amd64-avx2-10l-mxaa/ge25519_double_scalarmult_precompute.S
crypto_mGnP/ed25519/amd64-avx2-9l-maa4/ge25519_double_scalarmult_precompute.S
crypto_mGnP/ed25519/amd64-avx2-9l-maax/ge25519_double_scalarmult_precompute.S
crypto_mGnP/ed25519/amd64-avx2-9l-mxaa/ge25519_double_scalarmult_precompute.S
crypto_mGnP/ed25519/amd64-avx512ifma-5l-maax/ge25519_double_scalarmult_precompute.S
crypto_mGnP/ed25519/amd64-maa4/ge25519_double_scalarmult_precompute.S
crypto_mGnP/ed25519/amd64-maax/ge25519_double_scalarmult_precompute.S
crypto_mGnP/ed25519/amd64-mxaa/ge25519_double_scalarmult_precompute.S
crypto_mGnP/ed25519/amd64-avx2-10l-maa4/ge25519_double_scalarmult_process.S
crypto_mGnP/ed25519/amd64-avx2-10l-maax/ge25519_double_scalarmult_process.S
crypto_mGnP/ed25519/amd64-avx2-10l-mxaa/ge25519_double_scalarmult_process.S
crypto_mGnP/ed25519/amd64-avx2-9l-maa4/ge25519_double_scalarmult_process.S
crypto_mGnP/ed25519/amd64-avx2-9l-maax/ge25519_double_scalarmult_process.S
crypto_mGnP/ed25519/amd64-avx2-9l-mxaa/ge25519_double_scalarmult_process.S
crypto_mGnP/ed25519/amd64-avx512ifma-5l-maax/ge25519_double_scalarmult_process.S
crypto_mGnP/ed25519/amd64-maa4/ge25519_double_scalarmult_process.S
crypto_mGnP/ed25519/amd64-maax/ge25519_double_scalarmult_process.S
crypto_mGnP/ed25519/amd64-mxaa/ge25519_double_scalarmult_process.S
Almost all of the crypto_pow/inv25519 implementations use exponentiation,
but there is also a different implementation from the following source:
* Daniel J. Bernstein, Bo-Yin Yang. "Fast constant-time gcd
computation and modular inversion." IACR Transactions on
Cryptographic Hardware and Embedded Systems 2019 issue 3 (2019),
340398.
This is the source of the "safegcd" algorithm and software. Further
speedups (no paper yet; ideas from Peter Dettman, Gregory Maxwell,
and Pieter Wuille) have produced the "inverse25519skylake" software
available here: https://gcd.cr.yp.to/software.html
lib25519/crypto_pow/inv25519/amd64-safegcd is inverse25519skylake,
tweaked to provide the crypto_pow API and to clear the top bit of
the input.
For lower-layer SHA-512 functions:
* Daniel J. Bernstein, supercop/crypto_hash*/sha512/*. In lib25519,
some unused variables are removed in crypto_hashblocks/sha512/avx
to eliminate compiler warnings.
Most of the lib25519 infrastructure, such as the run-time implementation
selector automatically guided by CPU type and previous benchmarks, is
new in lib25519 from Daniel J. Bernstein. Portions of autogen-speed
(generating lib25519-speed.c) and autogen-test (generating
lib25519-test.c) are based on benchmarking software and test software in
SUPERCOP by Daniel J. Bernstein. The symmetric-cryptography code for
generating pseudorandom test inputs and hashing test outputs is adapted
from TweetNaCl, a library by Daniel J. Bernstein, Wesley Janssen, Tanja
Lange, and Peter Schwabe.
-53
View File
@@ -1,53 +0,0 @@
Prerequisites: python3; gcc and/or clang.
For sysadmins, to install in /usr/local/{include,lib,bin}:
./configure && make -j8 install
For users, to install in $HOME/{include,lib,bin}:
./configure --prefix=$HOME && make -j8 install
For distributors creating a package: Run
./configure --prefix=/usr && make -j8
and then follow your usual packaging procedures for the .h files in
build/0/package/include, the libraries in build/0/package/lib, and the
test programs in build/0/package/bin.
The long-term plan is to split off some components of lib25519 into
their own packages, and distributors may already wish to package these
components accordingly:
* -lcpucycles will be its own package.
* -lrandombytes_kernel will be its own package.
* -lrandombytes will be an indirection layer providing randombytes.h
and supporting an ecosystem of randombytes() implementations (via,
e.g., Debian's /etc/alternatives), such as -lrandombytes_kernel,
-lrandombytes_per_process_rng, etc.
* -l25519 will be the main lib25519 package, using -lrandombytes and
-lcpucycles.
lib25519-test already uses -l25519 without -lrandombytes: it substitutes
its own knownrandombytes() to generate test vectors.
More options: You can run
./configure --host=amd64
to override ./configure's guess of the architecture that it should
compile for. The architecture controls which implementations to try
(see crypto_*/*/*/architectures) and which compilers to try (see
compilers/*).
Inside the build directory, 0 is symlinked to amd64 for --host=amd64.
Running "make clean" removes build/amd64. Re-running ./configure
automatically starts with "make clean".
A subsequent ./configure --host=arm will create build/arm and symlink
0 -> arm, without touching an existing build/amd64. However,
cross-compilers aren't yet selected automatically.
-405
View File
@@ -1,405 +0,0 @@
This file explains the internal structure of lib25519, and explains how
to add new instruction sets and new implementations.
## Primitives
The directories `crypto_*/*` inside lib25519 define the following
primitives (see also `autogen-test` for Python versions of the
mathematical primitives):
* `crypto_verify/32`: `crypto_verify_32(s,t)` returns 0 when the 32-byte
arrays `s` and `t` are equal, otherwise `-1`. This function takes
constant time.
* `crypto_hashblocks/sha512`: `crypto_hashblocks_sha512(h,x,xlen)`
updates an intermediate SHA-512 hash `h` using all of the full
128-byte blocks at the beginning of the `xlen`-byte array `x`, and
returns the number of bytes left over, namely `xlen` mod 128. This
function takes time that depends on `xlen` but not on the contents of
`h` or `x`.
* `crypto_hash/sha512`: `crypto_hash_sha512(h,x,xlen)` computes the
SHA-512 hash `h` of the `xlen`-byte array `x`. This function takes
time that depends on `xlen` but not on the contents of `x`.
* `crypto_pow/inv25519`: `crypto_pow_inv25519(y,x)` computes the
2^255^21 power `y` of an integer `x` modulo 2^255^19. This is the
same as the inverse of `x` modulo 2^255^19 if `x` is not divisible by
2^255^19. The integers `x` and `y` are represented as a 32-byte array
in little-endian form. This function takes constant time.
This function guarantees that the output `y` is frozen modulo
2^255^19, i.e., completely reduced to the range 0,1,...,2^255^20. The
caller is expected to freeze `x` before calling this function. The
function accepts `x` in the range {0,1,...,2^256^1} while ignoring the
top bit (the coefficient of 2^255^ in binary): i.e., the function
reduces `x` modulo 2^255^ and then modulo 2^255^19.
* `crypto_nP/montgomery25519`: `crypto_nP_montgomery25519(nP,n,P)`
computes the X25519 function: in short, if a Curve25519 point has
x-coordinate `P` then the `n`th multiple of the point has x-coordinate
`nP`. The inputs and outputs are represented as 32-byte arrays in
little-endian form. This function takes constant time.
X25519 is defined for `n` in the range 2^254^ + 8{0,1,2,3,...,2^251^1}.
`crypto_nP_montgomery25519` allows `n` in the wider range
{0,1,...,2^256^1}, and in all cases computes `m`th multiples where `m`
is defined as follows: make a copy of `n`, clear the top bit, set the
next bit, and clear the bottom three bits.
X25519 guarantees that the output `nP` is frozen. It does not require
the input to be frozen; also, it allows the input to be on the twist,
and to have small order.
`crypto_nP_montgomery25519` clears the top bit of `P` before applying
the X25519 function. Callers that want the X25519 function on `P` with
the top bit set have to reduce modulo 2^255^19 for themselves.
* `crypto_nG/merged25519`: `crypto_nG_merged25519(nG,n)` reads an
integer `n` in the range {0,1,...,2^256^1} and outputs a frozen
integer `nG` modulo 2^255^19, possibly with the top bit set (i.e.,
adding 2^255^) as described below. Both `n` and `nG` are represented
as 32-byte arrays in little-endian form. This function takes constant
time.
If the top bit of `n` is clear then `nG` is the Edwards y-coordinate
of the `n`th multiple of G, and the top bit is set exactly when the
Edwards x-coordinate is odd. Otherwise `nG` is the Montgomery
x-coordinate of the (`n`2^255^)th multiple of G, and the top bit is
clear. Here G is the standard Curve25519 base point, which has
Montgomery x-coordinate 9, Edwards y-coordinate 4/5, and even Edwards
x-coordinate.
* `crypto_nG/montgomery25519`: `crypto_nG_montgomery25519(nG,n)` is
the same as `crypto_nP_montgomery(nG,n,G)` where `G` is the array
{9,0,0,...,0}. This function takes constant time.
The point of `crypto_nG` is to save time (using a small table
precomputed from `G`) compared to the more general `crypto_nP`. This
has the disadvantage of being more complicated, which is particularly
important given that lib25519 has not yet been verified, and in any
case increases code size noticeably for X25519. There is a `ref`
implementation of `crypto_nG` that simply calls `crypto_nP`, and
setting sticky bits on the other implementation directories
(`chmod +t crypto_nG/montgomery25519/*; chmod -t crypto_nG/montgomery25519/ref`)
will force lib25519 to use `ref`.
* `crypto_mGnP/ed25519`: `crypto_mGnP_ed25519(mGnP,m,n,P)` computes
`(m mod L)G(n mod L)P` in Edwards coordinates, where `L` is the prime
number 2^252^+27742317777372353535851937790883648493 and `G` is the
same standard base point. This function takes time that depends on the
inputs.
The input `m` is an integer in the range {0,1,...,2^256^1}
represented as a 32-byte array in little-endian form. Any `m` outside
the range {0,1,...,L1} triggers a failure, which is reported as
described below.
The input `n` is an integer in the range {0,1,...,2^512^1}
represented as a 64-byte array in little-endian form.
The input point `P` is represented as a 32-byte array as follows: the
(frozen) Edwards y-coordinate of `P` in {0,1,...,2^255^20} is stored
in little-endian form, and then the top bit is set exactly when the
(frozen) Edwards x-coordinate of `P` is odd. An input 32-byte array
that does not have this form is instead interpreted as the point `P`
with Edwards coordinates (...8,26), and triggers a failure, reported
as described below.
The output is a 33-byte array. The first 32 bytes are the output point
`(m mod L)G(n mod L)P`, represented the same way as `P`. The last
byte is 1 on success and 0 on failure.
* `crypto_dh/x25519`: `crypto_dh_x25519_keypair(pk,sk)` generates a
32-byte X25519 public key `pk` and the corresponding 32-byte secret
key `sk`. This function is the composition of `randombytes` to
generate `sk` and `crypto_nG_montgomery25519` to generate `pk`.
`crypto_dh_x25519(k,pk,sk)` generates a 32-byte shared secret `k`
given a public key `pk` and a secret key `sk`. This function is the
same as `crypto_nP_montgomery25519`.
* `crypto_sign/ed25519`: `crypto_sign_ed25519_keypair(pk,sk)` generates
a 32-byte Ed25519 public key `pk` and the corresponding 64-byte secret
key `sk`. This function takes constant time.
`crypto_sign_ed25519(sm,&smlen,m,mlen,sk)` generates an `smlen`-byte
signed message `sm` given an `mlen`-byte message `m` and a secret key
`sk`. The caller is required to allocate `mlen+64` bytes for `sm`. The
function always sets `smlen` to `mlen+64`. This function takes time
that depends on `mlen` but not on the other inputs.
`crypto_sign_ed25519_open(m,&mlen,sm,smlen,pk)` generates an
`mlen`-byte message `m` given an `smlen`-byte signed message `sm` and
a public key `pk`, and returns 0. However, if `sm` is invalid, this
function returns `-1`, sets `mlen` to `-1`, and clears `m`. The caller is
required to allocate `smlen` (not just `smlen-64`) bytes for `m`, for
example using the same array for `sm` and `m`. This function takes time
that depends on its inputs.
lib25519 includes a command-line utility `lib25519-test` that runs some
tests for each of these primitives, and another utility `lib25519-speed`
that measures cycle counts for each of these primitives.
The stable lib25519 API functions are built from the above primitives:
* `lib25519_dh_keypair` is `crypto_dh_x25519_keypair`.
* `lib25519_dh` is `crypto_dh_x25519`.
* `lib25519_sign_keypair` is `crypto_sign_ed25519_keypair`.
* `lib25519_sign` is `crypto_sign_ed25519`.
* `lib25519_sign_open` is `crypto_sign_ed25519_open`.
Some changes are anticipated in the list of primitives, but these API
functions will remain stable.
As in SUPERCOP and NaCl, message lengths intentionally use `long long`,
not `size_t`. In lib25519, message lengths are signed.
## Implementations
A single primitive can, and usually does, have multiple implementations.
Each implementation is in its own subdirectory. The implementations are
required to have exactly the same input-output behavior, and to some
extent this is tested, although it is not yet formally verified.
Different implementations typically offer different tradeoffs between
portability, simplicity, and efficiency. For example,
`crypto_nP/montgomery25519/ref10` is portable;
`crypto_nP/montgomery25519/amd64-maax` is faster and less portable.
Each unportable implementation has an `architectures` file. Each line in
this file identifies a CPU instruction set (and ABI) where the
implementation works. For example,
`crypto_nP/montgomery25519/amd64-maax/architectures` has one line
`amd64 bmi2 adx`, meaning that the implementation works on CPUs that
have the Intel/AMD 64-bit instruction set with the BMI2 and ADX
instruction-set extensions. The top-level `compilers` directory shows
(among other things) the allowed instruction-set names such as `bmi2`.
At run time, lib25519 checks the CPU where it is running, and selects
an implementation where `architectures` is compatible with that CPU.
Each primitive makes its own selection once per program startup, using
the compiler's `ifunc` mechanism. This type of run-time selection means,
for example, that an `amd64` CPU without AVX2 can share binaries with an
`amd64` CPU with AVX2. However, correctness requires instruction sets to
be preserved by migration across cores via the OS kernel, VM migration,
etc.
The compiler has a `target` mechanism that makes an `ifunc` selection
based on CPU architectures. Instead of using the `target` mechanism,
lib25519 uses a more sophisticated mechanism that also accounts for
benchmarks collected in advance of compilation.
## Compilers
lib25519 tries different C compilers for each implementation. For
example, `compilers/default` lists the following compilers:
gcc -Wall -fPIC -fwrapv -O2
clang -Wall -fPIC -fwrapv -Qunused-arguments -O2
Sometimes `gcc` produces better code, and sometimes `clang` produces
better code.
As another example, `compilers/amd64+avx` lists the following compilers:
gcc -Wall -fPIC -fwrapv -O2 -mmmx -msse -msse2 -msse3 -mssse3 -msse4.1 -msse4.2 -mavx -mtune=sandybridge
clang -Wall -fPIC -fwrapv -Qunused-arguments -O2 -mmmx -msse -msse2 -msse3 -mssse3 -msse4.1 -msse4.2 -mavx -mtune=sandybridge
The `-mavx` option tells these compilers that they are free to use the
AVX instruction-set extension.
Code compiled using the compilers in `compilers/amd64+avx` will be
considered at run time by the lib25519 selection mechanism if the
`supports()` function in `compilers/amd64+avx.c` returns nonzero. This
function checks whether the run-time CPU supports AVX (and SSE and so on,
and OSXSAVE with XMM/YMM being saved;
[https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85100](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85100)
says that all versions of gcc until 2018 handled this incorrectly in
`target`). Similar comments apply to other `compilers/*` files.
If some compilers fail (for example, clang is not installed, or the
compiler version is too old to support the compiler options used in
lib25519), the lib25519 compilation process will try its best to produce
a working library using the remaining compilers, even if this means
lower performance.
## Trimming
By default, to reduce size of the compiled library, the lib25519
compilation process trims the library down to the implementations that
are selected by lib25519's selection mechanism (across all CPUs; the
library remains portable, not tied to the compilation CPU).
This trimming is handled at link time rather than compile time to
increase the chance that, even if some implementations are broken by
compiler "upgrades", the library will continue to build successfully.
To avoid this trimming, pass the `--notrim` option to `./configure`.
All implementations that compile are then included in the library,
tested by `lib2519-test`, and measured by `lib25519-speed`. You'll want
to avoid trimming if you're adding new instruction sets or new
implementations (see below), so that you can run tests and benchmarks of
code that isn't selected yet.
## How to recompile after changes
If you make changes in the lib25519 source directory, you have to run
`./configure` again to repopulate the build directory. Simply running
`make` again doesn't suffice.
By default, `./configure` cleans the build directory first, so `make`
will recompile everything. This can be on the scale of seconds if you
have enough cores, but maybe you're developing on a slower machine. Two
options are currently available to accelerate the edit-compile cycle:
* There is an experimental `--noclean` option to `./configure` that,
for some simple types of changes, can produce a successful build
without cleaning.
* You can disable the implementations you're not using by setting
sticky bits on the source directories for those implementations:
e.g., `chmod +t crypto_nG/*/*avx2*`.
Make sure to reenable all implementations and do a full clean build if
you're collecting data to add to the source `benchmarks` directory.
## How to add new instruction sets
Adding another file `compilers/amd64+foo`, along with a `supports()`
implementation in `compilers/amd64+foo.c`, will support a new
instruction set. Do not assume that the new `foo` instruction set
implies support for older instruction sets (the idea of "levels" of
instruction sets); instead make sure to include the older instruction
sets in `+` tags, as illustrated by
`compilers/amd64+avx+bmi2+avx2+adx+avx512f+avx512vl+avx512ifma`.
In the compiler options, always make sure to include `-fPIC` to support
shared libraries, and `-fwrapv` to switch to a slightly less dangerous
version of C.
The `foo` tags don't have to be instruction sets. For example, if a CPU
has the same instruction set but wants different optimizations because
of differences in instruction timings, you can make a tag for those
optimizations, using, e.g., CPU IDs or benchmarks in the corresponding
`supports()` function to decide whether to enable those optimizations.
Benchmarks tend to be more future-proof than a list of CPU IDs, but the
time taken for benchmarks at program startup has to be weighed against
the subsequent speedup from the resulting optimizations.
To see how well lib25519 performs with the new compilers, run
`lib25519-speed` on the target machine and look for the `foo` lines in
the output. If the new performance is better than the performance shown
on the `selected` lines:
* Copy the `lib25519-speed` output into a file on the `benchmarks`
directory, typically named after the hostname of the target
machine.
* Run `./prioritize` in the top-level directory to create `priority`
files. These files tell lib25519 which implementations to select
for any given architecture.
* Reconfigure (again with `--notrim`), recompile, rerun
`lib25519-test`, and rerun `lib25519-speed` to check that the
`default` lines now use the `foo` compiler.
If the `foo` implementation is outperformed by other implementations,
then these steps don't help except for documenting this fact. The same
implementation might turn out to be useful for subsequent `foo` CPUs.
## How to add new implementations
Taking full advantage of the `foo` instruction set usually requires
writing new implementations. Sometimes there are also ideas for taking
better advantage of existing instruction sets.
Structurally, adding a new implementation of a primitive is a simple
matter of adding a new subdirectory with the code for that
implementation. Most of the work is optimizing the use of `foo`
intrinsics in `.c` files or `foo` instructions in `.S` files. Make sure
to include an `architectures` file saying, e.g., `amd64 avx2 foo`.
Names of implementation directories can use letters, digits, dashes, and
underscores. Do not use two implementation names that are the same when
dashes and underscores are removed.
All `.c` and `.S` files in the implementation directory are compiled and
linked. There is no need to edit a separate list of these files. You can
also use `.h` files via the C preprocessor.
If an implementation is actually more restrictive than indicated in
`architectures` then the resulting compiled library will fail on some
machines (although perhaps that implementation will not be used by
default). Putting unnecessary restrictions into `architectures` will not
create such failures, but can unnecessarily limit performance.
Some, but not all, mistakes in `architectures` will produce warnings
from the `checkinsns` script that runs automatically when lib25519 is
compiled. Running the `lib25519-test` program tries all implementations,
but only on the CPU where `lib25519-test` is being run, and `lib25519-test`
does not guarantee code coverage: for example, other message lengths
being signed could involve other code paths.
`amd64` implies little-endian, and implies architectural support for
unaligned loads and stores. Beware, however, that the Intel/AMD
vectorized `load`/`store` intrinsics (and the underlying `movdqa`
instruction) require alignment; if in doubt, use `loadu`/`storeu` (and
`movdqu`). The `lib25519-test` program checks unaligned inputs and
outputs, but can miss issues with unaligned stack variables.
To test your implementation, compile everything, check for compiler
warnings and errors, run `lib25519-test` (or just `lib25519-test nG` to
test a `crypto_nG` implementation), and check for a line saying `all
tests succeeded`. To use AddressSanitizer (for catching, at run time,
buffer overflows in C code), add `-fsanitize=address` to the `gcc` and
`clang` lines in `compilers/*`.
To see the performance of your implementation, run `lib25519-speed`.
If the new performance is better than the performance shown on the
`default` lines, follow the same steps as for a new instruction set:
copy the `lib25519-speed` output into a file on the `benchmarks`
directory; run `./prioritize` in the top-level directory to create
`priority` files; reconfigure (again with `--notrim`); recompile; rerun
`lib25519-test`; rerun `lib25519-speed`; check that the `default` lines
now use the new implementation.
## How to handle namespacing
As in SUPERCOP and NaCl, to call `crypto_hash_sha512()`, you have to
include `crypto_hash_sha512.h`; but to write an implementation of
`crypto_hash_sha512()`, you have to instead include `crypto_hash.h` and
define `crypto_hash`. Similar comments apply to other primitives.
The function name that's actually linked might end up as, e.g.,
`lib25519_hash_sha512_blocksplusavx_C2_hash` where `blocksplusavx`
indicates the implementation and `C2` indicates the compiler. Don't try
to build this name into your implementation.
If you have another global symbol `x` (for example, a non-`static`
function in a `.c` file, or a non-`static` variable outside functions in
a `.c` file), you have to replace it with `CRYPTO_NAMESPACE(x)`, for
example with `#define x CRYPTO_NAMESPACE(x)`.
For global symbols in `.S` files and `shared-*.c` files, use
`CRYPTO_SHARED_NAMESPACE` instead of `CRYPTO_NAMESPACE`. For `.S` files
that define both `x` and `_x` to handle platforms where `x` in C is `_x`
in assembly, use `CRYPTO_SHARED_NAMESPACE(x)` and
`_CRYPTO_SHARED_NAMESPACE(x)`; `CRYPTO_SHARED_NAMESPACE(_x)` is not
sufficient.
lib25519 includes a mechanism to recognize files that are copied across
implementations (possibly of different primitives) and to unify those
into a file compiled only once, reducing the overall size of the
compiled library and possibly improving cache utilization. To request
this mechanism, include a line `// linker define x` for any global
symbol `x` defined in the file, and a line `// linker use x` for any
global symbol `x` used in the file from the same implementation (not
`crypto_*` subroutines that you're calling, `randombytes`, etc.). This
mechanism tries very hard, perhaps too hard, to avoid improperly
unifying files: for example, even a slight difference in a `.h` file
included by a file defining a used symbol will disable the mechanism.
Typical namespacing mistakes will produce either linker failures or
warnings from the `checknamespace` script that runs automatically when
lib25519 is compiled.
-121
View File
@@ -1,121 +0,0 @@
Creative Commons Legal Code
CC0 1.0 Universal
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
HEREUNDER.
Statement of Purpose
The laws of most jurisdictions throughout the world automatically confer
exclusive Copyright and Related Rights (defined below) upon the creator
and subsequent owner(s) (each and all, an "owner") of an original work of
authorship and/or a database (each, a "Work").
Certain owners wish to permanently relinquish those rights to a Work for
the purpose of contributing to a commons of creative, cultural and
scientific works ("Commons") that the public can reliably and without fear
of later claims of infringement build upon, modify, incorporate in other
works, reuse and redistribute as freely as possible in any form whatsoever
and for any purposes, including without limitation commercial purposes.
These owners may contribute to the Commons to promote the ideal of a free
culture and the further production of creative, cultural and scientific
works, or to gain reputation or greater distribution for their Work in
part through the use and efforts of others.
For these and/or other purposes and motivations, and without any
expectation of additional consideration or compensation, the person
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
is an owner of Copyright and Related Rights in the Work, voluntarily
elects to apply CC0 to the Work and publicly distribute the Work under its
terms, with knowledge of his or her Copyright and Related Rights in the
Work and the meaning and intended legal effect of CC0 on those rights.
1. Copyright and Related Rights. A Work made available under CC0 may be
protected by copyright and related or neighboring rights ("Copyright and
Related Rights"). Copyright and Related Rights include, but are not
limited to, the following:
i. the right to reproduce, adapt, distribute, perform, display,
communicate, and translate a Work;
ii. moral rights retained by the original author(s) and/or performer(s);
iii. publicity and privacy rights pertaining to a person's image or
likeness depicted in a Work;
iv. rights protecting against unfair competition in regards to a Work,
subject to the limitations in paragraph 4(a), below;
v. rights protecting the extraction, dissemination, use and reuse of data
in a Work;
vi. database rights (such as those arising under Directive 96/9/EC of the
European Parliament and of the Council of 11 March 1996 on the legal
protection of databases, and under any national implementation
thereof, including any amended or successor version of such
directive); and
vii. other similar, equivalent or corresponding rights throughout the
world based on applicable law or treaty, and any national
implementations thereof.
2. Waiver. To the greatest extent permitted by, but not in contravention
of, applicable law, Affirmer hereby overtly, fully, permanently,
irrevocably and unconditionally waives, abandons, and surrenders all of
Affirmer's Copyright and Related Rights and associated claims and causes
of action, whether now known or unknown (including existing as well as
future claims and causes of action), in the Work (i) in all territories
worldwide, (ii) for the maximum duration provided by applicable law or
treaty (including future time extensions), (iii) in any current or future
medium and for any number of copies, and (iv) for any purpose whatsoever,
including without limitation commercial, advertising or promotional
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
member of the public at large and to the detriment of Affirmer's heirs and
successors, fully intending that such Waiver shall not be subject to
revocation, rescission, cancellation, termination, or any other legal or
equitable action to disrupt the quiet enjoyment of the Work by the public
as contemplated by Affirmer's express Statement of Purpose.
3. Public License Fallback. Should any part of the Waiver for any reason
be judged legally invalid or ineffective under applicable law, then the
Waiver shall be preserved to the maximum extent permitted taking into
account Affirmer's express Statement of Purpose. In addition, to the
extent the Waiver is so judged Affirmer hereby grants to each affected
person a royalty-free, non transferable, non sublicensable, non exclusive,
irrevocable and unconditional license to exercise Affirmer's Copyright and
Related Rights in the Work (i) in all territories worldwide, (ii) for the
maximum duration provided by applicable law or treaty (including future
time extensions), (iii) in any current or future medium and for any number
of copies, and (iv) for any purpose whatsoever, including without
limitation commercial, advertising or promotional purposes (the
"License"). The License shall be deemed effective as of the date CC0 was
applied by Affirmer to the Work. Should any part of the License for any
reason be judged legally invalid or ineffective under applicable law, such
partial invalidity or ineffectiveness shall not invalidate the remainder
of the License, and in such case Affirmer hereby affirms that he or she
will not (i) exercise any of his or her remaining Copyright and Related
Rights in the Work or (ii) assert any associated claims and causes of
action with respect to the Work, in either case contrary to Affirmer's
express Statement of Purpose.
4. Limitations and Disclaimers.
a. No trademark or patent rights held by Affirmer are waived, abandoned,
surrendered, licensed or otherwise affected by this document.
b. Affirmer offers the Work as-is and makes no representations or
warranties of any kind concerning the Work, express, implied,
statutory or otherwise, including without limitation warranties of
title, merchantability, fitness for a particular purpose, non
infringement, or the absence of latent or other defects, accuracy, or
the present or absence of errors, whether or not discoverable, all to
the greatest extent permissible under applicable law.
c. Affirmer disclaims responsibility for clearing rights of other persons
that may apply to the Work or any use thereof, including without
limitation any person's Copyright and Related Rights in the Work.
Further, Affirmer disclaims responsibility for obtaining any necessary
consents, permissions or other rights required for any use of the
Work.
d. Affirmer understands and acknowledges that Creative Commons is not a
party to this document and has no duty or obligation with respect to
this CC0 or use of the Work.
-8
View File
@@ -1,8 +0,0 @@
default:
cd build && $(MAKE)
install:
cd build && $(MAKE) install
clean:
cd build && $(MAKE) clean
-28
View File
@@ -1,28 +0,0 @@
lib25519 is a microlibrary for the X25519 encryption system and the
Ed25519 signature system, both of which use the Curve25519 elliptic
curve. Curve25519 is the fastest curve in TLS 1.3, and the only curve in
Wireguard, Signal, and many other applications (see Nicolai Brown's page
https://ianix.com/pub/curve25519-deployment.html).
lib25519 has a very simple stateless API based on the SUPERCOP API, with
wire-format inputs and outputs, providing functions that directly match
the central cryptographic operations in X25519 and Ed25519:
lib25519_dh_keypair(pk,sk): X25519 key generation
lib25519_dh(k,pk,sk): shared-secret generation
lib25519_sign_keypair(pk,sk): Ed25519 key generation
lib25519_sign(sm,&smlen,m,mlen,sk): signing
lib25519_sign_open(m,&mlen,sm,smlen,pk): verification + message recovery
Internally, lib25519 includes implementations designed for performance
on various CPUs, implementations designed to work portably across CPUs,
and automatic run-time selection of implementations.
lib25519 is intended to be called by larger multi-function libraries,
including libraries in other languages via FFI. The idea is that
lib25519 will take responsibility for the details of X25519/Ed25519
computation, including optimization, timing-attack protection, and
eventually verification, freeing up the calling libraries to concentrate
on application-specific needs such as protocol integration. Applications
can also call lib25519 directly.
-87
View File
@@ -1,87 +0,0 @@
Security model: X25519 is designed to be strong as a component of
various well-known "hashed DH" applications, and in particular is
designed to make the CDH problem difficult with respect to the standard
base. Ed25519 is designed to provide EUF-CMA, the standard notion of
unforgeability of a signature system under chosen-message attacks.
However, some applications need other security notions that are not
provided by X25519 and Ed25519.
Security level: X25519 and Ed25519 are more difficult to break by any
known attacks than a typical 128-bit cipher. They have an extremely
stable security track record, with two decades of research changing
security levels by only a fraction of a bit. They also proactively avoid
various potential risks. However, large quantum computers will break
both X25519 and Ed25519.
Software verification: lib25519 is intended to become a central target
for verification of full functional correctness of implementations of
X25519 and Ed25519. However, only certain portions have been verified so
far, and at this point the code should be presumed to have critical
bugs.
Timing attacks: lib25519 is designed to avoid all data flow from secret
data to memory addresses and branch conditions. Fully protecting the
user against timing attacks requires addressing more issues, such as the
following:
* Other common instructions used by lib25519 take variable time on
some CPUs. In particular, there are some embedded CPUs with
variable-time multipliers.
* Many CPUs include dynamic frequency-selection mechanisms such as
Turbo Boost, exposing power information via timing information.
Fortunately, these CPUs are normally shipped with simple options to
disable Turbo Boost etc., closing this leak; unfortunately, Turbo
Boost is enabled by default on CPUs that support it.
* Cryptographic keys are normally handled by cryptographic software,
but other user secrets are handled by many different pieces of
software.
See https://timing.attacks.cr.yp.to for a timing-attack survey and many
references.
Speculative-execution attacks: Some countermeasures against
speculative-execution attacks are planned but are not included in the
current version of lib25519. Full protection again requires addressing
issues at other system layers.
Further side-channel attacks: Even if all legitimate user sensors are
successfully kept isolated from attackers, attackers can set up their
own power sensors, electromagnetic sensors, acoustic sensors, etc.
Keeping cryptographic operations physically separated from sensors tends
to make such attacks much more expensive but is often infeasible.
"Masking" cryptographic computations seems to help and can be
affordable, although the security of masking is difficult to evaluate
and there are many broken masked implementations. Currently lib25519
does not include any masked implementations, so presumably it is easily
breakable by power attacks in environments where attackers can see power
consumption.
Further attacks: lib25519 creates an Ed25519 signing nonce as a hash of
the message, a long-term secret, and new randomness (specifically, the
nonce is a keyed hash of the message, where the key is the hash of the
long-term secret and new randomness). The literature identifies various
advantages and disadvantages of including these hash inputs:
* Including the message and a long-term secret protects against
signing-time RNG failures. This is a standard feature of Ed25519
signers.
* To the extent that the RNG works, including new randomness has the
advantage of stopping (e.g.) fault attacks that rely on a nonce
being reused for multiple signatures of the same message.
* Including new randomness has the disadvantage of requiring state
for the RNG. However, lib25519 runs within an OS that in any case
maintains state and provides an RNG.
* Including new randomness also has the disadvantage of interfering
with the use of test vectors. This disadvantage does not apply to
lib25519: lib25519's test vectors already handle randomness.
lib25519 includes a few further steps that could be useful in stopping
fault attacks (for example, signature verification internally converts
invalid public keys to the key (...,26), which does not have a known
discrete logarithm), but in general lib25519 should be presumed
breakable by fault attacks.
-17
View File
@@ -1,17 +0,0 @@
track history more precisely in documentation for individual source files
consider symlinks from files in build tree to source tree (via a build/source symlink so build can link elsewhere)
allow shared-* for API functions (requires tweaking dispatch)
speedups for more architectures
speedups for more microarchitectures
consider faster PRF for the keyed hash giving the nonce
merge subroutines in source to the extent possible
scan for and remove any unused functions and files
restructure for more merging at object-code level
sort object files (for, e.g., improved cache utilization)
optionally allow post-installation patching of current cpu as an exceptional cpuid
(based on benchmarks and, with more CPU time, full functionality tests)
dispatch: eliminate, e.g., avx2 if avx is higher priority
speed up dispatch cpuid tests (lazy evaluation, merging cpuid calls)
randombytes: support getrandom, getentropy
verify constbranch, constindex
full functional verification
-51
View File
@@ -1,51 +0,0 @@
crypto_verify/32
#define crypto_verify_32_BYTES 32
int crypto_verify(const unsigned char *,const unsigned char *);
crypto_hashblocks/sha512 f0bc623a9033f9f648336540e11e85be21aeb60905c7d8808d10ea20b39d58d1 f1a2c46c9ce7fa4cd22f180907d77b6f7189badef4b9a1b5284d6fb9db859b76
#define crypto_hashblocks_sha512_STATEBYTES 64
#define crypto_hashblocks_sha512_BLOCKBYTES 128
int crypto_hashblocks(unsigned char *,const unsigned char *,long long);
crypto_hash/sha512 8220572f58bd4730be165c9739d8d4b0fd2e0229dbe01e25b4aed23f00f23b70 c1e322b7cbfc941260c5508967ba05bce22eeee94d425e708b7c3301ea1d5e2e
#define crypto_hash_sha512_BYTES 64
void crypto_hash(unsigned char *,const unsigned char *,long long);
crypto_pow/inv25519 ad2062946e82718da820226504991a85c5fe56bdbff959c1313f837ee13b37be 59b3045a01e1fca2a86a0280aee8b985c5e040afdc0d3e85ed87eb97a46a4dd6
#define crypto_pow_inv25519_BYTES 32
void crypto_pow(unsigned char *,const unsigned char *);
crypto_nP/montgomery25519 b861d66109b42359e5994ed57ae566827c345b65a9d0671700320b82888397ec 740924011f3448f65299f61b087f74a6eb9651a4203dfbf621d2bec54e149405
#define crypto_nP_montgomery25519_SCALARBYTES 32
#define crypto_nP_montgomery25519_POINTBYTES 32
void crypto_nP(unsigned char *,const unsigned char *,const unsigned char *);
crypto_nG/merged25519 a4e761839798a07817484e97605bd63215b4938934ed9ce01935bbced48155bc 0a01c09fc8a8c7e8c18f841b2e1b2da9c156868737d194d223b03531cf2db731
#define crypto_nG_merged25519_SCALARBYTES 32
#define crypto_nG_merged25519_POINTBYTES 32
crypto_nG/montgomery25519 5c8a5d8b32e3d26b33071779ce9191095d7bd4ab3bb6a40b68976e41a98cfc3b 2becc8cd065820fcf82e53a03c5b5235582480fc11d072f2bd15153aebd4e057
#define crypto_nG_montgomery25519_SCALARBYTES 32
#define crypto_nG_montgomery25519_POINTBYTES 32
void crypto_nG(unsigned char *,const unsigned char *);
crypto_mGnP/ed25519 dc80be44fb0d482c5ae430779e76fe612c53fcd9e5847254bf27ab34e90745f4 9e1a3b7015c8fdb12763fd88494f5bfe9e2565ead4d3407d5ecf7ff6ca24c1d0
#define crypto_mGnP_ed25519_MBYTES 32
#define crypto_mGnP_ed25519_NBYTES 64
#define crypto_mGnP_ed25519_PBYTES 32
#define crypto_mGnP_ed25519_OUTPUTBYTES 33
void crypto_mGnP(unsigned char *,const unsigned char *,const unsigned char *,const unsigned char *);
crypto_dh/x25519 2c8a73ec86d5d4c4bc838f49cfd78c87b60b534ae6fff59ce3bea0c32cdc1450 b09016b3a1371786b46a183085133338159e623c5eb9cbc5eaa4f8b62d6c5aea
#define crypto_dh_x25519_SECRETKEYBYTES 32
#define crypto_dh_x25519_PUBLICKEYBYTES 32
#define crypto_dh_x25519_BYTES 32
void crypto_dh_keypair(unsigned char *,unsigned char *);
void crypto_dh(unsigned char *,const unsigned char *,const unsigned char *);
crypto_sign/ed25519 ce11fd7c1eac4dd0bc5eec49b26ad1e91aef696fae50ce377dbd806dc394da01 2ed857f17c917a8185e6c296303a11772ae45683a5e7cb5b095489bad65fffde
#define crypto_sign_ed25519_SECRETKEYBYTES 64
#define crypto_sign_ed25519_PUBLICKEYBYTES 32
#define crypto_sign_ed25519_BYTES 64
void crypto_sign_keypair(unsigned char *,unsigned char *);
void crypto_sign(unsigned char *,long long *,const unsigned char *,long long,const unsigned char *);
int crypto_sign_open(unsigned char *,long long *,const unsigned char *,long long,const unsigned char *);
-338
View File
@@ -1,338 +0,0 @@
#!/usr/bin/env python3
output = r'''/* WARNING: auto-generated (by autogen-speed); do not edit */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <time.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/resource.h>
#include "cpucycles.h" /* -lcpucycles */
#include "lib25519.h" /* -l25519 */
#include "randombytes.h" /* -lrandombytes_kernel */
static const char *targeto = 0;
static const char *targetp = 0;
static const char *targeti = 0;
#include "limits.inc"
static unsigned char *alignedcalloc(unsigned long long len)
{
unsigned char *x = (unsigned char *) calloc(1,len + 128);
if (!x) abort();
/* will never deallocate so shifting is ok */
x += 63 & (-(unsigned long) x);
return x;
}
#define TIMINGS 15
static long long t[TIMINGS+1];
static void t_print(const char *op,long long impl,long long len)
{
long long median = 0;
printf("%s",op);
if (impl >= 0)
printf(" %lld",impl);
else
printf(" selected");
printf(" %lld",len);
for (long long i = 0;i < TIMINGS;++i)
t[i] = t[i+1]-t[i];
for (long long j = 0;j < TIMINGS;++j) {
long long belowj = 0;
long long abovej = 0;
for (long long i = 0;i < TIMINGS;++i) if (t[i] < t[j]) ++belowj;
for (long long i = 0;i < TIMINGS;++i) if (t[i] > t[j]) ++abovej;
if (belowj*2 < TIMINGS && abovej*2 < TIMINGS) {
median = t[j];
break;
}
}
printf(" %lld ",median);
for (long long i = 0;i < TIMINGS;++i)
printf("%+lld",t[i]-median);
printf("\n");
fflush(stdout);
}
#define MAXTEST_BYTES 65536
static void measure_cpucycles(void)
{
printf("cpucycles selected persecond %lld\n",cpucycles_persecond());
printf("cpucycles selected implementation %s\n",cpucycles_implementation());
for (long long i = 0;i <= TIMINGS;++i)
t[i] = cpucycles();
t_print("cpucycles",-1,0);
}
static void measure_randombytes(void)
{
unsigned char *m = alignedcalloc(MAXTEST_BYTES);
long long mlen = 0;
while (mlen < MAXTEST_BYTES) {
for (long long i = 0;i <= TIMINGS;++i) {
t[i] = cpucycles();
randombytes(m,mlen);
}
t_print("randombytes",-1,mlen);
mlen += 1+mlen/2;
}
}
'''
# XXX: integrate todo into api
todo = (
('verify',(
('x','lib25519_verify_BYTES'),
('y','lib25519_verify_BYTES'),
),(
('crypto_verify','x','y'),
)),
('hashblocks',(
('h','lib25519_hashblocks_STATEBYTES'),
('m','MAXTEST_BYTES'),
('mlen',None),
),(
('crypto_hashblocks','h','m','mlen'),
)),
('hash',(
('h','lib25519_hash_BYTES'),
('m','MAXTEST_BYTES'),
('mlen',None),
),(
('crypto_hash','h','m','mlen'),
)),
('pow',(
('n','lib25519_pow_BYTES'),
('ne','lib25519_pow_BYTES'),
),(
('crypto_pow','ne','n'),
)),
('nP',(
('n','lib25519_nP_SCALARBYTES'),
('P','lib25519_nP_POINTBYTES'),
('nP','lib25519_nP_POINTBYTES'),
),(
('crypto_nP','nP','n','P'),
)),
('nG',(
('n','lib25519_nP_SCALARBYTES'),
('nG','lib25519_nP_POINTBYTES'),
),(
('crypto_nG','nG','n'),
)),
('mGnP',(
('mGnP','lib25519_mGnP_OUTPUTBYTES'),
('m','lib25519_mGnP_MBYTES'),
('n','lib25519_mGnP_NBYTES'),
('P','lib25519_mGnP_PBYTES'),
),(
('crypto_mGnP','mGnP','m','n','P'),
)),
('dh',(
('pka','lib25519_dh_PUBLICKEYBYTES'),
('ska','lib25519_dh_SECRETKEYBYTES'),
('pkb','lib25519_dh_PUBLICKEYBYTES'),
('skb','lib25519_dh_SECRETKEYBYTES'),
('ka','lib25519_dh_BYTES'),
),(
('crypto_dh_keypair','pka','ska'),
('crypto_dh_keypair','pkb','skb'),
('crypto_dh','ka','pkb','ska'),
)),
('sign',(
('pk','lib25519_sign_PUBLICKEYBYTES'),
('sk','lib25519_sign_SECRETKEYBYTES'),
('m','MAXTEST_BYTES+lib25519_sign_BYTES'),
('sm','MAXTEST_BYTES+lib25519_sign_BYTES'),
('m2','MAXTEST_BYTES+lib25519_sign_BYTES'),
('mlen',None),
('smlen',None),
('m2len',None),
),(
('crypto_sign_keypair','pk','sk'),
('crypto_sign','sm','&smlen','m','mlen','sk'),
('crypto_sign_open','m2','&m2len','sm','smlen','pk'),
)),
)
operations = []
primitives = {}
sizes = {}
exports = {}
prototypes = {}
with open('api') as f:
for line in f:
line = line.strip()
if line.startswith('crypto_'):
x = line.split()
x = x[0].split('/')
assert len(x) == 2
o = x[0].split('_')[1]
if o not in operations: operations += [o]
p = x[1]
if o not in primitives: primitives[o] = []
primitives[o] += [p]
continue
if line.startswith('#define '):
x = line.split(' ')
x = x[1].split('_')
assert len(x) == 4
assert x[0] == 'crypto'
o = x[1]
p = x[2]
if (o,p) not in sizes: sizes[o,p] = ''
sizes[o,p] += line+'\n'
continue
if line.endswith(');'):
fun,args = line[:-2].split('(')
rettype,fun = fun.split()
fun = fun.split('_')
o = fun[1]
assert fun[0] == 'crypto'
if o not in exports: exports[o] = []
exports[o] += ['_'.join(fun[1:])]
if o not in prototypes: prototypes[o] = []
prototypes[o] += [(rettype,fun,args)]
for t in todo:
o,vars,benches = t
for p in primitives[o]:
output += '\n'
output += 'static void measure_%s_%s(void)\n' % (o,p)
output += '{\n'
output += ' if (targeto && strcmp(targeto,"%s")) return;\n' % o
output += ' if (targetp && strcmp(targetp,"%s")) return;\n' % p
varsize = {}
for v,size in vars:
if size is None:
output += ' long long %s;\n' % v
else:
size = size.replace('lib25519_'+o,'lib25519_'+o+'_'+p)
output += ' unsigned char *%s = alignedcalloc(%s);\n' % (v,size)
varsize[v] = size
output += '\n'
output += ' for (long long impl = -1;impl < lib25519_numimpl_%s_%s();++impl) {\n' % (o,p)
for rettype,fun,args in prototypes[o]:
output += ' %s (*%s)(%s);\n' % (rettype,'_'.join(fun),args)
output += ' if (targeti && strcmp(targeti,lib25519_dispatch_%s_%s_implementation(impl))) continue;\n' % (o,p)
output += ' if (impl >= 0) {\n'
for rettype,fun,args in prototypes[o]:
f2 = ['lib25519','dispatch',o,p]+fun[2:]
output += ' %s = %s(impl);\n' % ('_'.join(fun),'_'.join(f2))
output += r' printf("%s_%s %%lld implementation %%s compiler %%s\n",impl,lib25519_dispatch_%s_%s_implementation(impl),lib25519_dispatch_%s_%s_compiler(impl));' % (o,p,o,p,o,p)
output += '\n'
output += ' } else {\n'
for rettype,fun,args in prototypes[o]:
f2 = ['lib25519',o,p]+fun[2:]
output += ' %s = %s;\n' % ('_'.join(fun),'_'.join(f2))
output += r' printf("%s_%s selected implementation %%s compiler %%s\n",lib25519_%s_%s_implementation(),lib25519_%s_%s_compiler());' % (o,p,o,p,o,p)
output += '\n'
output += ' }\n'
for v,size in vars:
if size is not None:
size = size.replace('lib25519_'+o,'lib25519_'+o+'_'+p)
output += ' randombytes(%s,%s);\n' % (v,size)
alreadybenched = set()
alreadybenched.add('assert')
for b in benches:
if b[0] in alreadybenched:
output += ' %s(%s);\n' % (b[0],','.join(b[1:]))
continue
fun = b[0].split('_')
shortfun = '_'.join([o,p]+fun[2:])
alreadybenched.add(b[0])
if 'mlen' in b[1:] or 'smlen' in b[1:]:
output += ' mlen = 0;\n'
output += ' while (mlen <= MAXTEST_BYTES) {\n'
output += ' randombytes(m,mlen);\n'
if shortfun == 'sign_ed25519_open': # XXX: put this into todo
output += ' lib25519_sign(sm,&smlen,m,mlen,sk);\n'
output += ' for (long long i = 0;i <= TIMINGS;++i) {\n'
output += ' t[i] = cpucycles();\n'
output += ' %s(%s);\n' % (b[0],','.join(b[1:]))
output += ' }\n'
output += ' t_print("%s",impl,mlen);\n' % (shortfun)
if shortfun == 'sign_ed25519_open': # XXX: put this into todo
output += ' /* this is, in principle, not a test program */\n'
output += ' /* but some checks here help validate the data flow above */\n'
output += ' assert(m2len == mlen);\n'
output += ' assert(!memcmp(m,m2,mlen));\n'
if o == 'sign': # XXX: put this into todo
output += ' mlen += 1+mlen/4;\n'
else:
output += ' mlen += 1+mlen/2;\n'
output += ' }\n'
else:
output += ' for (long long i = 0;i <= TIMINGS;++i) {\n'
output += ' t[i] = cpucycles();\n'
output += ' %s(%s);\n' % (b[0],','.join(b[1:]))
output += ' }\n'
output += ' t_print("%s",impl,%s);\n' % (shortfun,varsize[b[1]])
output += ' }\n'
output += '}\n'
output += r'''
#include "print_cpuid.inc"
int main(int argc,char **argv)
{
printf("lib25519 version %s\n",lib25519_version);
printf("lib25519 arch %s\n",lib25519_arch);
print_cpuid();
if (*argv) ++argv;
if (*argv) {
targeto = *argv++;
if (*argv) {
targetp = *argv++;
if (*argv) {
targeti = *argv++;
}
}
}
measure_cpucycles();
measure_randombytes();
limits();
'''
for t in todo:
o,vars,benches = t
for p in primitives[o]:
output += ' measure_%s_%s();\n' % (o,p)
output += r'''
return 0;
}
'''
with open('command/lib25519-speed.c','w') as f:
f.write(output)
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
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
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
-466
View File
@@ -1,466 +0,0 @@
/* WARNING: auto-generated (by autogen-speed); do not edit */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <time.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/resource.h>
#include "cpucycles.h" /* -lcpucycles */
#include "lib25519.h" /* -l25519 */
#include "randombytes.h" /* -lrandombytes_kernel */
static const char *targeto = 0;
static const char *targetp = 0;
static const char *targeti = 0;
#include "limits.inc"
static unsigned char *alignedcalloc(unsigned long long len)
{
unsigned char *x = (unsigned char *) calloc(1,len + 128);
if (!x) abort();
/* will never deallocate so shifting is ok */
x += 63 & (-(unsigned long) x);
return x;
}
#define TIMINGS 15
static long long t[TIMINGS+1];
static void t_print(const char *op,long long impl,long long len)
{
long long median = 0;
printf("%s",op);
if (impl >= 0)
printf(" %lld",impl);
else
printf(" selected");
printf(" %lld",len);
for (long long i = 0;i < TIMINGS;++i)
t[i] = t[i+1]-t[i];
for (long long j = 0;j < TIMINGS;++j) {
long long belowj = 0;
long long abovej = 0;
for (long long i = 0;i < TIMINGS;++i) if (t[i] < t[j]) ++belowj;
for (long long i = 0;i < TIMINGS;++i) if (t[i] > t[j]) ++abovej;
if (belowj*2 < TIMINGS && abovej*2 < TIMINGS) {
median = t[j];
break;
}
}
printf(" %lld ",median);
for (long long i = 0;i < TIMINGS;++i)
printf("%+lld",t[i]-median);
printf("\n");
fflush(stdout);
}
#define MAXTEST_BYTES 65536
static void measure_cpucycles(void)
{
printf("cpucycles selected persecond %lld\n",cpucycles_persecond());
printf("cpucycles selected implementation %s\n",cpucycles_implementation());
for (long long i = 0;i <= TIMINGS;++i)
t[i] = cpucycles();
t_print("cpucycles",-1,0);
}
static void measure_randombytes(void)
{
unsigned char *m = alignedcalloc(MAXTEST_BYTES);
long long mlen = 0;
while (mlen < MAXTEST_BYTES) {
for (long long i = 0;i <= TIMINGS;++i) {
t[i] = cpucycles();
randombytes(m,mlen);
}
t_print("randombytes",-1,mlen);
mlen += 1+mlen/2;
}
}
static void measure_verify_32(void)
{
if (targeto && strcmp(targeto,"verify")) return;
if (targetp && strcmp(targetp,"32")) return;
unsigned char *x = alignedcalloc(lib25519_verify_32_BYTES);
unsigned char *y = alignedcalloc(lib25519_verify_32_BYTES);
for (long long impl = -1;impl < lib25519_numimpl_verify_32();++impl) {
int (*crypto_verify)(const unsigned char *,const unsigned char *);
if (targeti && strcmp(targeti,lib25519_dispatch_verify_32_implementation(impl))) continue;
if (impl >= 0) {
crypto_verify = lib25519_dispatch_verify_32(impl);
printf("verify_32 %lld implementation %s compiler %s\n",impl,lib25519_dispatch_verify_32_implementation(impl),lib25519_dispatch_verify_32_compiler(impl));
} else {
crypto_verify = lib25519_verify_32;
printf("verify_32 selected implementation %s compiler %s\n",lib25519_verify_32_implementation(),lib25519_verify_32_compiler());
}
randombytes(x,lib25519_verify_32_BYTES);
randombytes(y,lib25519_verify_32_BYTES);
for (long long i = 0;i <= TIMINGS;++i) {
t[i] = cpucycles();
crypto_verify(x,y);
}
t_print("verify_32",impl,lib25519_verify_32_BYTES);
}
}
static void measure_hashblocks_sha512(void)
{
if (targeto && strcmp(targeto,"hashblocks")) return;
if (targetp && strcmp(targetp,"sha512")) return;
unsigned char *h = alignedcalloc(lib25519_hashblocks_sha512_STATEBYTES);
unsigned char *m = alignedcalloc(MAXTEST_BYTES);
long long mlen;
for (long long impl = -1;impl < lib25519_numimpl_hashblocks_sha512();++impl) {
int (*crypto_hashblocks)(unsigned char *,const unsigned char *,long long);
if (targeti && strcmp(targeti,lib25519_dispatch_hashblocks_sha512_implementation(impl))) continue;
if (impl >= 0) {
crypto_hashblocks = lib25519_dispatch_hashblocks_sha512(impl);
printf("hashblocks_sha512 %lld implementation %s compiler %s\n",impl,lib25519_dispatch_hashblocks_sha512_implementation(impl),lib25519_dispatch_hashblocks_sha512_compiler(impl));
} else {
crypto_hashblocks = lib25519_hashblocks_sha512;
printf("hashblocks_sha512 selected implementation %s compiler %s\n",lib25519_hashblocks_sha512_implementation(),lib25519_hashblocks_sha512_compiler());
}
randombytes(h,lib25519_hashblocks_sha512_STATEBYTES);
randombytes(m,MAXTEST_BYTES);
mlen = 0;
while (mlen <= MAXTEST_BYTES) {
randombytes(m,mlen);
for (long long i = 0;i <= TIMINGS;++i) {
t[i] = cpucycles();
crypto_hashblocks(h,m,mlen);
}
t_print("hashblocks_sha512",impl,mlen);
mlen += 1+mlen/2;
}
}
}
static void measure_hash_sha512(void)
{
if (targeto && strcmp(targeto,"hash")) return;
if (targetp && strcmp(targetp,"sha512")) return;
unsigned char *h = alignedcalloc(lib25519_hash_sha512_BYTES);
unsigned char *m = alignedcalloc(MAXTEST_BYTES);
long long mlen;
for (long long impl = -1;impl < lib25519_numimpl_hash_sha512();++impl) {
void (*crypto_hash)(unsigned char *,const unsigned char *,long long);
if (targeti && strcmp(targeti,lib25519_dispatch_hash_sha512_implementation(impl))) continue;
if (impl >= 0) {
crypto_hash = lib25519_dispatch_hash_sha512(impl);
printf("hash_sha512 %lld implementation %s compiler %s\n",impl,lib25519_dispatch_hash_sha512_implementation(impl),lib25519_dispatch_hash_sha512_compiler(impl));
} else {
crypto_hash = lib25519_hash_sha512;
printf("hash_sha512 selected implementation %s compiler %s\n",lib25519_hash_sha512_implementation(),lib25519_hash_sha512_compiler());
}
randombytes(h,lib25519_hash_sha512_BYTES);
randombytes(m,MAXTEST_BYTES);
mlen = 0;
while (mlen <= MAXTEST_BYTES) {
randombytes(m,mlen);
for (long long i = 0;i <= TIMINGS;++i) {
t[i] = cpucycles();
crypto_hash(h,m,mlen);
}
t_print("hash_sha512",impl,mlen);
mlen += 1+mlen/2;
}
}
}
static void measure_pow_inv25519(void)
{
if (targeto && strcmp(targeto,"pow")) return;
if (targetp && strcmp(targetp,"inv25519")) return;
unsigned char *n = alignedcalloc(lib25519_pow_inv25519_BYTES);
unsigned char *ne = alignedcalloc(lib25519_pow_inv25519_BYTES);
for (long long impl = -1;impl < lib25519_numimpl_pow_inv25519();++impl) {
void (*crypto_pow)(unsigned char *,const unsigned char *);
if (targeti && strcmp(targeti,lib25519_dispatch_pow_inv25519_implementation(impl))) continue;
if (impl >= 0) {
crypto_pow = lib25519_dispatch_pow_inv25519(impl);
printf("pow_inv25519 %lld implementation %s compiler %s\n",impl,lib25519_dispatch_pow_inv25519_implementation(impl),lib25519_dispatch_pow_inv25519_compiler(impl));
} else {
crypto_pow = lib25519_pow_inv25519;
printf("pow_inv25519 selected implementation %s compiler %s\n",lib25519_pow_inv25519_implementation(),lib25519_pow_inv25519_compiler());
}
randombytes(n,lib25519_pow_inv25519_BYTES);
randombytes(ne,lib25519_pow_inv25519_BYTES);
for (long long i = 0;i <= TIMINGS;++i) {
t[i] = cpucycles();
crypto_pow(ne,n);
}
t_print("pow_inv25519",impl,lib25519_pow_inv25519_BYTES);
}
}
static void measure_nP_montgomery25519(void)
{
if (targeto && strcmp(targeto,"nP")) return;
if (targetp && strcmp(targetp,"montgomery25519")) return;
unsigned char *n = alignedcalloc(lib25519_nP_montgomery25519_SCALARBYTES);
unsigned char *P = alignedcalloc(lib25519_nP_montgomery25519_POINTBYTES);
unsigned char *nP = alignedcalloc(lib25519_nP_montgomery25519_POINTBYTES);
for (long long impl = -1;impl < lib25519_numimpl_nP_montgomery25519();++impl) {
void (*crypto_nP)(unsigned char *,const unsigned char *,const unsigned char *);
if (targeti && strcmp(targeti,lib25519_dispatch_nP_montgomery25519_implementation(impl))) continue;
if (impl >= 0) {
crypto_nP = lib25519_dispatch_nP_montgomery25519(impl);
printf("nP_montgomery25519 %lld implementation %s compiler %s\n",impl,lib25519_dispatch_nP_montgomery25519_implementation(impl),lib25519_dispatch_nP_montgomery25519_compiler(impl));
} else {
crypto_nP = lib25519_nP_montgomery25519;
printf("nP_montgomery25519 selected implementation %s compiler %s\n",lib25519_nP_montgomery25519_implementation(),lib25519_nP_montgomery25519_compiler());
}
randombytes(n,lib25519_nP_montgomery25519_SCALARBYTES);
randombytes(P,lib25519_nP_montgomery25519_POINTBYTES);
randombytes(nP,lib25519_nP_montgomery25519_POINTBYTES);
for (long long i = 0;i <= TIMINGS;++i) {
t[i] = cpucycles();
crypto_nP(nP,n,P);
}
t_print("nP_montgomery25519",impl,lib25519_nP_montgomery25519_POINTBYTES);
}
}
static void measure_nG_merged25519(void)
{
if (targeto && strcmp(targeto,"nG")) return;
if (targetp && strcmp(targetp,"merged25519")) return;
unsigned char *n = alignedcalloc(lib25519_nP_SCALARBYTES);
unsigned char *nG = alignedcalloc(lib25519_nP_POINTBYTES);
for (long long impl = -1;impl < lib25519_numimpl_nG_merged25519();++impl) {
void (*crypto_nG)(unsigned char *,const unsigned char *);
if (targeti && strcmp(targeti,lib25519_dispatch_nG_merged25519_implementation(impl))) continue;
if (impl >= 0) {
crypto_nG = lib25519_dispatch_nG_merged25519(impl);
printf("nG_merged25519 %lld implementation %s compiler %s\n",impl,lib25519_dispatch_nG_merged25519_implementation(impl),lib25519_dispatch_nG_merged25519_compiler(impl));
} else {
crypto_nG = lib25519_nG_merged25519;
printf("nG_merged25519 selected implementation %s compiler %s\n",lib25519_nG_merged25519_implementation(),lib25519_nG_merged25519_compiler());
}
randombytes(n,lib25519_nP_SCALARBYTES);
randombytes(nG,lib25519_nP_POINTBYTES);
for (long long i = 0;i <= TIMINGS;++i) {
t[i] = cpucycles();
crypto_nG(nG,n);
}
t_print("nG_merged25519",impl,lib25519_nP_POINTBYTES);
}
}
static void measure_nG_montgomery25519(void)
{
if (targeto && strcmp(targeto,"nG")) return;
if (targetp && strcmp(targetp,"montgomery25519")) return;
unsigned char *n = alignedcalloc(lib25519_nP_SCALARBYTES);
unsigned char *nG = alignedcalloc(lib25519_nP_POINTBYTES);
for (long long impl = -1;impl < lib25519_numimpl_nG_montgomery25519();++impl) {
void (*crypto_nG)(unsigned char *,const unsigned char *);
if (targeti && strcmp(targeti,lib25519_dispatch_nG_montgomery25519_implementation(impl))) continue;
if (impl >= 0) {
crypto_nG = lib25519_dispatch_nG_montgomery25519(impl);
printf("nG_montgomery25519 %lld implementation %s compiler %s\n",impl,lib25519_dispatch_nG_montgomery25519_implementation(impl),lib25519_dispatch_nG_montgomery25519_compiler(impl));
} else {
crypto_nG = lib25519_nG_montgomery25519;
printf("nG_montgomery25519 selected implementation %s compiler %s\n",lib25519_nG_montgomery25519_implementation(),lib25519_nG_montgomery25519_compiler());
}
randombytes(n,lib25519_nP_SCALARBYTES);
randombytes(nG,lib25519_nP_POINTBYTES);
for (long long i = 0;i <= TIMINGS;++i) {
t[i] = cpucycles();
crypto_nG(nG,n);
}
t_print("nG_montgomery25519",impl,lib25519_nP_POINTBYTES);
}
}
static void measure_mGnP_ed25519(void)
{
if (targeto && strcmp(targeto,"mGnP")) return;
if (targetp && strcmp(targetp,"ed25519")) return;
unsigned char *mGnP = alignedcalloc(lib25519_mGnP_ed25519_OUTPUTBYTES);
unsigned char *m = alignedcalloc(lib25519_mGnP_ed25519_MBYTES);
unsigned char *n = alignedcalloc(lib25519_mGnP_ed25519_NBYTES);
unsigned char *P = alignedcalloc(lib25519_mGnP_ed25519_PBYTES);
for (long long impl = -1;impl < lib25519_numimpl_mGnP_ed25519();++impl) {
void (*crypto_mGnP)(unsigned char *,const unsigned char *,const unsigned char *,const unsigned char *);
if (targeti && strcmp(targeti,lib25519_dispatch_mGnP_ed25519_implementation(impl))) continue;
if (impl >= 0) {
crypto_mGnP = lib25519_dispatch_mGnP_ed25519(impl);
printf("mGnP_ed25519 %lld implementation %s compiler %s\n",impl,lib25519_dispatch_mGnP_ed25519_implementation(impl),lib25519_dispatch_mGnP_ed25519_compiler(impl));
} else {
crypto_mGnP = lib25519_mGnP_ed25519;
printf("mGnP_ed25519 selected implementation %s compiler %s\n",lib25519_mGnP_ed25519_implementation(),lib25519_mGnP_ed25519_compiler());
}
randombytes(mGnP,lib25519_mGnP_ed25519_OUTPUTBYTES);
randombytes(m,lib25519_mGnP_ed25519_MBYTES);
randombytes(n,lib25519_mGnP_ed25519_NBYTES);
randombytes(P,lib25519_mGnP_ed25519_PBYTES);
for (long long i = 0;i <= TIMINGS;++i) {
t[i] = cpucycles();
crypto_mGnP(mGnP,m,n,P);
}
t_print("mGnP_ed25519",impl,lib25519_mGnP_ed25519_OUTPUTBYTES);
}
}
static void measure_dh_x25519(void)
{
if (targeto && strcmp(targeto,"dh")) return;
if (targetp && strcmp(targetp,"x25519")) return;
unsigned char *pka = alignedcalloc(lib25519_dh_x25519_PUBLICKEYBYTES);
unsigned char *ska = alignedcalloc(lib25519_dh_x25519_SECRETKEYBYTES);
unsigned char *pkb = alignedcalloc(lib25519_dh_x25519_PUBLICKEYBYTES);
unsigned char *skb = alignedcalloc(lib25519_dh_x25519_SECRETKEYBYTES);
unsigned char *ka = alignedcalloc(lib25519_dh_x25519_BYTES);
for (long long impl = -1;impl < lib25519_numimpl_dh_x25519();++impl) {
void (*crypto_dh_keypair)(unsigned char *,unsigned char *);
void (*crypto_dh)(unsigned char *,const unsigned char *,const unsigned char *);
if (targeti && strcmp(targeti,lib25519_dispatch_dh_x25519_implementation(impl))) continue;
if (impl >= 0) {
crypto_dh_keypair = lib25519_dispatch_dh_x25519_keypair(impl);
crypto_dh = lib25519_dispatch_dh_x25519(impl);
printf("dh_x25519 %lld implementation %s compiler %s\n",impl,lib25519_dispatch_dh_x25519_implementation(impl),lib25519_dispatch_dh_x25519_compiler(impl));
} else {
crypto_dh_keypair = lib25519_dh_x25519_keypair;
crypto_dh = lib25519_dh_x25519;
printf("dh_x25519 selected implementation %s compiler %s\n",lib25519_dh_x25519_implementation(),lib25519_dh_x25519_compiler());
}
randombytes(pka,lib25519_dh_x25519_PUBLICKEYBYTES);
randombytes(ska,lib25519_dh_x25519_SECRETKEYBYTES);
randombytes(pkb,lib25519_dh_x25519_PUBLICKEYBYTES);
randombytes(skb,lib25519_dh_x25519_SECRETKEYBYTES);
randombytes(ka,lib25519_dh_x25519_BYTES);
for (long long i = 0;i <= TIMINGS;++i) {
t[i] = cpucycles();
crypto_dh_keypair(pka,ska);
}
t_print("dh_x25519_keypair",impl,lib25519_dh_x25519_PUBLICKEYBYTES);
crypto_dh_keypair(pkb,skb);
for (long long i = 0;i <= TIMINGS;++i) {
t[i] = cpucycles();
crypto_dh(ka,pkb,ska);
}
t_print("dh_x25519",impl,lib25519_dh_x25519_BYTES);
}
}
static void measure_sign_ed25519(void)
{
if (targeto && strcmp(targeto,"sign")) return;
if (targetp && strcmp(targetp,"ed25519")) return;
unsigned char *pk = alignedcalloc(lib25519_sign_ed25519_PUBLICKEYBYTES);
unsigned char *sk = alignedcalloc(lib25519_sign_ed25519_SECRETKEYBYTES);
unsigned char *m = alignedcalloc(MAXTEST_BYTES+lib25519_sign_ed25519_BYTES);
unsigned char *sm = alignedcalloc(MAXTEST_BYTES+lib25519_sign_ed25519_BYTES);
unsigned char *m2 = alignedcalloc(MAXTEST_BYTES+lib25519_sign_ed25519_BYTES);
long long mlen;
long long smlen;
long long m2len;
for (long long impl = -1;impl < lib25519_numimpl_sign_ed25519();++impl) {
void (*crypto_sign_keypair)(unsigned char *,unsigned char *);
void (*crypto_sign)(unsigned char *,long long *,const unsigned char *,long long,const unsigned char *);
int (*crypto_sign_open)(unsigned char *,long long *,const unsigned char *,long long,const unsigned char *);
if (targeti && strcmp(targeti,lib25519_dispatch_sign_ed25519_implementation(impl))) continue;
if (impl >= 0) {
crypto_sign_keypair = lib25519_dispatch_sign_ed25519_keypair(impl);
crypto_sign = lib25519_dispatch_sign_ed25519(impl);
crypto_sign_open = lib25519_dispatch_sign_ed25519_open(impl);
printf("sign_ed25519 %lld implementation %s compiler %s\n",impl,lib25519_dispatch_sign_ed25519_implementation(impl),lib25519_dispatch_sign_ed25519_compiler(impl));
} else {
crypto_sign_keypair = lib25519_sign_ed25519_keypair;
crypto_sign = lib25519_sign_ed25519;
crypto_sign_open = lib25519_sign_ed25519_open;
printf("sign_ed25519 selected implementation %s compiler %s\n",lib25519_sign_ed25519_implementation(),lib25519_sign_ed25519_compiler());
}
randombytes(pk,lib25519_sign_ed25519_PUBLICKEYBYTES);
randombytes(sk,lib25519_sign_ed25519_SECRETKEYBYTES);
randombytes(m,MAXTEST_BYTES+lib25519_sign_ed25519_BYTES);
randombytes(sm,MAXTEST_BYTES+lib25519_sign_ed25519_BYTES);
randombytes(m2,MAXTEST_BYTES+lib25519_sign_ed25519_BYTES);
for (long long i = 0;i <= TIMINGS;++i) {
t[i] = cpucycles();
crypto_sign_keypair(pk,sk);
}
t_print("sign_ed25519_keypair",impl,lib25519_sign_ed25519_PUBLICKEYBYTES);
mlen = 0;
while (mlen <= MAXTEST_BYTES) {
randombytes(m,mlen);
for (long long i = 0;i <= TIMINGS;++i) {
t[i] = cpucycles();
crypto_sign(sm,&smlen,m,mlen,sk);
}
t_print("sign_ed25519",impl,mlen);
mlen += 1+mlen/4;
}
mlen = 0;
while (mlen <= MAXTEST_BYTES) {
randombytes(m,mlen);
lib25519_sign(sm,&smlen,m,mlen,sk);
for (long long i = 0;i <= TIMINGS;++i) {
t[i] = cpucycles();
crypto_sign_open(m2,&m2len,sm,smlen,pk);
}
t_print("sign_ed25519_open",impl,mlen);
/* this is, in principle, not a test program */
/* but some checks here help validate the data flow above */
assert(m2len == mlen);
assert(!memcmp(m,m2,mlen));
mlen += 1+mlen/4;
}
}
}
#include "print_cpuid.inc"
int main(int argc,char **argv)
{
printf("lib25519 version %s\n",lib25519_version);
printf("lib25519 arch %s\n",lib25519_arch);
print_cpuid();
if (*argv) ++argv;
if (*argv) {
targeto = *argv++;
if (*argv) {
targetp = *argv++;
if (*argv) {
targeti = *argv++;
}
}
}
measure_cpucycles();
measure_randombytes();
limits();
measure_verify_32();
measure_hashblocks_sha512();
measure_hash_sha512();
measure_pow_inv25519();
measure_nP_montgomery25519();
measure_nG_merged25519();
measure_nG_montgomery25519();
measure_mGnP_ed25519();
measure_dh_x25519();
measure_sign_ed25519();
return 0;
}
File diff suppressed because it is too large Load Diff
-17
View File
@@ -1,17 +0,0 @@
static void limits()
{
#ifdef RLIM_INFINITY
struct rlimit r;
r.rlim_cur = 0;
r.rlim_max = 0;
#ifdef RLIMIT_NOFILE
setrlimit(RLIMIT_NOFILE,&r);
#endif
#ifdef RLIMIT_NPROC
setrlimit(RLIMIT_NPROC,&r);
#endif
#ifdef RLIMIT_CORE
setrlimit(RLIMIT_CORE,&r);
#endif
#endif
}
@@ -1,9 +0,0 @@
static void print_cpuid(void)
{
unsigned int cpuid[32];
lib25519_cpuid(cpuid,32);
printf("cpuid");
for (long long j = 0;j < 32;++j)
printf(" %08x",cpuid[j]);
printf("\n");
}
-2
View File
@@ -1,2 +0,0 @@
gcc -Wall -fPIC -fwrapv -O2 -mmmx -msse -msse2 -msse3 -mssse3 -msse4.1 -msse4.2 -mavx -mtune=sandybridge
clang -Wall -fPIC -fwrapv -Qunused-arguments -O2 -mmmx -msse -msse2 -msse3 -mssse3 -msse4.1 -msse4.2 -mavx -mtune=sandybridge
@@ -1,2 +0,0 @@
gcc -Wall -fPIC -fwrapv -O2 -mmmx -msse -msse2 -msse3 -mssse3 -msse4.1 -msse4.2 -mavx -mbmi -mbmi2 -mavx2 -mtune=haswell
clang -Wall -fPIC -fwrapv -Qunused-arguments -O2 -mmmx -msse -msse2 -msse3 -mssse3 -msse4.1 -msse4.2 -mavx -mbmi -mbmi2 -mavx2 -mtune=haswell
@@ -1,2 +0,0 @@
gcc -Wall -fPIC -fwrapv -O2 -mmmx -msse -msse2 -msse3 -mssse3 -msse4.1 -msse4.2 -mavx -mbmi -mbmi2 -mavx2 -madx -mtune=skylake
clang -Wall -fPIC -fwrapv -Qunused-arguments -O2 -mmmx -msse -msse2 -msse3 -mssse3 -msse4.1 -msse4.2 -mavx -mbmi -mbmi2 -mavx2 -madx -mtune=skylake
@@ -1,2 +0,0 @@
gcc -Wall -fPIC -fwrapv -O2 -mmmx -msse -msse2 -msse3 -mssse3 -msse4.1 -msse4.2 -mavx -mbmi -mbmi2 -mavx2 -madx -mavx512f -mavx512vl -mtune=skylake
clang -Wall -fPIC -fwrapv -Qunused-arguments -O2 -mmmx -msse -msse2 -msse3 -mssse3 -msse4.1 -msse4.2 -mavx -mbmi -mbmi2 -mavx2 -madx -mavx512f -mavx512vl -mtune=skylake
@@ -1,2 +0,0 @@
gcc -Wall -fPIC -fwrapv -O2 -mmmx -msse -msse2 -msse3 -mssse3 -msse4.1 -msse4.2 -mavx -mbmi -mbmi2 -mavx2 -madx -mavx512f -mavx512vl -mavx512ifma -mtune=skylake
clang -Wall -fPIC -fwrapv -Qunused-arguments -O2 -mmmx -msse -msse2 -msse3 -mssse3 -msse4.1 -msse4.2 -mavx -mbmi -mbmi2 -mavx2 -madx -mavx512f -mavx512vl -mavx512ifma -mtune=skylake
@@ -1,37 +0,0 @@
#define CPUID(func,leaf,a,b,c,d) \
__asm("cpuid":"=a"(a),"=b"(b),"=c"(c),"=d"(d):"a"(func),"c"(leaf):)
#define WANT_1_3 ((1<<23)|(1<<25)|(1<<26))
/* 23=mmx; 25=sse; 26=sse2 */
#define WANT_1_2 ((1<<0)|(1<<9)|(1<<19)|(1<<20)|(1<<27)|(1<<28))
/* 0=sse3; 9=ssse3; 19=sse41; 20=sse42; 27=osxsave; 28=avx */
#define WANT_7_1 ((1<<3)|(1<<5)|(1<<8)|(1<<16)|(1<<19)|(1<<21)|(1<<31))
/* 3=bmi1; 5=avx2; 8=bmi2; 16=avx512_f; 19=adx; 21=avx512_ifma; 31=avx512_vl */
#define WANT_XCR ((1<<1)|(1<<2))
/* 1=xmm; 2=ymm */
int supports(void)
{
unsigned int cpuidmax,id0,id1,id2;
unsigned int familymodelstepping;
unsigned int feature0,feature1,feature2,feature3;
unsigned int xcrlow,xcrhigh;
CPUID(0,0,cpuidmax,id0,id1,id2);
if (cpuidmax < 7) return 0;
CPUID(1,0,familymodelstepping,feature1,feature2,feature3);
if (WANT_1_2 != (WANT_1_2 & feature2)) return 0;
if (WANT_1_3 != (WANT_1_3 & feature3)) return 0;
CPUID(7,0,feature0,feature1,feature2,feature3);
if (WANT_7_1 != (WANT_7_1 & feature1)) return 0;
asm(".byte 15;.byte 1;.byte 208":"=a"(xcrlow),"=d"(xcrhigh):"c"(0));
if (WANT_XCR != (WANT_XCR & xcrlow)) return 0;
return 1;
}
@@ -1,37 +0,0 @@
#define CPUID(func,leaf,a,b,c,d) \
__asm("cpuid":"=a"(a),"=b"(b),"=c"(c),"=d"(d):"a"(func),"c"(leaf):)
#define WANT_1_3 ((1<<23)|(1<<25)|(1<<26))
/* 23=mmx; 25=sse; 26=sse2 */
#define WANT_1_2 ((1<<0)|(1<<9)|(1<<19)|(1<<20)|(1<<27)|(1<<28))
/* 0=sse3; 9=ssse3; 19=sse41; 20=sse42; 27=osxsave; 28=avx */
#define WANT_7_1 ((1<<3)|(1<<5)|(1<<8)|(1<<16)|(1<<19)|(1<<31))
/* 3=bmi1; 5=avx2; 8=bmi2; 16=avx512_f; 19=adx; 31=avx512_vl */
#define WANT_XCR ((1<<1)|(1<<2))
/* 1=xmm; 2=ymm */
int supports(void)
{
unsigned int cpuidmax,id0,id1,id2;
unsigned int familymodelstepping;
unsigned int feature0,feature1,feature2,feature3;
unsigned int xcrlow,xcrhigh;
CPUID(0,0,cpuidmax,id0,id1,id2);
if (cpuidmax < 7) return 0;
CPUID(1,0,familymodelstepping,feature1,feature2,feature3);
if (WANT_1_2 != (WANT_1_2 & feature2)) return 0;
if (WANT_1_3 != (WANT_1_3 & feature3)) return 0;
CPUID(7,0,feature0,feature1,feature2,feature3);
if (WANT_7_1 != (WANT_7_1 & feature1)) return 0;
asm(".byte 15;.byte 1;.byte 208":"=a"(xcrlow),"=d"(xcrhigh):"c"(0));
if (WANT_XCR != (WANT_XCR & xcrlow)) return 0;
return 1;
}
@@ -1,37 +0,0 @@
#define CPUID(func,leaf,a,b,c,d) \
__asm("cpuid":"=a"(a),"=b"(b),"=c"(c),"=d"(d):"a"(func),"c"(leaf):)
#define WANT_1_3 ((1<<23)|(1<<25)|(1<<26))
/* 23=mmx; 25=sse; 26=sse2 */
#define WANT_1_2 ((1<<0)|(1<<9)|(1<<19)|(1<<20)|(1<<27)|(1<<28))
/* 0=sse3; 9=ssse3; 19=sse41; 20=sse42; 27=osxsave; 28=avx */
#define WANT_7_1 ((1<<3)|(1<<5)|(1<<8)|(1<<19))
/* 3=bmi1; 5=avx2; 8=bmi2; 19=adx */
#define WANT_XCR ((1<<1)|(1<<2))
/* 1=xmm; 2=ymm */
int supports(void)
{
unsigned int cpuidmax,id0,id1,id2;
unsigned int familymodelstepping;
unsigned int feature0,feature1,feature2,feature3;
unsigned int xcrlow,xcrhigh;
CPUID(0,0,cpuidmax,id0,id1,id2);
if (cpuidmax < 7) return 0;
CPUID(1,0,familymodelstepping,feature1,feature2,feature3);
if (WANT_1_2 != (WANT_1_2 & feature2)) return 0;
if (WANT_1_3 != (WANT_1_3 & feature3)) return 0;
CPUID(7,0,feature0,feature1,feature2,feature3);
if (WANT_7_1 != (WANT_7_1 & feature1)) return 0;
asm(".byte 15;.byte 1;.byte 208":"=a"(xcrlow),"=d"(xcrhigh):"c"(0));
if (WANT_XCR != (WANT_XCR & xcrlow)) return 0;
return 1;
}
@@ -1,53 +0,0 @@
/*
gcc has __builtin_cpu_supports("avx2")
but implemented it incorrectly until 2018:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85100
as of 2022, many machines still have buggy versions of gcc
furthermore, why is checking just for avx2 enough?
has intel guaranteed that it will never introduce
a cpu with avx2 instructions and without (e.g.) sse4.2?
so manually check cpuid and xgetbv here
and include all the "lower" instruction sets
rather than trying to guess which ones are implied
*/
#define CPUID(func,leaf,a,b,c,d) \
__asm("cpuid":"=a"(a),"=b"(b),"=c"(c),"=d"(d):"a"(func),"c"(leaf):)
#define WANT_1_3 ((1<<23)|(1<<25)|(1<<26))
/* 23=mmx; 25=sse; 26=sse2 */
#define WANT_1_2 ((1<<0)|(1<<9)|(1<<19)|(1<<20)|(1<<27)|(1<<28))
/* 0=sse3; 9=ssse3; 19=sse41; 20=sse42; 27=osxsave; 28=avx */
#define WANT_7_1 ((1<<3)|(1<<5)|(1<<8))
/* 3=bmi1; 5=avx2; 8=bmi2 */
#define WANT_XCR ((1<<1)|(1<<2))
/* 1=xmm; 2=ymm */
int supports(void)
{
unsigned int cpuidmax,id0,id1,id2;
unsigned int familymodelstepping;
unsigned int feature0,feature1,feature2,feature3;
unsigned int xcrlow,xcrhigh;
CPUID(0,0,cpuidmax,id0,id1,id2);
if (cpuidmax < 7) return 0;
CPUID(1,0,familymodelstepping,feature1,feature2,feature3);
if (WANT_1_2 != (WANT_1_2 & feature2)) return 0;
if (WANT_1_3 != (WANT_1_3 & feature3)) return 0;
CPUID(7,0,feature0,feature1,feature2,feature3);
if (WANT_7_1 != (WANT_7_1 & feature1)) return 0;
asm(".byte 15;.byte 1;.byte 208":"=a"(xcrlow),"=d"(xcrhigh):"c"(0));
if (WANT_XCR != (WANT_XCR & xcrlow)) return 0;
return 1;
}

Some files were not shown because too many files have changed in this diff Show More