Royce  Reinger

Royce Reinger

1664000943

10 Favorite Cryptography Library for Rust

In today's post we will learn about 10 Favorite Cryptography Library for Rust.

What is Cryptography?

Cryptography is a method of protecting information and communications through the use of codes, so that only those for whom the information is intended can read and process it.

In computer science, cryptography refers to secure information and communication techniques derived from mathematical concepts and a set of rule-based calculations called algorithms, to transform messages in ways that are hard to decipher. These deterministic algorithms are used for cryptographic key generation, digital signing, verification to protect data privacy, web browsing on the internet and confidential communications such as credit card transactions and email.

Table of contents:

  • Briansmith/ring - Safe, fast, small crypto using Rust and BoringSSL's cryptography primitives. 
  • Briansmith/webpki - Web PKI TLS X.509 certificate validation in Rust. 
  • Conradkleinespel/rooster [rooster] - Simple password manager to use in your terminal.
  • Cossacklabs/themis [themis] - A high-level cryptographic library for solving typical data security tasks, best fit for multi-platform apps. 
  • DaGenix/rust-crypto - Cryptographic algorithms in Rust.
  • Dalek-cryptography/curve25519-dalek - Pure Rust implementation of Curve25519 operations.
  • Dalek-cryptography/ed25519-dalek - Pure Rust implementation of Ed25519 digital signatures.
  • Dalek-cryptography/x25519-dalek - Pure Rust implementation of X25519 key exchange.
  • Debris/tiny-keccak - Pure Rust implementation of the Keccak family (SHA3).
  • Exonum/exonum [exonum] - Extensible framework for blockchain projects.

1 - Briansmith/ring:

Safe, fast, small crypto using Rust and BoringSSL's cryptography primitives.

ring is focused on the implementation, testing, and optimization of a core set of cryptographic operations exposed via an easy-to-use (and hard-to-misuse) API. ring exposes a Rust API and is written in a hybrid of Rust, C, and assembly language.

Particular attention is being paid to making it easy to build and integrate ring into applications and higher-level frameworks, and to ensuring that ring works optimally on small devices, and eventually microcontrollers, to support Internet of Things (IoT) applications.

ring is focused on general-purpose cryptography. WebPKI X.509 certificate validation is done in the webpki project, which is built on top of ring. Also, multiple groups are working on implementations of cryptographic protocols like TLS, SSH, and DNSSEC on top of ring.

ring is the successor of an earlier project called GFp. GFp implemented some elliptic curve cryptography over prime finite fields, also known as prime Galois fields and often denoted GF(p). When we implemented RSA, the name GFp did not make as much sense, since modular arithmetic over RSA public moduli is not GF(p) arithmetic but rather finite commutative ring arithmetic. Also note that ring started as a subset of BoringSSL, and “ring” is a substring of “BoringSSL”.

Most of the C and assembly language code in ring comes from BoringSSL, and BoringSSL is derived from OpenSSL. ring merges changes from BoringSSL regularly. Also, several changes that were developed for ring have already been merged into BoringSSL.

Benchmarks

ring's benchmarks are located in the benches folder of this repository. Because there is lots of platform-specific code in ring, and because ring chooses dynamically at runtime which optimized implementation of each crypto primitive to use, it is very difficult to publish a useful single set of benchmarks; instead, you are highly encouraged to run the benchmarks yourselves on your target hardware.

Contributing

The most important contributions are uses of ring. That is, we're very interested in seeing useful things built on top of ring, like implementations of TLS, SSH, the Noise Protocol, etc.

Of course, contributions to ring's code base are highly appreciated too. The ring project happily accepts pull requests without you needing to sign any formal license agreement. The portions of pull requests that modify existing files must be licensed under the same terms as the files being modified. New files in pull requests, including in particular all Rust code, must be licensed under the ISC-style license. Please state that you agree to license your contributions in the commit messages of commits in pull requests, e.g. by putting this at the bottom of your commit message:


I agree to license my contributions to each file under the terms given
at the top of each file I changed.

If you want to work directly on ring and you don't have an idea for something to contribute already, see these curated lists of open issues:

  • good-first-bug: Bugs that we think newcomers might find best to start with. Note that what makes a bug a good fit depends a lot on the developer's background and not just the hardness of the work.

In addition, we're always interested in these kinds of contributions:

  • Expanding the benchmarks in the benches folder.
  • Additional testing code and additional test vectors.
  • Static analysis and fuzzing in the continuous integration.
  • Support for more platforms in the continuous integration (e.g. Android, iOS, ARM microcontrollers).
  • Documentation improvements.
  • More code simplification, especially eliminating dead code.
  • Improving the code size, execution speed, and/or memory footprint.
  • Fixing any bugs you may have found.
  • Better IDE support for Windows (e.g. running the tests within the IDE) and macOS (e.g. Xcode project files).

Before submitting pull requests, make sure that the tests succeed both when running cargo test and cargo test --no-default-features. See BUILDING.md for more info about the features flags that are useful for people hacking on ring.

View on Github

2 - Briansmith/webpki:

Web PKI TLS X.509 certificate validation in Rust.

What is webpki?

webpki is a library that validates Web PKI (TLS/SSL) certificates. webpki is designed to provide a full implementation of the client side of the Web PKI to a diverse range of applications and devices, including embedded (IoT) applications, mobile apps, desktop applications, and server infrastructure. webpki is intended to not only be the best implementation of the Web PKI, but to also precisely define what the Web PKI is.

webpki is written in Rust and uses ring for signature verification.

webpki is strongly influenced by mozilla::pkix. You can read a little about the ideas underlying both mozilla::pkix and webpki in insanity::pkix: A New Certificate Path Building & Validation Library.

The Rust compiler statically guarantees there are no buffer overflows, uses-after-free, double-frees, data races, etc. in webpki. webpki takes advantage of Rust's borrow checker to ensure that its zero-copy parsing strategy is safe and efficient. webpki never allocates memory on the heap, and it maintains a tight bound on the amount of stack memory it uses. webpki avoids all superfluous PKIX features in order to keep its object code size small. Further reducing the code size of webpki is an important goal.

This release is the very first prototype. Lots of improvements are planned, including:

  • An extensive automated test suite.
  • Key pinning.
  • Certificate Transparency support.
  • Short-lived certificate, OCSP stapling, and CRLSet support.
  • Customization of the supported algorithms, key sizes, and elliptic curves allowed during a validation.
  • A C language wrapper interface to allow using webpki in non-Rust applications.
  • A specification of precisely what the Web PKI is.

View on Github

3 - Conradkleinespel/rooster [rooster]:

Simple password manager to use in your terminal.

Rooster is a simple password manager for geeks (it works in the terminal).

asciicast

Rooster is made available free of charge. You can support its development through Liberapay 💪

Features

Rooster has some unique goals:

  • it is easy to maintain so that it never becomes unmaintained
  • it works completely offline by saving your password in a single local file
  • it stores username/password combinations, nothing more, nothing less
  • it can import/export passwords from and to 1Password/JSON/CSV

Rooster protects your passwords with state-of-the-art cryptography algorithms:

  • scrypt for key derivation (n = 2^12, r = 8, p = 1 by default, customizable)
  • aes-256-cbc for encryption
  • hmac-sha512 for authentication

Supported operating systems include Linux, BSD and OSX. Windows is not supported at this time.

Installation

To install Rooster, run the following commands as root.

On Arch Linux, install Rooster from AUR.

On Void Linux, install Rooster from XBPS.

On Fedora:

dnf update -y
dnf install -y curl gcc unzip pkgconfig libX11-devel libXmu-devel python3 openssl-devel libsodium-devel
curl https://sh.rustup.rs -sSf | sh -s -- -y
source $HOME/.cargo/env
cargo install --root /usr rooster

On CentOS: instructions should be similar to Fedora, but it seems like libsodium is not available on CentOS and I haven't been able to figure out how to install it. If you know, please let me know.

On Debian:

apt-get update -y
apt-get install -y curl gcc unzip pkg-config libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev libx11-dev libxmu-dev python3 libssl-dev libsodium-dev xsel
curl https://sh.rustup.rs -sSf | sh -s -- -y
source $HOME/.cargo/env
cargo install --root /usr rooster

On Ubuntu 16.04/18.04:

apt update -y
apt install -y curl unzip pkg-config libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev libx11-dev libxmu-dev python3 libssl-dev libsodium-dev xsel
curl https://sh.rustup.rs -sSf | sh -s -- -y
source $HOME/.cargo/env
cargo install --root /usr rooster

On OSX:

brew install curl libsodium openssl
curl https://sh.rustup.rs -sSf | sh -s -- -y
cargo install --root /usr rooster

If you use Wayland instead of X11, install wl-clipboard and make sure you have the following environment variable set: XDG_SESSION_TYPE=wayland.

For other distributions, the various Docker files can help you find which dependencies you need.

Once you have installed Rooster (see instructions below), you can view documentation with:

rooster --help

View on Github

4 - Cossacklabs/themis [themis]:

A high-level cryptographic library for solving typical data security tasks, best fit for multi-platform apps. 

What Themis is

Themis is an open-source high-level cryptographic services library for securing data during authentication, storage, messaging, network exchange, etc. Themis solves 90% of typical data protection use cases that are common for most apps.

Themis helps to build both simple and complex cryptographic features easily, quickly, and securely. Themis allows developers to focus on the main thing: developing their applications.

Use cases that Themis solves

Encrypt stored secrets in your apps and backend: API keys, session tokens, files.

Encrypt sensitive data fields before storing in database ("application-side field-level encryption").

Support searchable encryption, data tokenisation and data masking using Themis and Acra.

Exchange secrets securely: share sensitive data between parties, build simple chat app between patients and doctors.

Build end-to-end encryption schemes with centralised or decentralised architecture: encrypt data locally on one app, use it encrypted everywhere, decrypt only for authenticated user.

Maintain real-time secure sessions: send encrypted messages to control connected devices from your app, receive real-time sensitive data from your apps to your backend.

Compare secrets between parties without revealing them (zero-knowledge proof-based authentication).

One cryptographic library that fits them all: Themis is the best fit for multi-platform apps (e.g., iOS+Android+Electron app with Node.js backend) because it provides 100% compatible API and works in the same way across all supported platforms.

Cryptosystems

Themis provides ready-made building blocks (“cryptosystems”) which simplify usage of core cryptographic security operations.

Themis provides 4 important cryptographic services:

  • Secure Cell: a multi-mode cryptographic container suitable for storing anything from encrypted files to database records and format-preserved strings. Secure Cell is built around AES-256-GCM, AES-256-CTR.
  • Secure Message: a simple encrypted messaging solution for the widest scope of applications. Exchange the keys between the parties and you're good to go. Two pairs of underlying cryptosystems: ECC + ECDSA / RSA + PSS + PKCS#7.
  • Secure Session: session-oriented encrypted data exchange with forward secrecy for better security guarantees and more demanding infrastructures. Secure Session can perfectly function as socket encryption, session security, or a high-level messaging primitive (with some additional infrastructure like PKI). ECDH key agreement, ECC & AES encryption.
  • Secure Comparator: Zero knowledge proofs-based cryptographic protocol for authentication and comparing secrets.

We created Themis to build other products on top of it - i.e. Acra and Hermes.

Installation

Refer to the Installation page to install Themis for your mobile, web, desktop, or server-side application. We highly recommend installation packages instead of building from source.

Availability

Themis supports following CPU architectures: x86_64/i386, ARM, Apple Silicon (ARM64), various Android architectures.

We build and verify Themis on the latest stable OS versions:

  • Debian (9, 10), CentOS (7, 8), Ubuntu (16.04, 18.04, 20.04)
  • macOS (10.12–10.15, 11.*)
  • Android (7–12)
  • iOS (11–15)
  • Windows (experimental MSYS2 support)

We plan to expand this list with a broader set of platforms. If you'd like to help improve or bring Themis to your favourite platform or language — get in touch.

Cryptography

Themis relies on proven cryptographic algorithms implemented by well-known cryptography libraries such as OpenSSL, LibreSSL, BoringSSL. Refer to Cryptograhy in Themis docs to learn more.

This distribution includes cryptographic software. The country in which you currently reside may have restrictions on the import, possession, use, and/or re-export to another country, of encryption software. BEFORE using any encryption software, please check your country's laws, regulations, and policies concerning the import, possession, or use, and re-export of encryption software, to see if this is permitted. See http://www.wassenaar.org/ for more information.

The U.S. Government Department of Commerce, Bureau of Industry and Security (BIS), has classified this software as Export Commodity Control Number (ECCN) 5D002.C.1, which includes information security software using or performing cryptographic functions with asymmetric algorithms. The form and manner of this distribution make it eligible for export under the License Exception ENC Technology Software Unrestricted (TSU) exception (see the BIS Export Administration Regulations, Section 740.13) for both object code and source code.

View on Github

5 - DaGenix/rust-crypto:

Cryptographic algorithms in Rust.

A (mostly) pure-Rust implementation of various common cryptographic algorithms.

Rust-Crypto seeks to create practical, auditable, pure-Rust implementations of common cryptographic algorithms with a minimum amount of assembly code where appropriate. The x86-64, x86, and ARM architectures are supported, although the x86-64 architecture receives the most testing.

Rust-Crypto targets the current, stable build of Rust. If you are having issues while using an older version, please try upgrading to the latest stable.

Rust-Crypto has not been thoroughly audited for correctness, so any use where security is important is not recommended at this time.

Usage

To use Rust-Crypto, add the following to your Cargo.toml:

[dependencies]
rust-crypto = "^0.2"

and the following to your crate root:

extern crate crypto;

Contributions

Contributions are extremely welcome. The most significant needs are help adding documentation, implementing new algorithms, and general cleanup and improvement of the code. By submitting a pull request you are agreeing to make you work available under the license terms of the Rust-Crypto project.

Algorithms

Rust-Crypto already supports a significant number of algorithms and with your help it will support even more in the future. Currently supported algorithms include:

  • AES
  • Bcrypt
  • BLAKE2b
  • BLAKE2s
  • Blowfish
  • ChaCha20
  • Curve25519
  • ECB, CBC, and CTR block cipher modes
  • Ed25519
  • Fortuna
  • Ghash
  • HC128
  • HMAC
  • MD5
  • PBKDF2
  • PKCS padding for CBC block cipher mode
  • Poly1305
  • RC4
  • RIPEMD-160
  • Salsa20 and XSalsa20
  • Scrypt
  • Sha1
  • Sha2 (All fixed output size variants)
  • Sha3
  • Sosemanuk
  • Whirlpool

View on Github

6 - Dalek-cryptography/curve25519-dalek:

Pure Rust implementation of Curve25519 operations.

A pure-Rust implementation of group operations on Ristretto and Curve25519.

curve25519-dalek is a library providing group operations on the Edwards and Montgomery forms of Curve25519, and on the prime-order Ristretto group.

curve25519-dalek is not intended to provide implementations of any particular crypto protocol. Rather, implementations of those protocols (such as x25519-dalek and ed25519-dalek) should use curve25519-dalek as a library.

curve25519-dalek is intended to provide a clean and safe mid-level API for use implementing a wide range of ECC-based crypto protocols, such as key agreement, signatures, anonymous credentials, rangeproofs, and zero-knowledge proof systems.

In particular, curve25519-dalek implements Ristretto, which constructs a prime-order group from a non-prime-order Edwards curve. This provides the speed and safety benefits of Edwards curve arithmetic, without the pitfalls of cofactor-related abstraction mismatches.

Documentation

The semver-stable, public-facing curve25519-dalek API is documented here. In addition, the unstable internal implementation details are documented here.

The curve25519-dalek documentation requires a custom HTML header to include KaTeX for math support. Unfortunately cargo doc does not currently support this, but docs can be built using

make doc
make doc-internal

Use

To import curve25519-dalek, add the following to the dependencies section of your project's Cargo.toml:

curve25519-dalek = "3"

The sole breaking change in the 3.x series was an update to the digest version, and in terms of non-breaking changes it includes:

  • support for using alloc instead of std on stable Rust,
  • the Elligator2 encoding for Edwards points,
  • a fix to use packed_simd2,
  • various documentation fixes and improvements,
  • support for configurably-sized, precomputed lookup tables for basepoint scalar multiplication,
  • two new formally-verified field arithmetic backends which use the Fiat Crypto Rust code, which is generated from proofs of functional correctness checked by the Coq theorem proving system, and
  • support for explicitly calling the zeroize traits for all point types.

The 2.x series has API almost entirely unchanged from the 1.x series, except that:

  • an error in the data modeling for the (optional) serde feature was corrected, so that when the 2.x-series serde implementation is used with serde-bincode, the derived serialization matches the usual X/Ed25519 formats;
  • the rand version was updated.

See CHANGELOG.md for more details.

Backends and Features

The nightly feature enables features available only when using a Rust nightly compiler. In particular, it is required for rendering documentation and for the SIMD backends.

Curve arithmetic is implemented using one of the following backends:

  • a u32 backend using serial formulas and u64 products;
  • a u64 backend using serial formulas and u128 products;
  • an avx2 backend using parallel formulas and avx2 instructions (sets speed records);
  • an ifma backend using parallel formulas and ifma instructions (sets speed records);

By default the u64 backend is selected. To select a specific backend, use:

cargo build --no-default-features --features "std u32_backend"
cargo build --no-default-features --features "std u64_backend"
# Requires nightly, RUSTFLAGS="-C target_feature=+avx2" to use avx2
cargo build --no-default-features --features "std simd_backend"
# Requires nightly, RUSTFLAGS="-C target_feature=+avx512ifma" to use ifma
cargo build --no-default-features --features "std simd_backend"

Crates using curve25519-dalek can either select a backend on behalf of their users, or expose feature flags that control the curve25519-dalek backend.

The std feature is enabled by default, but it can be disabled for no-std builds using --no-default-features. Note that this requires explicitly selecting an arithmetic backend using one of the _backend features. If no backend is selected, compilation will fail.

Performance

Benchmarks are run using criterion.rs:

cargo bench --no-default-features --features "std u32_backend"
cargo bench --no-default-features --features "std u64_backend"
# Uses avx2 or ifma only if compiled for an appropriate target.
export RUSTFLAGS="-C target_cpu=native"
cargo bench --no-default-features --features "std simd_backend"

Performance is a secondary goal behind correctness, safety, and clarity, but we aim to be competitive with other implementations.

View on Github

7 - Dalek-cryptography/ed25519-dalek:

Pure Rust implementation of Ed25519 digital signatures.

Fast and efficient Rust implementation of ed25519 key generation, signing, and verification in Rust.

Installation

To install, add the following to your project's Cargo.toml:

[dependencies.ed25519-dalek]
version = "1"

Benchmarks

On an Intel Skylake i9-7900X running at 3.30 GHz, without TurboBoost, this code achieves the following performance benchmarks:

∃!isisⒶmistakenot:(master *=)~/code/rust/ed25519-dalek ∴ cargo bench
   Compiling ed25519-dalek v0.7.0 (file:///home/isis/code/rust/ed25519-dalek)
    Finished release [optimized] target(s) in 3.11s
      Running target/release/deps/ed25519_benchmarks-721332beed423bce

Ed25519 signing                     time:   [15.617 us 15.630 us 15.647 us]
Ed25519 signature verification      time:   [45.930 us 45.968 us 46.011 us]
Ed25519 keypair generation          time:   [15.440 us 15.465 us 15.492 us]

By enabling the avx2 backend (on machines with compatible microarchitectures), the performance for signature verification is greatly improved:

∃!isisⒶmistakenot:(master *=)~/code/rust/ed25519-dalek ∴ export RUSTFLAGS=-Ctarget_cpu=native
∃!isisⒶmistakenot:(master *=)~/code/rust/ed25519-dalek ∴ cargo bench --features=avx2_backend
   Compiling ed25519-dalek v0.7.0 (file:///home/isis/code/rust/ed25519-dalek)
    Finished release [optimized] target(s) in 4.28s
      Running target/release/deps/ed25519_benchmarks-e4866664de39c84d
Ed25519 signing                     time:   [15.923 us 15.945 us 15.967 us]
Ed25519 signature verification      time:   [33.382 us 33.411 us 33.445 us]
Ed25519 keypair generation          time:   [15.246 us 15.260 us 15.275 us]

In comparison, the equivalent package in Golang performs as follows:

∃!isisⒶmistakenot:(master *=)~/code/go/src/github.com/agl/ed25519 ∴ go test -bench .
BenchmarkKeyGeneration     30000             47007 ns/op
BenchmarkSigning           30000             48820 ns/op
BenchmarkVerification      10000            119701 ns/op
ok      github.com/agl/ed25519  5.775s

Making key generation and signing a rough average of 2x faster, and verification 2.5-3x faster depending on the availability of avx2. Of course, this is just my machine, and these results—nowhere near rigorous—should be taken with a handful of salt.

Translating to a rough cycle count: we multiply by a factor of 3.3 to convert nanoseconds to cycles per second on a 3300 Mhz CPU, that's 110256 cycles for verification and 52618 for signing, which is competitive with hand-optimised assembly implementations.

Additionally, if you're using a CSPRNG from the rand crate, the nightly feature will enable u128/i128 features there, resulting in potentially faster performance.

If your protocol or application is able to batch signatures for verification, the verify_batch() function has greatly improved performance. On the aforementioned Intel Skylake i9-7900X, verifying a batch of 96 signatures takes 1.7673ms. That's 18.4094us, or roughly 60750 cycles, per signature verification, more than double the speed of batch verification given in the original paper (this is likely not a fair comparison as that was a Nehalem machine). The numbers after the / in the test name refer to the size of the batch:

∃!isisⒶmistakenot:(master *=)~/code/rust/ed25519-dalek ∴ export RUSTFLAGS=-Ctarget_cpu=native
∃!isisⒶmistakenot:(master *=)~/code/rust/ed25519-dalek ∴ cargo bench --features=avx2_backend batch
   Compiling ed25519-dalek v0.8.0 (file:///home/isis/code/rust/ed25519-dalek)
    Finished release [optimized] target(s) in 34.16s
      Running target/release/deps/ed25519_benchmarks-cf0daf7d68fc71b6
Ed25519 batch signature verification/4   time:   [105.20 us 106.04 us 106.99 us]
Ed25519 batch signature verification/8   time:   [178.66 us 179.01 us 179.39 us]
Ed25519 batch signature verification/16  time:   [325.65 us 326.67 us 327.90 us]
Ed25519 batch signature verification/32  time:   [617.96 us 620.74 us 624.12 us]
Ed25519 batch signature verification/64  time:   [1.1862 ms 1.1900 ms 1.1943 ms]
Ed25519 batch signature verification/96  time:   [1.7611 ms 1.7673 ms 1.7742 ms]
Ed25519 batch signature verification/128 time:   [2.3320 ms 2.3376 ms 2.3446 ms]
Ed25519 batch signature verification/256 time:   [5.0124 ms 5.0290 ms 5.0491 ms]

As you can see, there's an optimal batch size for each machine, so you'll likely want to test the benchmarks on your target CPU to discover the best size. For this machine, around 100 signatures per batch is the optimum:

Additionally, thanks to Rust, this implementation has both type and memory safety. It's also easily readable by a much larger set of people than those who can read qhasm, making it more readily and more easily auditable. We're of the opinion that, ultimately, these features—combined with speed—are more valuable than simply cycle counts alone.

View on Github

8 - Dalek-cryptography/x25519-dalek:

Pure Rust implementation of X25519 key exchange.

A pure-Rust implementation of x25519 elliptic curve Diffie-Hellman key exchange, with curve operations provided by curve25519-dalek.

This crate provides two levels of API: a bare byte-oriented x25519 function which matches the function specified in RFC7748, as well as a higher-level Rust API for static and ephemeral Diffie-Hellman.

Examples

Alice and Bob are two adorable kittens who have lost their mittens, and they wish to be able to send secret messages to each other to coordinate finding them, otherwise—if their caretaker cat finds out—they will surely be called naughty kittens and be given no pie!

But the two kittens are quite clever. Even though their paws are still too big and the rest of them is 90% fuzziness, these clever kittens have been studying up on modern public key cryptography and have learned a nifty trick called elliptic curve Diffie-Hellman key exchange. With the right incantations, the kittens will be able to secretly organise to find their mittens, and then spend the rest of the afternoon nomming some yummy pie!

First, Alice uses EphemeralSecret::new() and then PublicKey::from() to produce her secret and public keys:

use rand_core::OsRng;
use x25519_dalek::{EphemeralSecret, PublicKey};

let alice_secret = EphemeralSecret::new(OsRng);
let alice_public = PublicKey::from(&alice_secret);

Bob does the same:

# use rand_core::OsRng;
# use x25519_dalek::{EphemeralSecret, PublicKey};
let bob_secret = EphemeralSecret::new(OsRng);
let bob_public = PublicKey::from(&bob_secret);

Alice meows across the room, telling alice_public to Bob, and Bob loudly meows bob_public back to Alice. Alice now computes her shared secret with Bob by doing:

# use rand_core::OsRng;
# use x25519_dalek::{EphemeralSecret, PublicKey};
# let alice_secret = EphemeralSecret::new(OsRng);
# let alice_public = PublicKey::from(&alice_secret);
# let bob_secret = EphemeralSecret::new(OsRng);
# let bob_public = PublicKey::from(&bob_secret);
let alice_shared_secret = alice_secret.diffie_hellman(&bob_public);

Similarly, Bob computes a shared secret by doing:

# use rand_core::OsRng;
# use x25519_dalek::{EphemeralSecret, PublicKey};
# let alice_secret = EphemeralSecret::new(OsRng);
# let alice_public = PublicKey::from(&alice_secret);
# let bob_secret = EphemeralSecret::new(OsRng);
# let bob_public = PublicKey::from(&bob_secret);
let bob_shared_secret = bob_secret.diffie_hellman(&alice_public);

These secrets are the same:

# use rand_core::OsRng;
# use x25519_dalek::{EphemeralSecret, PublicKey};
# let alice_secret = EphemeralSecret::new(OsRng);
# let alice_public = PublicKey::from(&alice_secret);
# let bob_secret = EphemeralSecret::new(OsRng);
# let bob_public = PublicKey::from(&bob_secret);
# let alice_shared_secret = alice_secret.diffie_hellman(&bob_public);
# let bob_shared_secret = bob_secret.diffie_hellman(&alice_public);
assert_eq!(alice_shared_secret.as_bytes(), bob_shared_secret.as_bytes());

Voilà! Alice and Bob can now use their shared secret to encrypt their meows, for example, by using it to generate a key and nonce for an authenticated-encryption cipher.

This example used the ephemeral DH API, which ensures that secret keys cannot be reused; Alice and Bob could instead use the static DH API and load a long-term secret key.

Installation

To install, add the following to your project's Cargo.toml:

[dependencies]
x25519-dalek = "1"

View on Github

9 - Debris/tiny-keccak:

Pure Rust implementation of the Keccak family (SHA3).

An implementation of Keccak derived functions specified in FIPS-202, SP800-185 and KangarooTwelve.

Usage

In your Cargo.toml specify what features (hash functions, you are intending to use). Available options are: cshake, fips202, k12, keccak, kmac, parallel_hash, sha3, shake, sp800, tuple_hash.

[dependencies]
tiny-keccak = { version = "2.0", features = ["sha3"] }

Example

use tiny_keccak::Sha3;

fn main() {
    let mut sha3 = Sha3::v256();
    let mut output = [0u8; 32];
    let expected = b"\
        \x64\x4b\xcc\x7e\x56\x43\x73\x04\x09\x99\xaa\xc8\x9e\x76\x22\xf3\
        \xca\x71\xfb\xa1\xd9\x72\xfd\x94\xa3\x1c\x3b\xfb\xf2\x4e\x39\x38\
    ";

    sha3.update(b"hello");
    sha3.update(b" ");
    sha3.update(b"world");
    sha3.finalize(&mut output);

    assert_eq!(expected, &output);
}

Benchmarks

Benchmarked with rust-crypto sha3 on:

MacBook Pro (Retina, 15-inch, Mid 2015)
2,5 GHz Intel Core i7
16 GB 1600 MHz DDR3
Intel Iris Pro 1536 MB

Benchmark code is available here

running 4 tests
test rust_crypto_sha3_256_input_32_bytes   ... bench:         677 ns/iter (+/- 113) = 47 MB/s
test rust_crypto_sha3_256_input_4096_bytes ... bench:      17,619 ns/iter (+/- 4,174) = 232 MB/s
test tiny_keccak_sha3_256_input_32_bytes   ... bench:         569 ns/iter (+/- 204) = 56 MB/s
test tiny_keccak_sha3_256_input_4096_bytes ... bench:      17,185 ns/iter (+/- 4,575) = 238 MB/s

View on Github

10 - Exonum/exonum [exonum]:

Extensible framework for blockchain projects.

Exonum is an extensible open-source framework for creating blockchain applications. Exonum can be used to create cryptographically powered distributed ledgers in virtually any problem domain, including FinTech, GovTech, and LegalTech. The Exonum framework is oriented towards creating permissioned blockchains, that is, blockchains with the known set of blockchain infrastructure providers.

Contents

This is the main Exonum repository containing the bulk of Rust crates used in Exonum. Rust crates for Exonum are intended to be reasonably small and reusable, hence there is relatively large number of them.

Main Crates

Upstream Dependencies

Tools for Building Services

Services and Node Plugins

Examples

Versioning Policy

Exonum crates follow semantic versioning.

The exonum crate and its re-exported dependencies (exonum-crypto, exonum-merkledb and exonum-keys) are released at the same time; their version is considered the version of the Exonum framework. On the other hand, the crates downstream of exonum (e.g., exonum-node) or independent of it (e.g., exonum-api) may evolve at different speeds, including major releases not tied to a major Exonum release.

Throughout the Exonum codebase, certain APIs are described in the API docs as unstable or experimental. Such APIs may be removed or changed in a semantically non-breaking release (for example, a minor release) of the corresponding crate. Similarly, nominally public APIs that are hidden from the docs via [doc(hidden)] are considered unstable and thus exempt from semantic versioning limitations.

View on Github

Thank you for following this article.

Related videos:

Rust Crypto Libraries - The Rust Programming Language

#rust #cryptography 

10 Favorite Cryptography Library for Rust
Rocio  O'Keefe

Rocio O'Keefe

1660630740

A Set Of High-level APIs Over PointyCastle for Two-way Cryptography

encrypt  

A set of high-level APIs over PointyCastle for two-way cryptography.

Looking for password hashing? Please, visit password.

Secure random

You can generate cryptographically secure random keys and IVs for you project.

Activate the encrypt package:

pub global activate encrypt

Then use the secure-random command-line tool:

$ secure-random
CBoaDQIQAgceGg8dFAkMDBEOECEZCxgMBiAUFQwKFhg=

You can set the length and the base output.

$ secure-random --help
-l, --length       The length of the bytes
                   (defaults to "32")

-b, --base         Bytes represented as base 64 or base 16 (Hexdecimal)
                   (defaults to "64")

-h, --[no-]help    Show this help message

Algorithms

Current status is:

  • AES with PKCS7 padding
  • RSA with PKCS1 and OAEP encoding
  • Salsa20

Signing

  • SHA256 with RSA

Usage

Symmetric

AES

import 'package:encrypt/encrypt.dart';

void main() {
  final plainText = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit';
  final key = Key.fromUtf8('my 32 length key................');
  final iv = IV.fromLength(16);

  final encrypter = Encrypter(AES(key));

  final encrypted = encrypter.encrypt(plainText, iv: iv);
  final decrypted = encrypter.decrypt(encrypted, iv: iv);

  print(decrypted); // Lorem ipsum dolor sit amet, consectetur adipiscing elit
  print(encrypted.base64); // R4PxiU3h8YoIRqVowBXm36ZcCeNeZ4s1OvVBTfFlZRdmohQqOpPQqD1YecJeZMAop/hZ4OxqgC1WtwvX/hP9mw==
}

Modes of operation

Default mode is SIC AESMode.sic, you can override it using the mode named parameter:

final encrypter = Encrypter(AES(key, mode: AESMode.cbc));

Supported modes are:

  • CBC AESMode.cbc
  • CFB-64 AESMode.cfb64
  • CTR AESMode.ctr
  • ECB AESMode.ecb
  • OFB-64/GCTR AESMode.ofb64Gctr
  • OFB-64 AESMode.ofb64
  • SIC AESMode.sic

No/zero padding

To remove padding, pass null to the padding named parameter on the constructor:

final encrypter = Encrypter(AES(key, mode: AESMode.cbc, padding: null));

Salsa20

import 'package:encrypt/encrypt.dart';

void main() {
  final plainText = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit';
  final key = Key.fromLength(32);
  final iv = IV.fromLength(8);
  final encrypter = Encrypter(Salsa20(key));

  final encrypted = encrypter.encrypt(plainText, iv: iv);
  final decrypted = encrypter.decrypt(encrypted, iv: iv);

  print(decrypted); // Lorem ipsum dolor sit amet, consectetur adipiscing elit
  print(encrypted.base64); // CR+IAWBEx3sA/dLkkFM/orYr9KftrGa7lIFSAAmVPbKIOLDOzGwEi9ohstDBqDLIaXMEeulwXQ==
}

Fernet

import 'package:encrypt/encrypt.dart';
import 'dart:convert';

void main() {
  final plainText = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit';
  final key = Key.fromUtf8('my32lengthsupersecretnooneknows1');

  final b64key = Key.fromUtf8(base64Url.encode(key.bytes).substring(0,32));
  // if you need to use the ttl feature, you'll need to use APIs in the algorithm itself
  final fernet = Fernet(b64key);
  final encrypter = Encrypter(fernet);

  final encrypted = encrypter.encrypt(plainText);
  final decrypted = encrypter.decrypt(encrypted);

  print(decrypted); // Lorem ipsum dolor sit amet, consectetur adipiscing elit
  print(encrypted.base64); // random cipher text
  print(fernet.extractTimestamp(encrypted.bytes)); // unix timestamp
}

Asymmetric

RSA

import 'dart:io';
import 'package:encrypt/encrypt.dart';
import 'package:pointycastle/asymmetric/api.dart';

void main() {
  final publicKey = await parseKeyFromFile<RSAPublicKey>('test/public.pem');
  final privKey = await parseKeyFromFile<RSAPrivateKey>('test/private.pem');

  final plainText = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit';
  final encrypter = Encrypter(RSA(publicKey: publicKey, privateKey: privKey));

  final encrypted = encrypter.encrypt(plainText);
  final decrypted = encrypter.decrypt(encrypted);

  print(decrypted); // Lorem ipsum dolor sit amet, consectetur adipiscing elit
  print(encrypted.base64); // kO9EbgbrSwiq0EYz0aBdljHSC/rci2854Qa+nugbhKjidlezNplsEqOxR+pr1RtICZGAtv0YGevJBaRaHS17eHuj7GXo1CM3PR6pjGxrorcwR5Q7/bVEePESsimMbhHWF+AkDIX4v0CwKx9lgaTBgC8/yJKiLmQkyDCj64J3JSE=
}

Signature and verification

RSA

 final publicKey = await parseKeyFromFile<RSAPublicKey>('test/public.pem');
 final privateKey = await parseKeyFromFile<RSAPrivateKey>('test/private.pem');
 final signer = Signer(RSASigner(RSASignDigest.SHA256, publicKey: publicKey, privateKey: privateKey));

 print(signer.sign('hello world').base64);
 print(signer.verify64('hello world', 'jfMhNM2v6hauQr6w3ji0xNOxGInHbeIH3DHlpf2W3vmSMyAuwGHG0KLcunggG4XtZrZPAib7oHaKEAdkHaSIGXAtEqaAvocq138oJ7BEznA4KVYuMcW9c8bRy5E4tUpikTpoO+okHdHr5YLc9y908CAQBVsfhbt0W9NClvDWegs='));

Download Details:

Author: leocavalcante
Source Code: https://github.com/leocavalcante/encrypt 
License: BSD-3-Clause license

#flutter #dart #cryptography #encrypt 

A Set Of High-level APIs Over PointyCastle for Two-way Cryptography

Nettle.jl: Libnettle Supports A Wide Array Of Hashing Algorithms

Nettle.jl 

libnettle supports a wide array of hashing algorithms. This package interrogates libnettle to determine the available hash types, which are then available from Nettle.get_hash_types(). Typically these include SHA1, SHA224, SHA256, SHA384, SHA512, MD2, MD5 and RIPEMD160.

Typical usage of these hash algorithms is to create a Hasher, update! it, and finally get a digest:

h = Hasher("sha256")
update!(h, "this is a test")
hexdigest!(h)

#or...
hexdigest("sha256", "this is a test")

Outputs:

2e99758548972a8e8822ad47fa1017ff72f06f3ff6a016851f45c398732bc50c

A digest! function is also available to return the digest as an Array(UInt8,1). Note that both the digest! function and the hexdigest! function reset the internal Hasher object to a pristine state, ready for further update! calls.

HMAC Functionality

HMAC functionality revolves around the HMACState type, created by the function of the same name. Arguments to this constructor are the desired hash type, and the desired key used to authenticate the hashing:

h = HMACState("sha256", "mykey")
update!(h, "this is a test")
hexdigest!(h)

#or...
hexdigest("sha256", "mykey", "this is a test")

Outputs:

"ca1dcafe1b5fb329256248196c0f92a95fbe3788db6c5cb0775b4106db437ba2"

A digest! function is also available to return the digest as an Array(UInt8,1). Note that both the digest! function and the hexdigest! function reset the internal HMACState object to a pristine state, ready for further update! calls.

Encryption/Decryption Functionality

Nettle also provides encryption and decryption functionality, using the Encryptor and Decryptor objects. Cipher types are available through get_cipher_types(). Create a pair of objects with a shared key, and encrypt()/decrypt() to your heart's content:

key = "this key's exactly 32 bytes long"
enc = Encryptor("AES256", key)
plaintext = "this is 16 chars"
ciphertext = encrypt(enc, plaintext)

dec = Decryptor("AES256", key)
deciphertext = decrypt(dec, ciphertext)
Vector{UInt8}(plaintext) == deciphertext # no bytestring

# or...
decrypt("AES256", key, encrypt("AES256", key, plaintext)) == Vector{UInt8}(plaintext)

For AES256CBC encrypt/decrypt, generate a pair of key32 and iv16 with salt.

(And add or trim padding yourself.)

passwd = "Secret Passphrase"
salt = hex2bytes("a3e550e89e70996c") # use random 8 bytes
(key32, iv16) = gen_key32_iv16(Vector{UInt8}(passwd), salt)

enc = Encryptor("AES256", key32)
plaintext = "Message"
ciphertext = encrypt(enc, :CBC, iv16, add_padding_PKCS5(Vector{UInt8}(plaintext), 16))

dec = Decryptor("AES256", key32)
deciphertext = decrypt(dec, :CBC, iv16, ciphertext)
Vector{UInt8}(plaintext) == trim_padding_PKCS5(deciphertext) # no bytestring

# or...
plainbytes = hex2bytes("414155aa5541416162")
cipherbytes = encrypt("AES256", :CBC, iv16, key32, add_padding_PKCS5(plainbytes, 16))
decipherbytes = decrypt("AES256", :CBC, iv16, key32, cipherbytes)
plainbytes == trim_padding_PKCS5(decipherbytes) # no bytestring

Download Details: 

Author: JuliaCrypto
Source Code: https://github.com/JuliaCrypto/Nettle.jl 
License: View license

#julia #cryptography #encryption 

Nettle.jl: Libnettle Supports A Wide Array Of Hashing Algorithms
Elian  Harber

Elian Harber

1659918480

Iotex-core: Official Implementation Of IoTeX Blockchain Protocol in Go

iotex-core

Official Golang implementation of the IoTeX protocol.       

Welcome to the official Go implementation of IoTeX protocol! IoTeX is building the next generation of the decentralized blockchain protocol for powering real-world information marketplace in a decentralized-yet-scalable way. Refer to IoTeX whitepaper for details. 

New to IoTeX?

Please visit https://iotex.io official website or IoTeX onboard pack to learn more about IoTeX network.

Run a delegate?

Please visit IoTeX Delegate Manual for detailed setup process.

Building the source code

Minimum requirements

ComponentsVersionDescription
Golang≥ 1.17.3Go programming language
Protoc≥ 3.6.0Protocol buffers, required only when you rebuild protobuf messages

Compile

Download the code to your desired local location (doesn't have to be under $GOPATH/src)

git clone git@github.com:iotexproject/iotex-core.git
cd iotex-core

If you put the project code under your $GOPATH\src, you will need to set up an environment variable

export GO111MODULE=on
set GO111MODULE=on (for windows)

Build the project for general purpose (server, ioctl) by

make

Build the project for broader purpose (server, ioctl, injector...) by

make all 

If the dependency needs to be updated, run

go get -u
go mod tidy

If you want learn more advanced usage about go mod, you can find out here.

Run unit tests only by

make test

Build the docker image by

make docker

Run iotex-core

Start (or resume) a standalone server to operate on an blockchain by

make run

Restart the server from a clean state by

make reboot

If "make run" fails due to corrupted or missing state database while block database is in normal condition, e.g., failing to get factory's height from underlying DB, please try to recover state database by

make recover

Then, "make run" again.

Use CLI

Users could interact with iotex blockchain by

ioctl [command]

Refer to CLI document for more details.

Contact

Contribution

We are glad to have contributors out of the core team; contributions, including (but not limited to) style/bug fixes, implementation of features, proposals of schemes/algorithms, and thorough documentation, are welcomed. Please refer to our contribution guideline for more information. Development guide documentation is here.

For any major protocol level changes, we use IIP to track the proposal, decision and etc.

Contributors

Thank you for considering contributing to the IoTeX framework! 

Author: iotexproject
Source Code: https://github.com/iotexproject/iotex-core 
License: Apache-2.0 license

#go #golang #core #cryptography #blockchain 

Iotex-core: Official Implementation Of IoTeX Blockchain Protocol in Go
Nat  Grady

Nat Grady

1658100120

Swifty: Free Offline Password Manager

Free Offline-first Password Manager for MacOS, Windows and Linux.

Features

  • Store Login/Password credentials
  • Credit card Information
  • Secure notes to store sensitive information
  • One-click Strong Password Generation
  • Time-based One Time Passwords support (TOTP)
  • Google Drive Sync (optional)
  • No data is leaving your computer:
    • Everything is encrypted, stored and decrypted on your local file system
    • Decryption happens once on entering Master Password
    • Ability to migrate from one computer to another using backup file or GDrive sync
  • There's more to come...

Screenshots

img

img

Install

Check Latest Releases page for recent version of packaged app for MacOS, Windows or Linux.

Alternatively you can build app yourself:

git clone git@github.com:swiftyapp/swifty.git
yarn install
bozon package mac

Author: Swiftyapp
Source Code: https://github.com/swiftyapp/swifty 
License: GPL-3.0 license

#electron #javascript #security #cryptography 

Swifty: Free Offline Password Manager
Gordon  Taylor

Gordon Taylor

1658040240

Open Source Cybersecurity Protocol for Syncing Decentralized Graph

Gun

GUN is an ecosystem of tools that let you build community run and encrypted applications - like an Open Source Firebase or a Decentralized Dropbox.

The Internet Archive and 100s of other apps run GUN in-production. GUN is also part of Twitter's Bluesky initiative!

  • Multiplayer by default with realtime p2p state synchronization!
  • Graph data lets you use key/value, tables, documents, videos, & more!
  • Local-first, offline, and decentralized with end-to-end encryption.

Decentralized alternatives to Zoom, Reddit, Instagram, Slack, YouTube, Stripe, Wikipedia, Facebook Horizon and more have already pushed terabytes of daily P2P traffic on GUN. We are a friendly community creating a free fun future for freedom:

Quickstart

GUN is super easy to get started with:

  • Try the interactive tutorial in the browser (5min ~ average developer).
  • Or npm install gun and run the examples with cd node_modules/gun && npm start (5min ~ average developer).

Note: If you don't have node or npm, read this first. If the npm command line didn't work, you may need to mkdir node_modules first or use sudo.

<script src="https://cdn.jsdelivr.net/npm/gun/gun.js"></script>
<script>
// import GUN from 'gun'; // in ESM
// GUN = require('gun'); // in NodeJS
// GUN = require('gun/gun'); // in React
gun = GUN();

gun.get('mark').put({
  name: "Mark",
  email: "mark@gun.eco",
});

gun.get('mark').on((data, key) => {
  console.log("realtime updates:", data);
});

setInterval(() => { gun.get('mark').get('live').put(Math.random()) }, 9);
</script>
  • Or try something mind blowing, like saving circular references to a table of documents! (play)
cat = {name: "Fluffy", species: "kitty"};
mark = {boss: cat};
cat.slave = mark;

// partial updates merge with existing data!
gun.get('mark').put(mark);

// access the data as if it is a document.
gun.get('mark').get('boss').get('name').once(function(data, key){
  // `once` grabs the data once, no subscriptions.
  console.log("Mark's boss is", data);
});

// traverse a graph of circular references!
gun.get('mark').get('boss').get('slave').once(function(data, key){
  console.log("Mark is the cat's slave!", data);
});

// add both of them to a table!
gun.get('list').set(gun.get('mark').get('boss'));
gun.get('list').set(gun.get('mark'));

// grab each item once from the table, continuously:
gun.get('list').map().once(function(data, key){
  console.log("Item:", data);
});

// live update the table!
gun.get('list').set({type: "cucumber", goal: "jumping cat"});

Want to keep building more? Jump to THE DOCUMENTATION!

About

First & foremost, GUN is a community of the nicest and most helpful people out there. So I want to invite you to come tell us about what you are working on & wanting to build (new or old school alike! Just be nice as well.) and ask us your questions directly. :)


Watch the 100 second intro!

The GUN ecosystem stack is a collection of independent and modular tools covering everything from CRDT conflict resolution, cryptographic security & encryption, radix storage serialization, mesh networking & routing algorithms, to distributed systems correctness & load testing, CPU scheduled JSON parser to prevent UI lag, and more!

On that note, let's get some official shout outs covered first:

History

GUN was created by Mark Nadal in 2014 after he had spent 4 years trying to get his collaborative web app to scale up with traditional databases.

After he realized Master-Slave database architecture causes one big bottleneck, he (as a complete newbie outsider) naively decided to question the status quo and shake things up with controversial, heretical, and contrarian experiments:

The NoDB - no master, no servers, no "single source of truth", not built with a real programming language or real hardware, no DevOps, no locking, not just SQL or NoSQL but both (all - graphs, documents, tables, key/value).

The goal was to build a P2P database that could survive living inside any browser, and could correctly sync data between any device after assuming any offline-first activity.

Technically, GUN is a graph synchronization protocol with a lightweight embedded engine, capable of doing 20M+ API ops/sec in just ~9KB gzipped size.

Documentation

API reference

Tutorials

Examples

GraphQL

Electron

React & Native

Vue

Svelte

Webcomponents

CAP Theorem Tradeoffs

How Data Sync Works

How GUN is Built

Crypto Auth

Modules

Roadmap

This would not be possible without community contributors, big shout out to:

ajmeyghani (Learn GUN Basics with Diagrams); anywhichway (Block Storage); beebase (Quasar); BrockAtkinson (brunch config); Brysgo (GraphQL); d3x0r (SQLite); forrestjt (file.js); hillct (Docker); JosePedroDias (graph visualizer); JuniperChicago (cycle.js bindings); jveres (todoMVC); kristianmandrup (edge); Lightnet (Awesome Vue User Examples & User Kitchen Sink Playground); lmangani (Cytoscape Visualizer, Cassandra, Fastify, LetsEncrypt); mhelander (SEA); omarzion (Sticky Note App); PsychoLlama (LevelDB); RangerMauve (schema); robertheessels (gun-p2p-auth); rogowski (AXE); sbeleidy; sbiaudet (C# Port); Sean Matheson (Observable/RxJS/Most.js bindings); Shadyzpop (React Native example); sjones6 (Flint); RIP Stefdv (Polymer/web components); zrrrzzt (JWT Auth); xmonader (Python Port);

I am missing many others, apologies, will be adding them soon! This list is infintiely old & way out of date, if you want to be listed in it please make a PR! :)

Testing

You will need to npm install -g mocha first. Then in the gun root folder run npm test. Tests will trigger persistent writes to the DB, so subsequent runs of the test will fail. You must clear the DB before running the tests again. This can be done by running rm -rf *data* command in the project directory.

Shims

These are only needed for NodeJS & React Native, they shim the native Browser WebCrypto API.

If you want to use SEA for User auth and security, you will need to install:

npm install @peculiar/webcrypto --save

Please see our React Native docs for installation instructions!

Then you can require SEA without an error:

GUN = require('gun/gun');
SEA = require('gun/sea');

Deploy

Note: The default examples that get auto-deployed on npm start CDN-ify all GUN files, modules, & storage.

Note: Moving forward, AXE will start to automatically cluster your peer into a shared DHT. You may want to disable this to run an isolated network.

Note: When deploying a web application using GUN on a cloud provider, you may have to set CI=false in your .env. This prevents GUN-specific warnings from being treated as errors when deploying your app. You may also resolve this by modifying your webpack config to not try to build the GUN dependencies.

To quickly spin up a GUN relay peer for your development team, utilize Heroku, Docker, or any others listed below. Or some variant thereof Dokku, K8s, etc. ! Or use all of them so your relays are decentralized too!

Linux

SSH into the home directory of a clean OS install with sudo ability. Set any environment variables you need (see below), then do:

curl -o- https://raw.githubusercontent.com/amark/gun/master/examples/install.sh | bash

Read install.sh first! If curl is not found, copy&paste the contents of install.sh into your ssh.

You can now safely CTRL+A+D to escape without stopping the peer. To stop everything killall screen or killall node.

Environment variables may need to be set like export HTTPS_CERT=~/cert.pem HTTPS_KEY=~/key.pem PORT=443. You can also look at a sample nginx config. For production deployments, you probably will want to use something like pm2 or better to keep the peer alive after machine reboots.

Heroku

Deploy

Heroku deletes your data every 15 minutes, one way to fix this is by adding cheap storage.

Or:

git clone https://github.com/amark/gun.git
cd gun
heroku create
git push -f heroku HEAD:master

Then visit the URL in the output of the 'heroku create' step, in a browser. Make sure to set any environment config vars in the settings tab.

Zeet.co

Deploy

Then visit the URL in the output of the 'now --npm' step, in your browser.

Docker

Warning: Docker image is community contributed and may be old with missing security updates, please check version numbers to compare.

Docker Automated build Docker Pulls Docker Stars

Pull from the Docker Hub . Or:

docker run -p 8765:8765 gundb/gun

Or build the Docker image locally:

git clone https://github.com/amark/gun.git
cd gun
docker build -t myrepo/gundb:v1 .
docker run -p 8765:8765 myrepo/gundb:v1

Or, if you prefer your Docker image with metadata labels (Linux/Mac only):

npm run docker
docker run -p 8765:8765 username/gun:git

Then visit http://localhost:8765 in your browser.

Author: Amark
Source Code: https://github.com/amark/gun 
License: View license

#javascript #machinelearning #cryptography #database #graph 

Open Source Cybersecurity Protocol for Syncing Decentralized Graph
Mike  Kozey

Mike Kozey

1656972720

Dummycastle: Cryptography for Dummies

DummyCastle - Cryptography for dummies.

What is DummyCastle?

It's a quick and simple solution for Java and Dart developers who want to apply any level of security to their applications and they are not interested in learning to use available libraries.

Who is this solution for?

DummyCastle should be used whenever there is a need to protect information that is not essential. For example, to protect:

  • API keys
  • chats
  • messages
  • settings
  • generally small amount of data

Who is this solution not for?

DummyCastle should not be used whenever there is a need to secure high-value information. For example, to protect:

  • money - ecoins
  • secret information
  • illegal information
  • generally large amounts of data

Features

The library provides the following features:

  • symmetric encryption
  • asymmetric encryption
  • random generation
  • hashing(digesting)
  • shuffling
  • obfuscation

Everything is preconfigured and there is no need to have any kind knowledge about cryptography other than this short manual.

Getting started

Installation 

implementation 'pl.polinc.dummycastle:dummycastle:1.2.0'

Code

One simple object is enough to handle all the operations and methods.

import pl.polinc.dummycastle.DummyCastle;
  
DummyCastle dummyCastle = new DummyCastle();
 
String password="Password";
dummyCastle.genSymmKeyWith(password);
String encrypted = dummyCastle.encryptSymmWith(plainText).getResult();

The DummyCastle class is designed to be a container for a value which is being operated on. That's why as a rule of thumb, a new object should be created for every value which you want to encrypt or carry out any other operation. It is not thread safe in any way. Object's memory footprint is very small though. Most of the methods are static, so the only memory weight is a result of the processed value. In order to help to work on a value, the method chaining is possible. For example if you want to generate a random value and encrypt it, you can do it with only one line of code:

String randomInt = dummyCastle.randomNumWith(8).genSymmKeyWith("Password").encryptSymm().getResult();

Encoding

DummyCastle keeps the processed value internally as an array of bytes. It may be retrieved from the object using couple of methods. In general the output from the library is encoded using HEX encoding. The reason behind it is to prevent any platform specific problems related to encoding. The result might be retrieved using getResult() or toString() methods.

String randomIntDecoded = dummyCastle.randomNumWith(8).getResult();

The raw/decoded output might be retrieved as a string using getResultDecoded() or as an array of bytes using getResultDecodedRaw():

String randomIntPlain = dummyCastle.randomNumWith(8).getResultDecoded();

Alternatively, you may use the method fromStringEncoded() which accept encoded text and then decode it using getResultDecoded():

String plainText = dummyCastle.fromStringEncoded(decrypted).getResultDecoded();

of using decodeWith() method:

String plainText=dummyCastle.decodeWith(decrypted).toStringDecoded();

Error handling

The library tries to be as unobtrusive as possible, that's why it handles all its exceptions internally. Thanks to that there is no risk of NullPointerException, but it is attained at the cost of verbosity of error handling. So if the exception occurs the value gets purged and limited to an empty string, but not nullified. In order to detect causes of potential errors two methods are provided: isError() and getException(). The isError() method, as one may suspect, returns boolean value which indicate that at any point of calling methods of the library an exceptions has been thrown. This means that errors don't get reset by next operations. This poses a risk of calling chained methods which in sequence may work of erratic value. The second method returns the actual exceptions which may be used to retrieve information concerning the issue.

//Any kind of operations. We assume it will throw an internal exception.
String plainText=dummyCastle.decodeWith(decrypted).toStringDecoded();
//If an exception occures, at this point the plainText == "". 
//By checking the flag and printing the exceptions stack we may get the necesarry information
if(dummyCastle.isError())
    System.out.println(dummyCastle.getException());

Usage

Symmetric encryption

Symmetric encryption is a type of encryption where only one key (a secret key) is used to both encrypt and decrypt electronic information. The requirement that both parties have access to the secret key is one of the main drawbacks of symmetric-key encryption, in comparison to public-key encryption (also known as asymmetric-key encryption).

Basic

String encrypted = dummyCastle.encryptSymmWith(plainText).getResult();
String decrypted = dummyCastle.decryptSymmWith(encrypted).getResult();
String decodedResult = dummyCastle.decodeWith(decrypted).toStringDecoded();

Advanced

//Prepare key
String password="Password";
dummyCastle.genSymmKeyWith(password);
//Encrypt and get the result as a safe HEX encoded string
String encrypted = dummyCastle.encryptSymmWith(plainText).getResult();
//If a raw encrypted bytes are required you may get it from the same object
byte[] encryptedDecoded = dummyCastle.getResultDecodedRaw();

//Decryption in general should be carried out using the HEX encoded string. The resulting plain text is still HEX decoded.
 String decrypted = dummyCastle.decryptSymmWith(encrypted).getResult();
 //The input for decryption may be provided through a separate method.
 dummyCastle.fromStringEncoded(encrypted);
 //Now you can decrypt the data as they are kept inside. 
String decrypted = dummyCastle.decryptSymm().getResult();

Asymmetric encryption

Public-key cryptography or asymmetric cryptography, is a cryptographic system that uses pairs of keys. Each pair consists of a public key (which may be known to others) and a private key (which may not be known by anyone except the owner). The generation of such key pairs depends on cryptographic algorithms which are based on mathematical problems termed one-way functions. Effective security requires keeping the private key private. The public key can be openly distributed without compromising security.

Basic

CryptAsymmKeysPair cryptAsymmKeysPair = dummyCastle.genAsymmKeys();
CryptAsymmPublicKey cryptAsymmPublicKey = cryptAsymmKeysPair.getCryptAsymmPublicKey();
CryptAsymmPrivateKey cryptAsymmPrivateKey = cryptAsymmKeysPair.getCryptAsymmPrivateKey();

String encrypted = dummyCastle.encryptAsymmWith(plainText, cryptAsymmPublicKey).getResult();
String decrypted = dummyCastle.decryptAsymmWith( encrypted , cryptAsymmPrivateKey).getResult();
String decodedResult=dummyCastle.decodeWith(decrypted).toStringDecoded();

Advanced

//Generate a key pair
CryptAsymmKeysPair cryptAsymmKeysPair = dummyCastle.genAsymmKeys();
//Retrieve private key for decrypting
CryptAsymmPrivateKey cryptAsymmPrivateKey = cryptAsymmKeysPair.getCryptAsymmPrivateKey();
//Retrieve the public key  
 CryptAsymmPublicKey cryptAsymmPublicKey = cryptAsymmKeysPair.getCryptAsymmPublicKey();
//Turn the key into a string for publishing and publish it somewhere on the web
String pub = cryptAsymmPublicKey.toString();
//Encrypt with the public key
encrypted = dummyCastle.encryptAsymmWith(plainText, cryptAsymmPublicKey).getResult();
//Get published key from the web and turn it into an object
cryptAsymmPrivateKey = dummyCastle.genAsymmPublicKeyWith(pub);
//Decrypt data using the private key
decrypted = dummyCastle.decryptAsymmWith(encrypted, cryptAsymmPrivateKey).getResult();

Random generation

DummyCastle makes it possible to generate random numeric and alphanumeric values. Both are always represented as strings, the numeric value can be parsed into a long though. The result is always HEX encoded.

Basic

String randomInt1 = dummyCastle.randomNumWith(8).getResultDecoded();
String randomStr1 = dummyCastle.randomStrWith(8).getResultDecoded();
String randomInt2 = dummyCastle.randomDeterministicNumWith(someRand1, 8).getResult();

Advanced

//Generates 6 characters in a deterministic manner but starts the generation from the '2' character.
//This method is a counterpart of substring method but without generating the whole 8 characters.
randomStr2 = dummyCastle.randomDeterministicStrFromWith(someRand1, 6, 2).getResult();

Hashing

Hashing maps data of any length into a fixed/determined length hash value. The library enables you to hash into a numeric(long) or string(alphanumeric) value. Both are always represented as strings, the numeric hash value can be parsed into a long though. The default length of alphanumeric value is 8. The result is always HEX encoded.

Basic

String hashed1  = dummyCastle.hashToNumWith(plainText1).getResult();
String hashed2  = dummyCastle.hashToStrWith(plainText1).getResult();

Advanced

//Hash data provided externally
String hashed1 = dummyCastle.hashToStrWith(plainText1).getResult();
//Provide data from an external source
String dummyCastle.fromStringDecoded(plainText1);
//Hash the data internally
String hashed2 = dummyCastle.hashToStr().getResult();

Shuffling

Shuffling arranges bytes in a random or deterministic order. The deterministic shuffling needs a seed data which will put the data in the same order every time it gets called.

Simple

String someRand1="aAbBcC";
String shuffled1 = dummyCastle.shuffleWith(plainText).getResultDecoded();
String shuffled2 = dummyCastle.shuffleDeterministicWith(plainText, someRand1).getResultDecoded();

Advanced

dummyCastle.fromStringDecoded(plainText);
String shuffled1 = dummyCastle.shuffle().getResultDecoded();

Obfuscation

Obfuscation is the process of creating data that is difficult to decompile, read and understand in order to protect intellectual property or other secrets, and to prevent an attacker from reverse engineering a proprietary software program.

Simple

String obfuscated = dummyCastle.obfuscateWith(plainText).getResult();
String unobfuscated = dummyCastle.unobfuscateWith(obfuscated).getResult();

Advanced

dummyCastle.fromStringDecoded(plainText);
String obfuscated = dummyCastle.obfuscate().getResult();
String unobfuscated = dummyCastle.unobfuscateWith(obfuscated).getResultDecoded();
        

##Clean up - optional

The cleaning up is not required. What it does is resetting the main value to an empty string, setting the error flag to false and resetting the exception.

dummyCastle.reset();

Test

The below tests were prepared without a use of any kind of testing framework in order to make them Java and Dart versions compatible.

Given the following global variables:

String password = "Password";
String plainText = "TestPlainText";
String plainText1 = "TestPlainText1";
String plainText2 = "TestPlainText2";
String encrypted = "";
String decrypted = "";
String hashed1 = "";
String hashed2 = "";
String decodedResult = "";
String someRand1 = "aAbBcC";
String someRand2 = "xXyYzZ";
String obfuscated = "";
String unobfuscated = "";
String shuffled1 = "";
String shuffled2 = "";
String randomInt1 = "";
String randomInt2 = "";
String randomStr1 = "";
String randomStr2 = "";
boolean verbose = true;

and the main library object:

DummyCastle dummyCastle = new DummyCastle();

as well as a helper method:

String getOpErrorStatus(DummyCastle dummyCastle) {
        return " [Error=" + dummyCastle.isError() + " " + dummyCastle.getException() + "]";
    }

we can call a set of testing methods:

/* SYMMETRIC ENCRYPTION */
testSymmEncryption();

/* ASYMMETRIC ENCRYPTION */
testAsymmEncryption();

/* HASHING */
testHashing();

/* SHUFFLING */
testShuffling();

/* OBFUSCATION */
testObfuscation();

/* RANDOM */
testRandomGeneration();

where testSymmEncryption() is:

void testSymmEncryption() {
System.out.println("***Test symmetric encryption***");
//
dummyCastle.genSymmKeyWith(password);
if (verbose)
System.out.println("Test: Symmetric key generation=" + dummyCastle.getSymmKey().toString()
        + getOpErrorStatus(dummyCastle));
//
System.out.println("*Test symmetric encryption externally*");
encrypted = dummyCastle.encryptSymmWith(plainText).getResult();
if (verbose)
System.out.println("Test: Symmetric encryption=" + encrypted + getOpErrorStatus(dummyCastle));
decrypted = dummyCastle.decryptSymmWith(encrypted).getResult();
if (verbose)
System.out.println("Test: Symmetric decryption=" + decrypted + getOpErrorStatus(dummyCastle));
decodedResult = dummyCastle.decodeWith(decrypted).toStringDecoded();
System.out.println("Test: Symmetric result=" + (decodedResult.equals(plainText) ? "PASSED" : "FAILED")
    + getOpErrorStatus(dummyCastle));

//
dummyCastle.reset();
//
dummyCastle.genSymmKeyWith(password);
if (verbose)
System.out.println("Test: Symmetric key generation=" + dummyCastle.getSymmKey().toString()
        + getOpErrorStatus(dummyCastle));
//
System.out.println("*Test symmetric encryption internally*");
dummyCastle.fromStringDecoded(plainText);
encrypted = dummyCastle.encryptSymm().getResult();
if (verbose)
System.out.println("Test: Symmetric encryption=" + encrypted + getOpErrorStatus(dummyCastle));
decrypted = dummyCastle.decryptSymm().getResult();
if (verbose)
System.out.println("Test: Symmetric decryption=" + decrypted + getOpErrorStatus(dummyCastle));
decodedResult = dummyCastle.decodeWith(decrypted).toStringDecoded();
System.out.println("Test: Symmetric result=" + ((decodedResult.equals(plainText)) ? "PASSED" : "FAILED")
    + getOpErrorStatus(dummyCastle));
dummyCastle.reset();
 }

and testAsymmEncryption() is:

void testAsymmEncryption() {
System.out.println("***Test asymmetric encryption***");
CryptAsymmKeysPair cryptAsymmKeysPair = dummyCastle.genAsymmKeys();
CryptAsymmPublicKey cryptAsymmPublicKey = cryptAsymmKeysPair.getCryptAsymmPublicKey();
CryptAsymmPrivateKey cryptAsymmPrivateKey = cryptAsymmKeysPair.getCryptAsymmPrivateKey();

System.out.println("*Test asymmetric encryption externally*");
encrypted = dummyCastle.encryptAsymmWith(plainText, cryptAsymmPublicKey).getResult();
if (verbose)
System.out.println("Test: Asymmetric encryption=" + encrypted + getOpErrorStatus(dummyCastle));
decrypted = dummyCastle.decryptAsymmWith(encrypted, cryptAsymmPrivateKey).getResult();
if (verbose)
System.out.println("Test: Asymmetric decryption=" + decrypted + getOpErrorStatus(dummyCastle));
decodedResult = dummyCastle.decodeWith(decrypted).toStringDecoded();
;
System.out.println("Test: Asymmetric result=" + (decodedResult.equals(plainText) ? "PASSED" : "FAILED")
+ getOpErrorStatus(dummyCastle));
dummyCastle.reset();

System.out.println("*Test asymmetric encryption from source*");
encrypted = "0000009a333835323632343536353337343134323232333835353032323831363039353832343031333939323839343836393334383439323230333833393938333230363530363336303034363538393736383237363931323933373331323835303938303134313731363932333435343734323137323637343136383132333435323633323438393032303232373430353438333231303534333238356b2937316a302f57140c163c11";
String pub = "3050648331079197714843623445805135130729850255102544140887224657375482563080876790127317106805275373497518298601036749587025082479587574370867084455170723=@=5046681414847334363823497680505582547008051696988249793270100134042430048998694849893001642372341723686739425690696038035592605596450556906661936335457107";
String priv = "2152374241593825319134227098618465774395685084445578076220700307631905644072705303010484875134566030047425527839702624538996411351348511657549884035109787=@=5046681414847334363823497680505582547008051696988249793270100134042430048998694849893001642372341723686739425690696038035592605596450556906661936335457107";
cryptAsymmPublicKey = dummyCastle.genAsymmPublicKeyWith(pub);
cryptAsymmPrivateKey = dummyCastle.genAsymmPrivateKeyWith(priv);

decrypted = dummyCastle.decryptAsymmWith(encrypted, cryptAsymmPrivateKey).getResult();
if (verbose)
System.out.println("Test: Asymmetric decryption=" + decrypted + getOpErrorStatus(dummyCastle));
decodedResult = dummyCastle.decodeWith(decrypted).toStringDecoded();
 
System.out.println("Test: Asymmetric descryption from source result="
+ (decodedResult.equals(plainText) ? "PASSED" : "FAILED") + getOpErrorStatus(dummyCastle));

System.out.println("*Test asymmetric encryption internally*");
dummyCastle.fromStringDecoded(plainText);
encrypted = dummyCastle.encryptAsymmWithKey(cryptAsymmPublicKey).getResult();
if (verbose)
System.out.println("Test: Symmetric encryption=" + encrypted + getOpErrorStatus(dummyCastle));
decrypted = dummyCastle.decryptAsymmWithKey(cryptAsymmPrivateKey).getResult();
if (verbose)
System.out.println("Test: Symmetric decryption=" + decrypted + getOpErrorStatus(dummyCastle));
decodedResult = dummyCastle.decodeWith(decrypted).toStringDecoded();
;
System.out.println("Test: Symmetric result=" + (decodedResult.equals(plainText) ? "PASSED" : "FAILED")
+ getOpErrorStatus(dummyCastle));
dummyCastle.reset();
}

and testHashing() is:

void testHashing() {

System.out.println("***Test hashing***");
System.out.println("*Test hashing to number*");
hashed1 = dummyCastle.hashToNumWith(plainText1).getResult();
if (verbose)
System.out.println("Test: Hashing to number 1=" + hashed1 + getOpErrorStatus(dummyCastle));
hashed2 = dummyCastle.hashToNumWith(plainText1).getResult();
if (verbose)
System.out.println("Test: Hashing to number 2=" + hashed1 + getOpErrorStatus(dummyCastle));
System.out.println("Test: Hashing to number idepotency result="
+ ((hashed1.equals(hashed2)) ? "PASSED" : "FAILED") + getOpErrorStatus(dummyCastle));

hashed2 = dummyCastle.hashToNumWith(plainText2).getResult();
if (verbose)
System.out.println("Test: Hashing to number 3=" + hashed2 + getOpErrorStatus(dummyCastle));
System.out.println("Test: Hashing to number duplication result="
+ ((!hashed1.equals(hashed2)) ? "PASSED" : "FAILED") + getOpErrorStatus(dummyCastle));

System.out.println("*Test hashing to string*");
hashed1 = dummyCastle.hashToStrWith(plainText1).getResult();
if (verbose)
System.out.println("Test: Hashing to string 1=" + hashed1 + getOpErrorStatus(dummyCastle));
hashed2 = dummyCastle.hashToStrWith(plainText1).getResult();
if (verbose)
System.out.println("Test: Hashing to string 2=" + hashed1 + getOpErrorStatus(dummyCastle));
System.out.println("Test: Hashing to string idepotency result="
+ ((hashed1.equals(hashed2)) ? "PASSED" : "FAILED") + getOpErrorStatus(dummyCastle));

hashed2 = dummyCastle.hashToStrWith(plainText2).getResult();
if (verbose)
System.out.println("Test: Hashing to string 3=" + hashed2 + getOpErrorStatus(dummyCastle));
System.out.println("Test: Hashing to string duplication result="
+ ((!hashed1.equals(hashed2)) ? "PASSED" : "FAILED") + getOpErrorStatus(dummyCastle));

System.out.println("*Test hashing to non-standart lenght string*");
hashed1 = dummyCastle.hashToStrWithTextAndLength(plainText1,20).getResult();
if (verbose)
System.out.println("Test: Hashing to non-standart string 1=" + hashed1 + getOpErrorStatus(dummyCastle));


   System.out.println("*Test hashing coherence*");
hashed1 = dummyCastle.hashToStrWith(plainText1).getResult();
if (verbose)
System.out.println("Test: Hashing to string 4=" + hashed1 + getOpErrorStatus(dummyCastle));
System.out.println("Test: Hashing to string coherence result="
+ ((hashed1.equals("091c6c3057c6665f")) ? "PASSED" : "FAILED") + getOpErrorStatus(dummyCastle));

hashed1 = dummyCastle.hashToStrWithTextAndLength(plainText1,20).getResult();
if (verbose)
System.out.println("Test: Hashing to string 5=" + hashed1 + getOpErrorStatus(dummyCastle));
System.out.println("Test: Hashing to string coherence result 2="
+ ((hashed1.equals("0bdf72e1c5734009658b0a1944d4971053a45432")) ? "PASSED" : "FAILED") + getOpErrorStatus(dummyCastle));


System.out.println("*Test hashing internally*");
hashed1 = dummyCastle.hashToStrWith(plainText1).getResult();
dummyCastle.fromStringDecoded(plainText1);
hashed2 = dummyCastle.hashToStr().getResult();
System.out.println("Test: Hashing to string internal result="
+ ((hashed1.equals(hashed2)) ? "PASSED" : "FAILED") + getOpErrorStatus(dummyCastle));

dummyCastle.reset();
}

and testShuffling() is:

void testShuffling() {
System.out.println("***Test shuffling***");
shuffled1 = dummyCastle.shuffleWith(plainText).getResultDecoded();
System.out.println("Test: Shuffling random result=" + ((shuffled1 != plainText) ? "PASSED" : "FAILED")
    + getOpErrorStatus(dummyCastle));
shuffled1 = dummyCastle.shuffleDeterministicWith(plainText, someRand1).getResultDecoded();
System.out.println("Test: Shuffling deterministic result 1=" + ((shuffled1 != plainText) ? "PASSED" : "FAILED")
    + getOpErrorStatus(dummyCastle));
shuffled2 = dummyCastle.shuffleDeterministicWith(plainText, someRand1).getResultDecoded();
System.out.println("Test: Shuffling deterministic result 2="
    + ((shuffled1.equals(shuffled2)) ? "PASSED" : "FAILED") + getOpErrorStatus(dummyCastle));
System.out.println("Test: Shuffling coherence result="
    + ((shuffled1.equals("teTTixtlPensa")) ? "PASSED" : "FAILED") + getOpErrorStatus(dummyCastle));

//
System.out.println("*Test Shuffling internally*");
dummyCastle.fromStringDecoded(plainText);
shuffled1 = dummyCastle.shuffle().getResultDecoded();
if (verbose)
System.out.println("Test: Shuffling random result=" + shuffled1 + getOpErrorStatus(dummyCastle));
System.out.println("Test: Shuffling internally result=" + ((!shuffled1.equals(plainText)) ? "PASSED" : "FAILED")
    + getOpErrorStatus(dummyCastle));
dummyCastle.reset();

}

and testObfuscation() is:

void testObfuscation() {
System.out.println("*** Test obfuscation***");
obfuscated = dummyCastle.obfuscateWith(plainText).getResult();
if (verbose)
    System.out.println("Test: obfuscation=" + obfuscated + getOpErrorStatus(dummyCastle));
unobfuscated = dummyCastle.unobfuscateWith(obfuscated).getResult();
if (verbose)
    System.out.println("Test unobfuscation=" + unobfuscated + getOpErrorStatus(dummyCastle));
System.out.println("Test: Obfuscation result=" + ((dummyCastle.toStringDecoded().equals(plainText)) ? "PASSED" : "FAILED")
                + getOpErrorStatus(dummyCastle));
dummyCastle.reset();
}

and testRandomGeneration() is:

void testRandomGeneration() {
System.out.println("*** Test random generation***");
randomInt1 = dummyCastle.randomNumWith(8).getResultDecoded();
if (verbose)
System.out.println("Test: random number=" + randomInt1 + getOpErrorStatus(dummyCastle));
randomStr1 = dummyCastle.randomStrWith(8).getResultDecoded();
if (verbose)
System.out.println("Test: random string=" + randomStr1 + " " + getOpErrorStatus(dummyCastle));
System.out.println("Test: random result=" + ((randomInt1.length() == 8) ? "PASSED" : "FAILED").toString()
+ getOpErrorStatus(dummyCastle));

System.out.println("* Test deterministic generation*");
randomInt1 = dummyCastle.randomDeterministicNumWith(someRand1, 8).getResult();
if (verbose)
System.out.println("Test: deterministic number=" + randomInt1 + " " + getOpErrorStatus(dummyCastle));
randomInt2 = dummyCastle.randomDeterministicNumWith(someRand1, 8).getResult();
if (verbose)
System.out.println("Test: deterministic number=" + randomInt1 + getOpErrorStatus(dummyCastle));
System.out.println("Test: random deterministic result="
+ ((randomInt1.equals(randomInt2)) ? "PASSED" : "FAILED") + getOpErrorStatus(dummyCastle));
System.out.println("Test: random deterministic coherence result="
+ ((randomInt1.equals("3637353832333233")) ? "PASSED" : "FAILED") + getOpErrorStatus(dummyCastle));

randomStr1 = dummyCastle.randomDeterministicStrWith(someRand1, 8).getResult();
if (verbose)
System.out.println("Test: deterministic number=" + randomStr1 + getOpErrorStatus(dummyCastle));
randomStr2 = dummyCastle.randomDeterministicStrFromWith(someRand1, 6, 2).getResult();
if (verbose)
System.out.println("Test: deterministic number from=" + randomStr2 + getOpErrorStatus(dummyCastle));
System.out.println("Test: random deterministic number from result="
+ ((randomStr1.endsWith(randomStr2)) ? "PASSED" : "FAILED") + getOpErrorStatus(dummyCastle));

dummyCastle.reset();

}

Installing

Use this package as a library

Depend on it

Run this command:

With Flutter:

 $ flutter pub add dummycastle

This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get):

dependencies:
  dummycastle: ^1.2.0

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

Import it

Now in your Dart code, you can use:

import 'package:dummycastle/pl/polinc/dummycastle/coding/Coder.dart';
import 'package:dummycastle/pl/polinc/dummycastle/coding/HexCoder.dart';
import 'package:dummycastle/pl/polinc/dummycastle/coding/HexDecoder.dart';
import 'package:dummycastle/pl/polinc/dummycastle/coding/HexEncoder.dart';
import 'package:dummycastle/pl/polinc/dummycastle/crypt/asymm/BigInteger.dart';
import 'package:dummycastle/pl/polinc/dummycastle/crypt/asymm/CryptAsymm.dart';
import 'package:dummycastle/pl/polinc/dummycastle/crypt/asymm/CryptAsymmClient.dart';
import 'package:dummycastle/pl/polinc/dummycastle/crypt/asymm/CryptAsymmKey.dart';
import 'package:dummycastle/pl/polinc/dummycastle/crypt/asymm/CryptAsymmKeys.dart';
import 'package:dummycastle/pl/polinc/dummycastle/crypt/asymm/CryptAsymmKeysPair.dart';
import 'package:dummycastle/pl/polinc/dummycastle/crypt/asymm/CryptAsymmPrivateKey.dart';
import 'package:dummycastle/pl/polinc/dummycastle/crypt/asymm/CryptAsymmPublicKey.dart';
import 'package:dummycastle/pl/polinc/dummycastle/crypt/symm/CryptClient.dart';
import 'package:dummycastle/pl/polinc/dummycastle/crypt/symm/CryptSymm.dart';
import 'package:dummycastle/pl/polinc/dummycastle/crypt/symm/CryptSymmKey.dart';
import 'package:dummycastle/pl/polinc/dummycastle/dummycastle.dart';
import 'package:dummycastle/pl/polinc/dummycastle/hash/HashClient.dart';
import 'package:dummycastle/pl/polinc/dummycastle/hash/HasherClient.dart';
import 'package:dummycastle/pl/polinc/dummycastle/hash/PermutClient.dart';
import 'package:dummycastle/pl/polinc/dummycastle/obfuscate/ObfuscateClient.dart';
import 'package:dummycastle/pl/polinc/dummycastle/random/RandomClient.dart';

Additional information

This library has an official port fo Dart/Flutter version which can be found here: https://github.com/polincdev/DummyCastle

The Dart/FLutter version is available here: https://github.com/polincdev/DummyCastle4Dart

The versions remain synced.

Author: polincdev
Source Code: https://github.com/polincdev/DummyCastle 
License: MIT

#flutter #dart #cryptography 

Dummycastle: Cryptography for Dummies
Hunter  Krajcik

Hunter Krajcik

1656726900

Einfache_krypto: RSA Cryptography Library with Ease Of Use At Its Core

einfache_krypto

RSA Cryptography library with ease of use at its core.

Hecho en 🇵🇷 por Radamés J. Valentín Reyes

Important notifications

  • Do not use any version before Version 1.0.4+2 because there were bugs in them and a lot has changed since.

API functions

Note: You must always convert your data to a List in order to pass it as argument. securityLevel must always be greater than or equal to one. To decipher content you always need to use the same password and security level with which you encrypted it.

Ciphering:

Einfache_Krypto.cipher(data: data,password: password);

Deciphering:

Einfache_Krypto.decipher(data: x, password: password);

Key Generation:

Returns an object with all of the RSA required variable values. You can access such values using the dot notation on the object.

CipherGen(seed: password);

Adaptable password generation:

Generates a password that adapts to the data so that it can completely cypher it by generating a password that avoids getting problems where data values are larger than the modulo mentioned in the technical limitations section. Its the smallest number that can be used as password seed on the CipherGen class in order to successfully cipher the data.

Einfache_Krypto.adaptivePasswordGeneration(data: myData);//Returns the password as an int

Asymmetric Encryption:

Einfache_Krypto.asymmetricCipher(data: myData, publicKey: publicKey, modulo: modulo);

Asymmetric Decryption:

Einfache_Krypto.asymmetricDecipher(data: encryptedData, privateKey: privateKey, modulo: modulo);

Catching errors

try{
  //Library operations go here
  CipherGen(seed: 12);
}catch(err){
   //Error handling goes here
  if(err == CipherError.bigPassword){
      //Do this
  }else{
      //Do that
  }
}

Library Use Example

Symmetric Encryption and Decryption Sample

//Define a password
int password = 2434;
//Convert the data to a list of integers
List<int> data = 'Hello Cyphered World'.codeUnits;
//Print the original text
print('Original: ${String.fromCharCodes(data)}');
//Cypher the data
List<int> x = Einfache_Krypto.cipher(data: data,password: password);
//Print the cyphered data
print('Cyphered: ${String.fromCharCodes(x)}');
//Decipher the data
List<int> y = Einfache_Krypto.decipher(data: x, password: password);
//Print decyphered data
print('Deciphered: ${String.fromCharCodes(y)}');

Key Generation:

All of the variables required for the RSA method shown in the Eddie Woo videos are generated and available through this object. All of the values are generated using an integer as seed.

//Generate Key pairs
CipherGen generated = CipherGen(seed: password);
//Encryption key
print(generated.e);
//Mod value(N variable)
print(generated.N);

Advanced Key Generation:

A class that provides a more granular control over key generation(CipherGen class is a simplified version of this).

Save the object into a variable:

//Save the class in a variable
AdvancedCipherGen key = AdvancedCipherGen();

Step 1:

Generate the possible encryption key values based on the provided p and q variable values

//Perform the first step to generate the possible encryption key values for the given p q
List<int> possibleE = key.step1(p: 17, q: 22);

Step 2: (Last step, key is ready to be used)

Select the encryption key by providing the index of the desired key.

//Perform second step
key.step2(eIndex: (possibleE.length - 1).floor());

Full demo:

//Save the class in a variable
AdvancedCipherGen key = AdvancedCipherGen();
//Perform the first step to generate the possible encryption key values for the given p q
List<int> possibleE = key.step1(p: -5, q: 22);
//Encryption keys to pick from
print(possibleE);
//Perform second step
key.step2(eIndex: (possibleE.length - 1).floor());
print("Encryption key: ${key.e}");
print("Decryption key: ${key.d}");
print("Phi(N): ${key.phi}");
print("Modulo: ${key.N}");

Adaptive Password:

Note: You can use the returned password number or a number bigger that itself to guarantee that all your content can be encrypted.

List<int> data = 'Hello from Puerto Rico Cyphered World'.codeUnits;
int password = Einfache_Krypto.adaptivePasswordGeneration(data);
List<int> encrypted = Einfache_Krypto.cipher(data: data, password: password);
List<int> decrypted = Einfache_Krypto.decipher(data: encrypted, password: password);
print('Generated adaptive password is "$password"');
print('Decrypted test: ${String.fromCharCodes(decrypted)}');

Asymmetric Encryption Sample:

Note: You can use your previously generated private and public keys with this methods. Using CipherGen() to generate the keys is completely unnecessary and its used in this example just to generate a valid encryption decryption key pairs.

List<int> myData = 'Hallo Freunde'.codeUnits;
print('Original: ${String.fromCharCodes(myData)}');
CipherGen generatedKeys = CipherGen(seed: Einfache_Krypto.adaptivePasswordGeneration(myData));
List<int> encrypted = Einfache_Krypto.asymmetricCipher(data: myData, publicKey: generatedKeys.e, modulo: generatedKeys.N);
List<int> decrypted = Einfache_Krypto.asymmetricDecipher(data: encrypted, privateKey: generatedKeys.d, modulo: generatedKeys.N);
print('Asymetric decryption result: ${String.fromCharCodes(decrypted)}');

Installing

Use this package as a library

Depend on it

Run this command:

With Dart:

 $ dart pub add einfache_krypto

With Flutter:

 $ flutter pub add einfache_krypto

This will add a line like this to your package's pubspec.yaml (and run an implicit dart pub get):

dependencies:
  einfache_krypto: ^1.0.4+2

Alternatively, your editor might support dart pub get or flutter pub get. Check the docs for your editor to learn more.

Import it

Now in your Dart code, you can use:

import 'package:einfache_krypto/einfache_krypto.dart';

References

I was able to understand the RSA method and create this library thanks to this marvelous learning resource. Check out eddie woo's YouTube channel.

I managed to find the RSA decryption key thanks to this stackoverflow question/thread. 💘 Stack Overflow.

Technical Limitations

Note: Take into account that all data is always read by the program as numbers. Your password is a seed for all of the RSA variables that need to be generated.

  • You cannot encrypt a number greater than the modulo. Modulo is generated on the background using your password(seed) or p and q values if you are using AdvancedKeyGen(modulo(variable N) is the product of p and q). After generating the key you can access all of the variables through dot notation on the key object.
    • [Explanaintion on this link](https://crypto.stackexchange.com/questions/3798/why-rsa-cant-handle-numbers-above-76/3800#:~:text=By definition you cannot encrypt,modulo n which loses information.&text=So with your n%3D77,equal in Z%2FnZ.)
  • If the password is too small. The range to pick a number for the variable e may be so small that it may not contain any number that meets the necessary criteria to use RSA encryption. Example: using 12 for the password parameter on CipherGen will throw you an error using this library.
  • Using as password extremely big numbers may generate numbers that are too big for your computer/device or client's computer/device to handle, because RSA relies on raising the numbers they will grow exponentially which means that your device may not be able to perform the necessary computation. In such case the library will throw an error.
  • Even though the RSA cryptography method requires you to provide two prime numbers for p and q this library takes care of converting any input into prime numbers so that you don't have to care about that(any integer is a valid input).

Original article source at: https://pub.dev/packages/einfache_krypto 

#flutter #dart #cryptography 

Einfache_krypto: RSA Cryptography Library with Ease Of Use At Its Core
Mike  Kozey

Mike Kozey

1656181800

Durt: Dart Lib for Duniter Cryptography and APIs

Dart lib for duniter cryptography and APIs

Description

Here is the common library which will facilitate your creation of Ğ1 libre currency client in Dart/Flutter, or any other cryptocurrency generated by Duniter.

For the moment, it only contains the methods essential for the operation of the Ğecko client. Other methods will emerge there depending on the needs of Ğecko or any other client based on this library.

Actual content

Crypto

  • Generated BIP39 mnemonic in english, french, spanish or italian
  • Create HD wallets based on BIP32 ED25519 cryptography
  • Create Cesium type wallets with salt + password, based on scrypt and ED25519 cryptography
  • Generate DEWIF encrypted wallet, using scrypt and XOR cypher as describe in RFC 13. Ready to store on filesystem.
  • Decrypt DEWIF wallets with the given correct secret code
  • Sign and verify signature for both HD wallets and Cesium wallets

GVA

  • Get account balance
  • Get account username
  • Pay with HD wallets
  • Pay with Cesium wallets

Cesium+

  • TODO

Installing

Use this package as a library

Depend on it

Run this command:

With Dart:

 $ dart pub add durt

With Flutter:

 $ flutter pub add durt

This will add a line like this to your package's pubspec.yaml (and run an implicit dart pub get):

dependencies:
  durt: ^0.1.6

Alternatively, your editor might support dart pub get or flutter pub get. Check the docs for your editor to learn more.

Import it

Now in your Dart code, you can use:

import 'package:durt/durt.dart';

example/durt_example.dart

import 'package:durt/durt.dart';
import 'dart:typed_data';

Future<void> main() async {
  const String mnemonicLang = 'french';
  const int derivation = 2;

  print('------------------\n HD Wallet example\n------------------\n');
  final mnemonic = generateMnemonic(lang: mnemonicLang);

  // Build HdWallet object from mnemonic
  HdWallet _hdWallet = HdWallet.fromMnemonic(mnemonic);

  // Get pubkey of derivation number $derivation
  String pubkey = _hdWallet.getPubkey(harden(derivation));

  String message = "blabla test";

  // Sign the message with derivation number $derivation
  final signature = _hdWallet.sign(message, derivation: derivation);
  bool isOK = _hdWallet.verifySign(message, signature, derivation: derivation);

  print('Mnemonic: ' + mnemonic);
  print('Pubkey N°$derivation: ' + pubkey);
  print('Is signature OK ? : ' + isOK.toString());

  print('\n------------------\n DEWIF example\n------------------\n');

  final _dewif = Dewif();

  final _dewifData =
      await _dewif.generateDewif(mnemonic, 'ABCDE', lang: mnemonicLang);
  print(_dewifData.dewif);

  String? decryptedDewif;
  try {
    decryptedDewif =
        _dewif.mnemonicFromDewif(_dewifData.dewif, 'ABCDE', lang: mnemonicLang);
    print('Unlock: ' + decryptedDewif);
  } on ChecksumException {
    print('Bad secret code');
  } catch (e) {
    print(e);
  }

  print(
      '\n------------------\n Cesium wallet generation example\n------------------\n');

  // Build Cesium wallet from salt + password
  final cesiumWallet =
      CesiumWallet('myCesiumID', 'myCesiumPassword'); // Cesium ID + Password

  print('Seed: ' + cesiumWallet.seed.toString());
  print('Pubkey: ' + cesiumWallet.pubkey);

  final signatureCesium = cesiumWallet.sign(message);
  bool isOKCesium = cesiumWallet.verifySign(message, signatureCesium);

  // Is signature valid ?
  print(isOKCesium); //true

  print('\n------------------\n Dewif for Cesium wallet\n------------------\n');

  final _dewifCesiumData =
      await _dewif.generateCesiumDewif(cesiumWallet.seed, 'FGHIJ');

  Uint8List? decryptedCesiumDewif;
  try {
    decryptedCesiumDewif =
        _dewif.cesiumSeedFromDewif(_dewifCesiumData.dewif, 'FGHIJ');
    print('Unlock: ' + decryptedCesiumDewif.toString());
  } on ChecksumException {
    print('Bad secret code');
  } catch (e) {
    print(e);
  }

  // Rebuild Cesium wallet, but this time from seed
  final reCesiumWallet = CesiumWallet.fromSeed(decryptedCesiumDewif!);
  print('Pubkey: ' + reCesiumWallet.pubkey);
}

Original article source at: https://pub.dev/packages/durt 

#flutter #dart #cryptography 

Durt: Dart Lib for Duniter Cryptography and APIs
Oral  Brekke

Oral Brekke

1655060400

Elliptic: Fast Elliptic Curve Cryptography in Plain Javascript

Elliptic 

Fast elliptic-curve cryptography in a plain javascript implementation.

Incentive

ECC is much slower than regular RSA cryptography, the JS implementations are even more slower.

Benchmarks

$ node benchmarks/index.js
Benchmarking: sign
elliptic#sign x 262 ops/sec ±0.51% (177 runs sampled)
eccjs#sign x 55.91 ops/sec ±0.90% (144 runs sampled)
------------------------
Fastest is elliptic#sign
========================
Benchmarking: verify
elliptic#verify x 113 ops/sec ±0.50% (166 runs sampled)
eccjs#verify x 48.56 ops/sec ±0.36% (125 runs sampled)
------------------------
Fastest is elliptic#verify
========================
Benchmarking: gen
elliptic#gen x 294 ops/sec ±0.43% (176 runs sampled)
eccjs#gen x 62.25 ops/sec ±0.63% (129 runs sampled)
------------------------
Fastest is elliptic#gen
========================
Benchmarking: ecdh
elliptic#ecdh x 136 ops/sec ±0.85% (156 runs sampled)
------------------------
Fastest is elliptic#ecdh
========================

API

ECDSA

var EC = require('elliptic').ec;

// Create and initialize EC context
// (better do it once and reuse it)
var ec = new EC('secp256k1');

// Generate keys
var key = ec.genKeyPair();

// Sign the message's hash (input must be an array, or a hex-string)
var msgHash = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];
var signature = key.sign(msgHash);

// Export DER encoded signature in Array
var derSign = signature.toDER();

// Verify signature
console.log(key.verify(msgHash, derSign));

// CHECK WITH NO PRIVATE KEY

var pubPoint = key.getPublic();
var x = pubPoint.getX();
var y = pubPoint.getY();

// Public Key MUST be either:
// 1) '04' + hex string of x + hex string of y; or
// 2) object with two hex string properties (x and y); or
// 3) object with two buffer properties (x and y)
var pub = pubPoint.encode('hex');                                 // case 1
var pub = { x: x.toString('hex'), y: y.toString('hex') };         // case 2
var pub = { x: x.toBuffer(), y: y.toBuffer() };                   // case 3
var pub = { x: x.toArrayLike(Buffer), y: y.toArrayLike(Buffer) }; // case 3

// Import public key
var key = ec.keyFromPublic(pub, 'hex');

// Signature MUST be either:
// 1) DER-encoded signature as hex-string; or
// 2) DER-encoded signature as buffer; or
// 3) object with two hex-string properties (r and s); or
// 4) object with two buffer properties (r and s)

var signature = '3046022100...'; // case 1
var signature = new Buffer('...'); // case 2
var signature = { r: 'b1fc...', s: '9c42...' }; // case 3

// Verify signature
console.log(key.verify(msgHash, signature));

EdDSA

var EdDSA = require('elliptic').eddsa;

// Create and initialize EdDSA context
// (better do it once and reuse it)
var ec = new EdDSA('ed25519');

// Create key pair from secret
var key = ec.keyFromSecret('693e3c...'); // hex string, array or Buffer

// Sign the message's hash (input must be an array, or a hex-string)
var msgHash = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];
var signature = key.sign(msgHash).toHex();

// Verify signature
console.log(key.verify(msgHash, signature));

// CHECK WITH NO PRIVATE KEY

// Import public key
var pub = '0a1af638...';
var key = ec.keyFromPublic(pub, 'hex');

// Verify signature
var signature = '70bed1...';
console.log(key.verify(msgHash, signature));

ECDH

var EC = require('elliptic').ec;
var ec = new EC('curve25519');

// Generate keys
var key1 = ec.genKeyPair();
var key2 = ec.genKeyPair();

var shared1 = key1.derive(key2.getPublic());
var shared2 = key2.derive(key1.getPublic());

console.log('Both shared secrets are BN instances');
console.log(shared1.toString(16));
console.log(shared2.toString(16));

three and more members:

var EC = require('elliptic').ec;
var ec = new EC('curve25519');

var A = ec.genKeyPair();
var B = ec.genKeyPair();
var C = ec.genKeyPair();

var AB = A.getPublic().mul(B.getPrivate())
var BC = B.getPublic().mul(C.getPrivate())
var CA = C.getPublic().mul(A.getPrivate())

var ABC = AB.mul(C.getPrivate())
var BCA = BC.mul(A.getPrivate())
var CAB = CA.mul(B.getPrivate())

console.log(ABC.getX().toString(16))
console.log(BCA.getX().toString(16))
console.log(CAB.getX().toString(16))

NOTE: .derive() returns a BN instance.

Supported curves

Elliptic.js support following curve types:

  • Short Weierstrass
  • Montgomery
  • Edwards
  • Twisted Edwards

Following curve 'presets' are embedded into the library:

  • secp256k1
  • p192
  • p224
  • p256
  • p384
  • p521
  • curve25519
  • ed25519

NOTE: That curve25519 could not be used for ECDSA, use ed25519 instead.

Implementation details

ECDSA is using deterministic k value generation as per RFC6979. Most of the curve operations are performed on non-affine coordinates (either projective or extended), various windowing techniques are used for different cases.

All operations are performed in reduction context using bn.js, hashing is provided by hash.js

Related projects

  • eccrypto: isomorphic implementation of ECDSA, ECDH and ECIES for both browserify and node (uses elliptic for browser and secp256k1-node for node)

NOTE: Please take a look at http://safecurves.cr.yp.to/ before choosing a curve for your cryptography operations.

Author: indutny
Source Code: https://github.com/indutny/elliptic 
License: MIT License

#node #nodejs #cryptography #javascript 

Elliptic: Fast Elliptic Curve Cryptography in Plain Javascript
Rocio  O'Keefe

Rocio O'Keefe

1653380715

Flutter_micro_ecc: Micro-ecc Plugin for Flutter

flutter_micro_ecc

micro-ecc plugin for Flutter.

Alpha version

This library is actively developed alongside production apps, and the API will evolve as we continue our way to version 1.0.

Please be fully prepared to deal with breaking changes. This package must be tested on a real device.

Need a API which is currently unavailable? Please raise a issue. PRs are also appreciated.


Android NDK is needed for using this library on Android.


Features

Curves

  • SECP160R1
  • SECP192R1
  • SECP224R1
  • SECP256R1
  • SECP256K1

Operations

  • Generate Key Pair
  • Compute shared secret

Usage

Selecting a curve

final curve = EcdhCurve.SECP256R1;

Generating a KeyPair

final Ecdh ecdh = Ecdh();
EcdhKeyPair _alice = _ecdh.generateKeyPair(_curve);

Computing the shared secret

final Ecdh ecdh = Ecdh();
Uint8List _aliceSharedSecret = _ecdh.computeSharedSecret(_alice.privateKey, _bob.publicKey, _curve);

Example Application

Generate a keypair by clicking on the Generate button.

  • Compute the shared secret by clicking on the Compute button.

  • The ✅ indicates the shared secret on both the nodes is equal.

Notes

I developed this library because I could not find any decent clean solution to facilitate the ECDH key exchange. The functionality may still be limited though. Please feel free to contribute to this library, in case you find any functionality is missing.

Author: Swanav
Source Code: https://github.com/swanav/flutter_micro_ecc 
License: MIT license

#dart #flutter #cryptography 

Flutter_micro_ecc: Micro-ecc Plugin for Flutter
Awesome  Rust

Awesome Rust

1653228300

Schnorr VRFs and Signatures on The Ristretto Group

schnorrkel

Schnorrkel implements Schnorr signature on Ristretto compressed Ed25519 points, as well as related protocols like HDKD, MuSig, and a verifiable random function (VRF).

Ristretto implements roughly section 7 of Mike Hamburg's Decaf paper to provide the 2-torsion free points of the Ed25519 curve as a prime order group. (related)

We employ the merlin strategy of type specific hashing methods with sound domain separation. These wrap Mike Hamburg's STROBE128 construction for symmetric cryptography, itself based on Keccak.

In practice, all our methods consume either a merlin::Transcript which developers create handily by feeding data to context specific builders. We do however also support &mut merlin::Transcript like the merlin crate prefers. We shall exploit this in future to adapt schnorrkel to better conform with the dalek ecosystem's zero-knowledge proof tooling.

We model the VRF itself on "Making NSEC5 Practical for DNSSEC" by Dimitrios Papadopoulos, Duane Wessels, Shumon Huque, Moni Naor, Jan Včelák, Leonid Rezyin, andd Sharon Goldberg. We note the V(X)EdDSA signature scheme by Trevor Perrin at is basically identical to the NSEC5 construction. Also, the VRF supports individual signers merging numerous VRF outputs created with the same keypair, which parallels the "DLEQ Proofs" and "Batching the Proofs" sections of "Privacy Pass - The Math" by Alex Davidson, and "Privacy Pass: Bypassing Internet Challenges Anonymously" by Alex Davidson, Ian Goldberg, Nick Sullivan, George Tankersley, and Filippo Valsorda.

Aside from some naive sequential VRF construction, we currently only support the three-round MuSig for Schnorr multi-signatures, due to all other Schnorr multi-signatures being somewhat broken. In future, we should develop secure schemes like mBCJ from section 5.1 starting page 21 of https://eprint.iacr.org/2018/417 however mBCJ itself works by proof-of-possession, while a delinearized variant sounds more applicable.

There are partial bindings for C, JavaScript, and Python as well.

Download Details:
Author: w3f
Source Code: https://github.com/w3f/schnorrkel
License: BSD-3-Clause license

#rust  #rustlang  #crypto  #cryptography 

Schnorr VRFs and Signatures on The Ristretto Group
Awesome  Rust

Awesome Rust

1653213600

A Random.org Client Library for Rust

random.org

A https://random.org client library. The randomness comes from atmospheric noise, which for many purposes is better than the pseudo-random number algorithms typically used in computer programs.

Status

Everything is implemented. Note, that the random.org service API is at beta stage of development, however the library will try to be up-to-date.

The documentation

The documentation which may help you using this library.

Implementation

  • Immutable interface, no need to synchronize, thread-safe (Sync and Send).
  • No unsafe blocks.
  • reqwest crate is used for performing requests.
  • chrono for dates.
  • serde for serialization and deserialization.

Features

  • rand feature which provides the rand_core::RngCore trait implementation for the Random struct and adds new FallibleRandom<T: rand_core::RngCore> structure for better random generation UX.

Usage

Start by creating Random instance and perform needed operations after.

extern crate randomorg;

fn main() {
    use randomorg::Random;
    let r = Random::new("API KEY HERE");
    // A method-call way:
    println!("Result: {:?}", r.generate_integers(-100, 100, 15, true));
    // A lazy request builder way:
    let random_data = r.request_integers().min(0).max(100).limit(5).collect::<Vec<i32>>();
    println!("Random integers: {:?}", random_data);
}

With the rand feature you can also use it that way:

extern crate randomorg;

fn main() {
    use rand_core::RngCore;
    use randomorg::Random;
   
    let mut random = Random::new("API KEY HERE");
    let mut key = [0u8; 16];
    random.fill_bytes(&mut key);
    let random_u64 = random.next_u64();
}

Download Details:
Author: vityafx
Source Code: https://github.com/vityafx/randomorg
License: MIT license

#rust  #rustlang  #crypto  #cryptography 

A Random.org Client Library for Rust
Awesome  Rust

Awesome Rust

1653202500

Rust Openssl: OpenSSL Bindings for Rust

rust-openssl

OpenSSL bindings for the Rust programming language.

Documentation.

Release Support

The current supported release of openssl is 0.10 and openssl-sys is 0.9.

New major versions will be published at most once per year. After a new release, the previous major version will be partially supported with bug fixes for 3 months, after which support will be dropped entirely.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed under the terms of both the Apache License, Version 2.0 and the MIT license without any additional terms or conditions.

Download Details:
Author: sfackler
Source Code: https://github.com/sfackler/rust-openssl
License:

#rust  #rustlang  #crypto  #cryptography 

Rust Openssl: OpenSSL Bindings for Rust
Awesome  Rust

Awesome Rust

1653195180

Rust Native Tls: Bindings for Native TLS Libraries

rust-native-tls

Documentation

An abstraction over platform-specific TLS implementations.

Specifically, this crate uses SChannel on Windows (via the schannel crate), Secure Transport on macOS (via the security-framework crate), and OpenSSL (via the openssl crate) on all other platforms.

Installation

# Cargo.toml
[dependencies]
native-tls = "0.2"

Usage

An example client looks like:

extern crate native_tls;

use native_tls::TlsConnector;
use std::io::{Read, Write};
use std::net::TcpStream;

fn main() {
    let connector = TlsConnector::new().unwrap();

    let stream = TcpStream::connect("google.com:443").unwrap();
    let mut stream = connector.connect("google.com", stream).unwrap();

    stream.write_all(b"GET / HTTP/1.0\r\n\r\n").unwrap();
    let mut res = vec![];
    stream.read_to_end(&mut res).unwrap();
    println!("{}", String::from_utf8_lossy(&res));
}

To accept connections as a server from remote clients:

extern crate native_tls;

use native_tls::{Identity, TlsAcceptor, TlsStream};
use std::fs::File;
use std::io::{Read};
use std::net::{TcpListener, TcpStream};
use std::sync::Arc;
use std::thread;

fn main() {
    let mut file = File::open("identity.pfx").unwrap();
    let mut identity = vec![];
    file.read_to_end(&mut identity).unwrap();
    let identity = Identity::from_pkcs12(&identity, "hunter2").unwrap();

    let acceptor = TlsAcceptor::new(identity).unwrap();
    let acceptor = Arc::new(acceptor);

    let listener = TcpListener::bind("0.0.0.0:8443").unwrap();

    fn handle_client(stream: TlsStream<TcpStream>) {
        // ...
    }

    for stream in listener.incoming() {
        match stream {
            Ok(stream) => {
                let acceptor = acceptor.clone();
                thread::spawn(move || {
                    let stream = acceptor.accept(stream).unwrap();
                    handle_client(stream);
                });
            }
            Err(e) => { /* connection failed */ }
        }
    }
}

Download Details:
Author: sfackler
Source Code: https://github.com/sfackler/rust-native-tls
License: View license

#rust  #rustlang  #crypto  #cryptography 

Rust Native Tls: Bindings for Native TLS Libraries