Fuel Crypto
Fuel cryptographic primitives.
Fuel cryptographic primitives.
Secp contains two classes of signatures: recoverable and unrecoverable.
Prior to this commit, only the recoverable variant was used. However, the consensus will require signature verification, so the introduction of the two classes of signatures is required.
Signing with private key of validator is needed in a few places:
We would like to have only one place where we load private key, and that place should have the ability to sign arbitrary hash that it receives from other parts of code.
The proposed way is to have tokio::sync::mpsc
for incoming requests that would contain tokio::sync::oneshot
to return signature in that way there is no exposing of secret info.
mnemonics aren't exclusive to SDK/Wallet use-cases, so to avoid requiring the whole SDK we should move core logic related to mnemonic->SecretKey utilities to fuel-crypto.
cc @digorithm
We used types from third party libraries in our APIs which weren't re-exported. This means consumers of the library would have to include these same deps with matching versions in their own crates to use the secret key mnemonic api.
Full Changelog: https://github.com/FuelLabs/fuel-crypto/compare/v0.5.0...v0.6.0
Closes https://github.com/FuelLabs/fuel-crypto/issues/27.
Note that these changes include some dependencies updates that were forced onto us because of conflicting deps' versions in the bip32/bip39 crates.
With these dependencies updates, some updates on our end had to be done as well. Small things such as replacing deprecated methods with new ones, etc.
enhancementThe secp256k1 provider shouldn't be instantiated on every request. Instead, it should be instantiated once, with a lazy strategy, and made available for signature requests.
This commit introduces lazy_static
to achieve that. Lazy is still
experimental in std
, so we need to wait for its stabilization before
requiring it.
In order to increase the robustness of the secp provider, we introduce
rand-std
for secp256k1
. This feature will boost the entropy of the
blinders, further protecting the implementation from side-channel
attacks. This will not remove the deterministic nonce requirement, as
defined in the RFC-6979 and the fuel crypto specs.
Include benchmarks comparing fuel-crypto
, secp256k1
and k256
Resolves #3
enhancementLeverage special nightly features enabled on docs.rs which allow denoting feature flags in our docs.
To test out the docs as docs.rs would render them use:
RUSTDOCFLAGS="--cfg docsrs" cargo +nightly doc --all-features --open
Hasher is a cryptographic secure hasher and is allowed to produce signature inputs.
Signatures are secure only if the input is pre-image checked and non-malleable; this is a hard requirement for any signature protocol.
enhancementEven though this crate doesn't actually use anything in the new fuel-types
version, it's needed in order to prevent crate version mismatch downstream.
Signer can be represented as trait in no-std
without a provided
implementation.
This is desirable to define the abstraction of the trait in no-std
consumers such as fuel-bft
.
This PR builds upon #26 and @vlopes11's comment to actually make WASM builds of fuel-crypto
meaningfully usable. It requires reorganization of code in #[cfg(feature = "std")]
blocks, as WASM is a no-std environment.
I imagine this PR to be unpleasant to review through diffs, so I'll list what methods were made available here when it's done™.
Currently we use raw uncompressed 64 bytes. To get 32 bytes, we hash the affine representation of the point.
However, we might be able to store the 32 bytes in compressed form. This will allow us to skip the hash and consume less bytes of storage, since the public key will already be a 32 bytes representation that can be used as address.
The compressed point holds an extra byte to encode the parity of elements.
As in sec1-v2, we might be able to use the last bit of n[32]
to encode that information and then apply 2.3.4.2.3 mutation. However, that needs to be confirmed.
Other point to check is the fuel specs and fuels implementation: https://github.com/FuelLabs/fuel-crypto/pull/9#issuecomment-1039701064
All of these new-type passthrough methods (Deref, AsRef, Into, From, LowerHex, UpperHex, etc) could be automatically generated using the derive_more crate.
it supports no_std out of the box
Originally posted by @Voxelot in https://github.com/FuelLabs/fuel-crypto/pull/2#discussion_r801152338
enhancement good first issue help wanted tech-debtThis seems quite costly to exhaustively fuzz the entire search space every test run. Using prop-tests we could randomly sample the distribution on each test run and easily track which input params cause a failure:
use proptest::prelude::{
prop::test_runner::{RngAlgorithm, TestRng}, *,
};
prop_compose! {
fn arb_rng()(
bytes: [u8; 32],
) -> TestRng {
TestRng::from_seed(RngAlgorithm::ChaCha, &bytes)
}
}
proptest! {
#![proptest_config(ProptestConfig::with_cases(50))]
#[test]
fn corrupted_signature(
mut rng in arb_rng(),
position in 0..Signature::LEN,
bit in 0..7,
) {
let message = b"When life itself seems lunatic, who knows where madness lies?";
let message = Message::new(message);
let secret = SecretKey::random(&mut rng);
let public = secret.public_key();
let signature = Signature::sign(&secret, &message);
// Tamper a random bit of the signature
//
// The recover and verify operations should fail in all cases.
let mut s = signature;
let m = 1u8 << bit;
s.as_mut()[position] ^= m;
// check recover
match s.recover(&message) {
Ok(pk) => assert_ne!(public, pk),
Err(Error::InvalidSignature) => (),
Err(e) => panic!("Unexpected error: {}", e),
}
// check verify
assert!(s.verify(&public, &message).is_err());
}
#[test]
fn corrupted_public_key(
mut rng in arb_rng(),
position in 0..PublicKey::LEN,
bit in 0..7,
) {
let message = b"When life itself seems lunatic, who knows where madness lies?";
let message = Message::new(message);
let secret = SecretKey::random(&mut rng);
let mut public = secret.public_key();
let signature = Signature::sign(&secret, &message);
// Tamper a random bit of the public key.
//
// The verify operations should fail in all cases.
let m = 1u8 << bit;
public.as_mut()[position] ^= m;
assert!(signature.verify(&public, &message).is_err());
}
}
Originally posted by @Voxelot in https://github.com/FuelLabs/fuel-crypto/pull/2#discussion_r801197967
enhancement good first issue help wantedTo simplify the initial implementation, we are using a plain recover for the verify operation.
However, recover
is more expensive than verify
. After https://github.com/FuelLabs/fuel-crypto/issues/3 , we should compare the performance gain of using native verify
instead of recover, pk == pk_p
The pseudocode for the native verify with secp256k1
backend is:
pub fn verify(mut self, pk: &PublicKey, message: &Message) -> Result<(), Error> {
self.truncate_recovery_id();
let signature = Secp256k1Signature::from_compact(self.as_ref())?;
let message = message.to_secp();
let pk = pk.to_secp()?;
Secp256k1::verification_only().verify(&message, &signature, &pk)?;
Ok(())
}
enhancement good first issue help wanted
Full Changelog: https://github.com/FuelLabs/fuel-crypto/compare/v0.6.1...v0.6.2
Source code(tar.gz)SecretKey is now zeroed out when dropped
Source code(tar.gz)Full Changelog: https://github.com/FuelLabs/fuel-crypto/compare/v0.5.0...v0.6.0
Source code(tar.gz)Full Changelog: https://github.com/FuelLabs/fuel-crypto/compare/v0.4.2...v0.5.0
Source code(tar.gz)From<Hasher>
to signature Message
by @vlopes11 in https://github.com/FuelLabs/fuel-crypto/pull/18Full Changelog: https://github.com/FuelLabs/fuel-crypto/compare/v0.4.1...v0.4.2
Source code(tar.gz)Full Changelog: https://github.com/FuelLabs/fuel-crypto/compare/v0.4.0...v0.4.1
Source code(tar.gz)Signer
to no-std
by @vlopes11 in https://github.com/FuelLabs/fuel-crypto/pull/12Full Changelog: https://github.com/FuelLabs/fuel-crypto/compare/v0.3.0...v0.4.0
Source code(tar.gz)Signer
trait by @vlopes11 in https://github.com/FuelLabs/fuel-crypto/pull/9Full Changelog: https://github.com/FuelLabs/fuel-crypto/compare/v0.2.0...v0.3.0
Source code(tar.gz)Full Changelog: https://github.com/FuelLabs/fuel-crypto/compare/v0.1.0...v0.2.0
Source code(tar.gz)Full Changelog: https://github.com/FuelLabs/fuel-crypto/commits/v0.1.0
Source code(tar.gz)Lockstitch is an incremental, stateful cryptographic primitive for symmetric-key cryptographic operations (e.g. hashing, encryption, message authentication codes, and authenticated encryption) in complex protocols.
Rust DjangoHashers A Rust port of the password primitives used in Django Project. Django's django.contrib.auth.models.User class has a few methods to
Rust DjangoHashers A Rust port of the password primitives used in Django Project. Django's django.contrib.auth.models.User class has a few methods to
Themis provides strong, usable cryptography for busy people General purpose cryptographic library for storage and messaging for iOS (Swift, Obj-C), An
Rust-Crypto A (mostly) pure-Rust implementation of various common cryptographic algorithms. Rust-Crypto seeks to create practical, auditable, pure-Rus
sodiumoxide |Crate|Documentation|Gitter| |:---:|:-----------:|:--------:|:-----:|:------:|:----:| |||| NaCl (pronounced "salt") is a new easy-to-use h
RustCrypto: hashes Collection of cryptographic hash functions written in pure Rust. All algorithms reside in the separate crates and implemented using
Trussed® Modern Cryptographic Firmware Status Very much WIP. Actively developed. Unstable APIs.
secrets secrets is a library to help Rust programmers safely held cryptographic secrets in memory. It is mostly an ergonomic wrapper around the memory
rncryptor Rust Implementation of the RNCryptor spec This library implements the specification for the RNCryptor encrypted file format by Rob Napier. d
subtle Pure-Rust traits and utilities for constant-time cryptographic implementations. It consists of a Choice type, and a collection of traits using
Fiat-Crypto: Synthesizing Correct-by-Construction Code for Cryptographic Primitives Building This repository requires Coq 8.11 or later. Note that if
RustCrypto: signatures Support for digital signatures, which provide authentication of data using public-key cryptography. All algorithms reside in th
BLAKE3 is a cryptographic hash function that is: Much faster than MD5, SHA-1, SHA-2, SHA-3, and BLAKE2. Secure, unlike MD5 and SHA-1. And secure again
Fastmurmur3 Murmur3 is a fast, non-cryptographic hash function. fastmurmur3 is, in my testing, the fastest implementation of Murmur3. Usage let bytes:
What is it? Dexios-Core is a library used for managing cryptographic functions and headers that adhere to the Dexios format. Security Dexios-Core uses
[fastcrypto] fastcrypto is a common cryptography library used in software at Mysten Labs. It is published as an independent crate to encourage reusabi
ethers-signer-factory ethers-signer-factory is a Rust crate that provides functions for key derivation and signing of Ethereum transactions and messag
noncrypto-digests Expose various non-cryptographic hashing functions with Digest traits. This allows users to use any hashing function with the same t