Skip to content

Commit

Permalink
Merge pull request #73 from paritytech/develop
Browse files Browse the repository at this point in the history
Cumulative develop branch update
  • Loading branch information
sorpaas authored Sep 14, 2021
2 parents c0def35 + 765b291 commit 54c7ccd
Show file tree
Hide file tree
Showing 12 changed files with 122 additions and 27 deletions.
8 changes: 7 additions & 1 deletion .github/workflows/clippy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,10 @@ jobs:
with:
command: clippy
toolchain: stable
args: --all --all-features
args: --all
- name: Checking clippy
uses: actions-rs/cargo@master
with:
command: clippy
toolchain: stable
args: --all --no-default-features --features std,hmac,lazy-static-context
9 changes: 8 additions & 1 deletion .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ jobs:
with:
command: build
toolchain: ${{ matrix.toolchain }}
args: --all --verbose --release
args: --all --verbose --release

- name: Building `no default` ${{ matrix.platform }}-${{ matrix.toolchain }}
uses: actions-rs/cargo@master
Expand All @@ -357,6 +357,13 @@ jobs:
toolchain: ${{ matrix.toolchain }}
args: --verbose --no-default-features --features static-context

- name: Building `lazy-static-context` ${{ matrix.platform }}-${{ matrix.toolchain }}
uses: actions-rs/cargo@master
with:
command: build
toolchain: ${{ matrix.toolchain }}
args: --verbose --no-default-features --features lazy-static-context

- name: Stop sccache
if: matrix.platform != 'windows-latest' && always()
run: sccache --stop-server
Expand Down
11 changes: 6 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
# Changelog

The format is based on [Keep a Changelog].
The format is based on [Keep a Changelog].

[Keep a Changelog]: http://keepachangelog.com/en/1.0.0/

## [Unreleased]
## [0.5.0] - 2021-05-18
- Add standard non-overflowing signature parsing `Signature::parse_standard`. The previous behavior `Signature::parse` is considered non-standard and renamed to `Signature::parse_overflowing`. Unless you have a specific need, you should switch to use the new `Signature::parse_standard` function. (PR #67)

## [0.3.5] - 2020-02-06
- Implement std::error::Error and Display for Error (PR #29)
- Implement `std::error::Error` and `Display` for `Error`. (PR #29)
- Fix the PartialEq impl of Field. (PR #30)
- Add LowerHex impl for SecretKey and Scalar (PR #32)
- Put signing behind feature flag (PR #33)
- Add `LowerHex` implementation for `SecretKey` and `Scalar`. (PR #32)
- Put signing behind feature flag. (PR #33)
11 changes: 7 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@
name = "libsecp256k1"
description = "Pure Rust secp256k1 implementation."
license = "Apache-2.0"
version = "0.4.0"
version = "0.6.0"
authors = ["Wei Tang <[email protected]>"]
repository = "https://github.com/paritytech/libsecp256k1"
keywords = ["crypto", "ECDSA", "secp256k1", "bitcoin", "no_std"]
edition = "2018"
resolver = "2"

[dependencies]
libsecp256k1-core = { version = "0.1.0", path = "core", default-features = false }
libsecp256k1-core = { version = "0.2.2", path = "core", default-features = false }
arrayref = "0.3"
rand = { version = "0.8", default-features = false }
digest = "0.9"
Expand All @@ -18,6 +19,7 @@ hmac-drbg = { version = "0.3", optional = true }
sha2 = { version = "0.9", optional = true, default-features = false }
typenum = { version = "1.12", optional = true }
serde = { version = "1.0.104", features = ["derive"], default-features = false }
lazy_static = { version = "1.4.0", optional = true }

[dev-dependencies]
secp256k1-test = { package = "secp256k1", version = "0.20.3", features = ["rand-std", "recovery"] }
Expand All @@ -26,14 +28,15 @@ serde_json = "1.0"
hex-literal = "0.3.3"

[build-dependencies]
libsecp256k1-gen-ecmult = { version = "0.1.0", path = "gen/ecmult" }
libsecp256k1-gen-genmult = { version = "0.1.0", path = "gen/genmult" }
libsecp256k1-gen-ecmult = { version = "0.2.1", path = "gen/ecmult" }
libsecp256k1-gen-genmult = { version = "0.2.1", path = "gen/genmult" }

[features]
default = ["std", "hmac", "static-context"]
std = ["libsecp256k1-core/std", "sha2/std", "rand/std", "serde/std", "base64/std"]
hmac = ["hmac-drbg", "sha2", "typenum"]
static-context = []
lazy-static-context = ["lazy_static", "std"]

[workspace]
members = [
Expand Down
63 changes: 62 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# SECP256K1 Implementation in Pure Rust
# SECP256K1 implementation in pure Rust

* [Cargo](https://crates.io/crates/libsecp256k1)
* [Documentation](https://docs.rs/libsecp256k1)
Expand All @@ -10,3 +10,64 @@ SECP256K1 implementation with `no_std` support. Currently we have implementation
* Signature verification.
* Public key recovery from signed messages.
* Shared secrets.

## Feature flags

* `std`: If disabled, works in `no_std` environment. Enabled by default.
* `hmac`: Add certain features that requires the HMAC-DRBG. This includes
signing. Enabled by default.
* `static-context`: To speed up computation, the library uses a pre-computed
table context for many `ecmult` operations. This feature flag puts the context
directly as static variables. If disabled, the context must be created from
heap manually. Increases binary size, enabled by default.
* `lazy-static-context`: Instead of storing the pre-computed table context as
static variables, store it as a variable that dynamically allocates the
context in heap via `lazy_static`. Only one of `static-context` and
`lazy-static-context` can be enabled, or both disabled. Impact bootstrap
performance, disabled by default.

## Development workflow

### Branch

This repository uses `develop` branch for development. Changes are periodically
merged to `master` branch.

### Pull request

All changes (except new releases) are handled through pull requests. Please open
your PR against `develop` branch.

### Versioning

Frontier follows [Semantic Versioning](https://semver.org/). An unreleased crate
in the repository will have the `-dev` suffix in the end, and we do rolling
releases.

When you make a pull request against this repository, please also update the
affected crates' versions, using the following rules. Note that the rules should
be applied recursively -- if a change modifies any upper crate's dependency
(even just the `Cargo.toml` file), then the upper crate will also need to apply
those rules.

Additionally, if your change is notable, then you should also modify the
corresponding `CHANGELOG.md` file, in the "Unreleased" section.

If the affected crate already has `-dev` suffix:

* If your change is a patch, then you do not have to update any versions.
* If your change introduces a new feature, please check if the local version
already had its minor version bumped, if not, bump it.
* If your change modifies the current interface, please check if the local
version already had its major version bumped, if not, bump it.

If the affected crate does not yet have `-dev` suffix:

* If your change is a patch, then bump the patch version, and add `-dev` suffix.
* If your change introduces a new feature, then bump the minor version, and add
`-dev` suffix.
* If your change modifies the current interface, then bump the major version,
and add `-dev` suffix.

If your pull request introduces a new crate, please set its version to
`1.0.0-dev`.
4 changes: 2 additions & 2 deletions benches/signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ fn bench_signature_parse(b: &mut Bencher) {
signature_a.copy_from_slice(&signature_arr[0..64]);

b.iter(|| {
let _signature = Signature::parse(&signature_a);
let _signature = Signature::parse_standard_slice(&signature_a);
});
}

Expand All @@ -34,7 +34,7 @@ fn bench_signature_serialize(b: &mut Bencher) {
assert!(signature_arr.len() == 64);
let mut signature_a = [0u8; 64];
signature_a.copy_from_slice(&signature_arr[0..64]);
let signature = Signature::parse(&signature_a);
let signature = Signature::parse_standard_slice(&signature_a).expect("parsed signature");

b.iter(|| {
let _serialized = signature.serialize();
Expand Down
2 changes: 1 addition & 1 deletion core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "libsecp256k1-core"
description = "Core functions for pure Rust secp256k1 implementation."
license = "Apache-2.0"
version = "0.1.0"
version = "0.2.2"
authors = ["Wei Tang <[email protected]>"]
repository = "https://github.com/paritytech/libsecp256k1"
keywords = ["crypto", "ECDSA", "secp256k1", "bitcoin", "no_std"]
Expand Down
2 changes: 2 additions & 0 deletions core/src/ecmult.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ use crate::{
};
use alloc::{
alloc::{alloc, Layout},
boxed::Box,
vec,
vec::Vec,
};
use subtle::Choice;

Expand Down
4 changes: 2 additions & 2 deletions gen/ecmult/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
name = "libsecp256k1-gen-ecmult"
description = "Generator function of const_gen for libsecp256k1."
license = "Apache-2.0"
version = "0.1.0"
version = "0.2.1"
authors = ["Wei Tang <[email protected]>"]
edition = "2018"
repository = "https://github.com/paritytech/libsecp256k1"
keywords = ["crypto", "ECDSA", "secp256k1", "bitcoin", "no_std"]

[dependencies]
libsecp256k1-core = { version = "0.1.0", path = "../../core" }
libsecp256k1-core = { version = "0.2.2", path = "../../core" }
4 changes: 2 additions & 2 deletions gen/genmult/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
name = "libsecp256k1-gen-genmult"
description = "Generator function of const for libsecp256k1."
license = "Apache-2.0"
version = "0.1.0"
version = "0.2.1"
authors = ["Wei Tang <[email protected]>"]
edition = "2018"
repository = "https://github.com/paritytech/libsecp256k1"
keywords = ["crypto", "ECDSA", "secp256k1", "bitcoin", "no_std"]

[dependencies]
libsecp256k1-core = { version = "0.1.0", path = "../../core" }
libsecp256k1-core = { version = "0.2.2", path = "../../core" }
1 change: 0 additions & 1 deletion rustfmt.toml
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
merge_imports = true
30 changes: 23 additions & 7 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
unreachable_code,
unused_parens
)]
#![cfg_attr(not(feature = "std"), no_std)]

pub use libsecp256k1_core::*;

Expand All @@ -36,6 +37,18 @@ use crate::{
util::{Decoder, SignatureArray},
};

#[cfg(all(feature = "static-context", feature = "lazy-static-context"))]
compile_error!("Should only enable one of static-context or lazy-static-context");

#[cfg(feature = "lazy-static-context")]
lazy_static::lazy_static! {
/// A static ECMult context.
pub static ref ECMULT_CONTEXT: Box<ECMultContext> = ECMultContext::new_boxed();

/// A static ECMultGen context.
pub static ref ECMULT_GEN_CONTEXT: Box<ECMultGenContext> = ECMultGenContext::new_boxed();
}

#[cfg(feature = "static-context")]
/// A static ECMult context.
// Correct `pre_g` values are fed into `ECMultContext::new_from_raw`, generated by build script.
Expand Down Expand Up @@ -99,7 +112,7 @@ impl PublicKey {
PublicKey(p)
}

#[cfg(feature = "static-context")]
#[cfg(any(feature = "static-context", feature = "lazy-static-context"))]
pub fn from_secret_key(seckey: &SecretKey) -> PublicKey {
Self::from_secret_key_with_context(seckey, &ECMULT_GEN_CONTEXT)
}
Expand Down Expand Up @@ -252,7 +265,7 @@ impl PublicKey {
Ok(())
}

#[cfg(feature = "static-context")]
#[cfg(any(feature = "static-context", feature = "lazy-static-context"))]
pub fn tweak_add_assign(&mut self, tweak: &SecretKey) -> Result<(), Error> {
self.tweak_add_assign_with_context(tweak, &ECMULT_CONTEXT)
}
Expand All @@ -275,7 +288,7 @@ impl PublicKey {
Ok(())
}

#[cfg(feature = "static-context")]
#[cfg(any(feature = "static-context", feature = "lazy-static-context"))]
pub fn tweak_mul_assign(&mut self, tweak: &SecretKey) -> Result<(), Error> {
self.tweak_mul_assign_with_context(tweak, &ECMULT_CONTEXT)
}
Expand Down Expand Up @@ -706,7 +719,7 @@ impl<D: Digest + Default> SharedSecret<D> {
Ok(SharedSecret(inner))
}

#[cfg(feature = "static-context")]
#[cfg(any(feature = "static-context", feature = "lazy-static-context"))]
pub fn new(pubkey: &PublicKey, seckey: &SecretKey) -> Result<SharedSecret<D>, Error> {
Self::new_with_context(pubkey, seckey, &ECMULT_CONTEXT)
}
Expand All @@ -728,7 +741,7 @@ pub fn verify_with_context(
context.verify_raw(&signature.r, &signature.s, &pubkey.0, &message.0)
}

#[cfg(feature = "static-context")]
#[cfg(any(feature = "static-context", feature = "lazy-static-context"))]
/// Check signature is a valid message signed by public key.
pub fn verify(message: &Message, signature: &Signature, pubkey: &PublicKey) -> bool {
verify_with_context(message, signature, pubkey, &ECMULT_CONTEXT)
Expand All @@ -746,7 +759,7 @@ pub fn recover_with_context(
.map(PublicKey)
}

#[cfg(feature = "static-context")]
#[cfg(any(feature = "static-context", feature = "lazy-static-context"))]
/// Recover public key from a signed message.
pub fn recover(
message: &Message,
Expand Down Expand Up @@ -792,7 +805,10 @@ pub fn sign_with_context(
(Signature { r: sigr, s: sigs }, RecoveryId(recid))
}

#[cfg(all(feature = "hmac", feature = "static-context"))]
#[cfg(all(
feature = "hmac",
any(feature = "static-context", feature = "lazy-static-context")
))]
/// Sign a message using the secret key.
pub fn sign(message: &Message, seckey: &SecretKey) -> (Signature, RecoveryId) {
sign_with_context(message, seckey, &ECMULT_GEN_CONTEXT)
Expand Down

0 comments on commit 54c7ccd

Please sign in to comment.