Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions docs/pkc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<!-- [start:omit] -->

> [!NOTE]
> This is a spliced page meant for publication on Zensical. See [`pkgs/pkc`](../../pkgs/pkc/) for available
> documentation.

<!-- [end:omit] -->

<!-- [include:pkgs/pkc/README.md] -->
9 changes: 9 additions & 0 deletions docs/pkc/changelog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<!-- [start:omit] -->

> [!NOTE]
> This is a spliced page meant for publication on Zensical. See [`pkgs/pkc`](../../pkgs/pkc/) for available
> documentation.

<!-- [end:omit] -->

<!-- [include:pkgs/pkc/CHANGELOG.md] -->
2 changes: 1 addition & 1 deletion docs/samples/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions docs/zensical.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ nav = [
{ "Overview" = "num/README.md" },
{ "Changelog" = "num/changelog.md" },
] },
{ "dash-pkc" = [
{ "Overview" = "pkc/README.md" },
{ "Changelog" = "pkc/changelog.md" },
] },
{ "Samples" = [
{ "Genesis Solver" = "samples/solver/README.md" },
{ "Object Parser" = "samples/parser/README.md" },
Expand Down
2 changes: 1 addition & 1 deletion pkgs/p2p_core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ bitcoin-consensus-encoding = { workspace = true, features = ["alloc"] }
bitcoin-internals = { workspace = true }
cfg-if = "1"
dash-num = { version = "0.1.0-beta", path = "../num", features = ["codec"] }
dash-pkc = { version = "0.0.0", path = "../pkc", features = ["codec"] }
dash-pkc = { version = "0.1.0-beta", path = "../pkc", features = ["codec"] }
dash-script = { version = "0.0.0", path = "../script" }
dash-params = { version = "0.0.0", path = "../params" }
dash-primitives = { version = "0.0.0", path = "../primitives" }
Expand Down
2 changes: 2 additions & 0 deletions pkgs/pkc/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),

## [Unreleased]

## [0.1.0-beta] - 2026-09-15

- Initial release.
66 changes: 51 additions & 15 deletions pkgs/pkc/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
[package]
name = "dash-pkc"
version = "0.0.0"
version = "0.1.0-beta"
description = "Cryptographic primitives for the Dash Base SDK"
keywords = ["base-sdk", "dash", "dashcore", "dashpay"]
categories = [
"cryptography",
"cryptography::cryptocurrencies",
"no-std",
"wasm",
]
exclude = [
"bench",
"corpus",
"tests",
]
readme = "README.md"
authors.workspace = true
edition.workspace = true
Expand All @@ -16,8 +29,6 @@ aes = { version = "0.8", default-features = false, features = [
base58ck = { workspace = true, optional = true, features = ["alloc"] }
bitcoin_hashes = { workspace = true, features = ["alloc"] }
blst = { version = "0.3", default-features = false, optional = true }
ff = { version = "0.14", default-features = false, optional = true }
group = { version = "0.14", default-features = false, optional = true }
cfg-if = "1"
dash-num = { version = "0.1.0-beta", path = "../num", default-features = false }
dash-types = { version = "0.1.0-beta", path = "../types", default-features = false }
Expand All @@ -27,15 +38,16 @@ ed25519-dalek = { version = "3", default-features = false, features = [
"signature",
"zeroize",
], optional = true }
ff = { version = "0.14", default-features = false, optional = true }
group = { version = "0.14", default-features = false, optional = true }
hex-conservative = { workspace = true, features = [
"alloc",
] }
rand_core = { workspace = true, optional = true }
secp256k1 = { version = "0.33.1", default-features = false, features = [
"alloc",
"recovery",
], optional = true }
rand_core = { workspace = true, optional = true }
rstest = { version = "0.25", optional = true }
serde = { version = "1", default-features = false, features = [
"alloc",
"derive",
Expand All @@ -46,7 +58,7 @@ zeroize = { workspace = true, features = ["alloc", "derive"] }

[dev-dependencies]
bitcoin-consensus-encoding = { workspace = true, features = ["alloc"] }
dash-dev = { version = "0.0.0", path = "../dev", features = ["full"] }
dash-dev = { path = "../dev", features = ["full"] }
divan = "0.1"
getrandom = { version = "0.4", features = ["sys_rng"] }
hex-conservative = { workspace = true, features = ["std"] }
Expand All @@ -55,8 +67,13 @@ rstest = "0.25"
serde = { version = "1", features = ["derive"] }

[features]
default = []
std = ["base58ck?/std", "bitcoin_hashes/std", "dash-types/std"]
default = ["codec"]
Comment thread
coderabbitai[bot] marked this conversation as resolved.
std = [
"base58ck?/std",
"bitcoin_hashes/std",
"dash-types/std",
]

bls = [
"dep:aes",
"dep:blst",
Expand All @@ -66,15 +83,32 @@ bls = [
"dep:sha2",
]
codec = [
"dep:base58ck",
"dash-num/codec",
"dash-types/codec",
"dep:base58ck",
]
ecdsa = [
"dep:rand_core",
"dep:secp256k1",
]
eddsa = [
"dep:ed25519-dalek",
"dep:rand_core",
]
full = [
"bls",
"codec",
"ecdsa",
"eddsa",
"serde",
"std",
]
Comment thread
coderabbitai[bot] marked this conversation as resolved.
serde = [
"codec",
"dash-num/serde",
"dash-types/serde",
"dep:serde",
]
ecdsa = ["dep:rand_core", "dep:secp256k1"]
eddsa = ["dep:ed25519-dalek", "dep:rand_core"]
serde = ["codec", "dep:serde", "dash-num/serde", "dash-types/serde"]
full = ["bls", "codec", "ecdsa", "eddsa", "serde", "std", "tests"]
tests = ["std", "dep:rstest"]

[lints]
workspace = true
Expand All @@ -83,4 +117,6 @@ workspace = true
name = "pkc"
path = "bench/main.rs"
harness = false
required-features = ["tests"]

[package.metadata.docs.rs]
all-features = true
21 changes: 21 additions & 0 deletions pkgs/pkc/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
The MIT License (MIT)

Copyright (c) 2026-present, The Dash Core developers

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
66 changes: 66 additions & 0 deletions pkgs/pkc/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,70 @@
[![dash-pkc](https://img.shields.io/github/actions/workflow/status/dashpay/base-sdk/pkg_pkc.yml?style=flat&logo=github&logoColor=white&label=pkc)](https://github.com/dashpay/base-sdk/actions/workflows/pkg_pkc.yml)
[![dash-pkc](https://img.shields.io/codecov/c/github/dashpay/base-sdk/develop?flag=dash-pkc&style=flat&logo=codecov&logoColor=white&label=pkc)](https://app.codecov.io/github/dashpay/base-sdk/tree/develop/pkgs%2Fpkc)

> [!WARNING]
>
> It is heavily advised **against** using this library for new consensus implementations and to use established
> spec-conformant libraries like [supranational/blst](https://github.com/supranational/blst) as this library codifies
> primitives predating the final IETF spec and includes a non-standard (now legacy) scheme.
>
> **This library has not undergone a formal security review.**

# dash-pkc

This crate supplies the curve primitives for signing, verifying and encrypting used by the Dash Base SDK for
consensus-stable types, including

* Distinct byte bag and operative types to allow parsing _without_ pulling in crypto dependencies with native
zeroization and constant-time comparison.
* A bug-compatible implementation of the sunset BLS12-381 scheme used by the reference implementation (also known as
"legacy" or Chia scheme) and the current active (i.e. "basic") scheme.
* Shared DH secret derivation and encryption using BLS12-381's integrated encryption scheme.
* A consensus-compatible wrapper around secp256k1 with support for DER (en/de)coding, recoverable signatures and
Bitcoin-derived compression semantics.
* Scalar and point tweaks for BLS12-381 and secp256k1

## Usage

To import `dash-pkc` to your project, add the following to the `[dependencies]` section in `Cargo.toml`

```toml
dash-pkc = "0.1.0-beta"
```

To use an unpublished revision of this crate, identify the commit hash to pin against and use the following replacing
the value of `rev`.

```toml
dash-pkc = { git = "https://github.com/dashpay/base-sdk", rev = "a1b2c3d4e5f67890abcdef1234567890abcdef" }
```

To build this crate on a clone of the repository, at the repository root, run the following

```bash
cargo build --package dash-pkc --all-features
```

## Features

This crate is `#![no_std]` + `alloc` by default.

| Feature | Default | Description |
| ------- | ------- | ----------- |
| `bls` | | Enables support for BLS12-381 operations backed by [`blst`](https://docs.rs/blst). Byte types are available without enabling this feature. |
| `codec` | :white_check_mark: | Enables support for encoding and decoding types using [`bitcoin-consensus-encoding`](https://docs.rs/bitcoin-consensus-encoding) |
| `ecdsa` | | Enables secp256k1 operations backed by [`rust-secp256k1`](https://docs.rs/secp256k1). Byte types are available without enabling this feature. |
| `eddsa` | | Enables ed25519 operations backed by [`ed25519-dalek`](https://docs.rs/ed25519-dalek). Byte types are available without enabling this feature. |
| `full` | | Enables all features and `std` support. |
| `serde` | | Enables support for encoding and decoding `codec`-backed types using [`serde`](https://github.com/serde-rs/serde). _Implies `codec`._ |

## Documentation

<!-- pyml disable-next-line no-bare-urls -->
Documentation for the most recent release of `dash-pkc` is available at https://dashpay.github.io/base-sdk/pkc and
changes between versions are recorded in the [changelog](https://dashpay.github.io/base-sdk/pkc/changelog).

## License

<!-- pyml disable-next-line no-bare-urls -->
`dash-pkc` is released under the terms of the MIT license. Copyright &copy; 2026-present, The Dash Core developers.
To read a copy of the license terms, visit https://opensource.org/license/MIT.
3 changes: 2 additions & 1 deletion pkgs/pkc/bench/bls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@

//! Benchmarks for BLS schemes.

use dash_pkc::bls::tests::{sequential_ids, test_ikm, test_msg};
use crate::common::bls::{sequential_ids, test_ikm, test_msg};

use dash_pkc::bls::{BlsPublicKey, BlsScChia, BlsScIetf, BlsScheme, BlsSecretKey, BlsSigShare, BlsSignature};
use divan::{counter::ItemsCount, Bencher};
use getrandom::SysRng;
Expand Down
3 changes: 2 additions & 1 deletion pkgs/pkc/bench/ecdsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@

//! Benchmarks for the ecdsa (secp256k1) feature

use dash_pkc::ecdsa::tests::{message_hash, ALICE_SK};
use crate::common::ecdsa::{message_hash, ALICE_SK};

use dash_pkc::ecdsa::{Compression, EcdsaPublicKey, EcdsaSecretKey};

fn test_key() -> EcdsaSecretKey {
Expand Down
3 changes: 2 additions & 1 deletion pkgs/pkc/bench/eddsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@

//! Benchmarks for the `eddsa` (ed25519) feature

use dash_pkc::eddsa::tests::{ALICE_PK, ALICE_SK, MSG};
use crate::common::eddsa::{ALICE_PK, ALICE_SK, MSG};

use dash_pkc::eddsa::{EddsaPkBytes, EddsaPublicKey, EddsaSecretKey};
use dash_types::Hashable;

Expand Down
5 changes: 5 additions & 0 deletions pkgs/pkc/bench/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,13 @@
expect(clippy::unwrap_used, reason = "benchmarks rely on trusted test vectors")
)]

extern crate alloc;

#[cfg(feature = "bls")]
mod bls;
#[cfg(any(feature = "bls", feature = "ecdsa", feature = "eddsa"))]
#[path = "../src/tests.rs"]
mod common;
#[cfg(feature = "ecdsa")]
mod ecdsa;
#[cfg(feature = "eddsa")]
Expand Down
6 changes: 2 additions & 4 deletions pkgs/pkc/src/bls/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,8 @@ cfg_if::cfg_if! {
pub(crate) mod group;
pub(crate) mod scalar;
pub(crate) mod scheme_ops;

#[cfg(any(test, feature = "tests"))]
#[doc(hidden)]
pub mod tests;
#[cfg(test)]
pub(crate) mod tests;

pub use ies_ops::{BlsIesBlob, BlsIesMulti};
pub use public_ops::BlsPublicKey;
Expand Down
37 changes: 1 addition & 36 deletions pkgs/pkc/src/bls/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@

//! Shared test fixtures and constants.

use crate::bls::BlsShareId;
use crate::prelude::*;
pub(crate) use crate::tests::bls::{make_id, sequential_ids, test_ikm, test_msg};

use cfg_if::cfg_if;
use dash_types::Numeric;
use hex_conservative::hex;

/// BLS12-381 scalar field order r, big-endian.
Expand Down Expand Up @@ -69,40 +68,6 @@ pub const fn ietf_g1_encoding(mut chia: [u8; 48]) -> [u8; 48] {
chia
}

/// Build a participant id whose field element is `i`.
pub fn make_id(i: u32) -> BlsShareId {
let mut bytes = [0u8; 32];
bytes[28..32].copy_from_slice(&i.to_be_bytes());
BlsShareId::from_lendian(bytes)
}

/// Build `n` sequential participant ids `1..=n`.
pub fn sequential_ids(n: usize) -> Vec<BlsShareId> {
(1..=n).map(|i| make_id(i as u32)).collect()
}

/// Build a distinct 32-byte IKM from an index, for multi-signer tests.
///
/// The index is carried in full, so a run of more than 256 signers gets that
/// many distinct keys instead of wrapping at 256.
pub fn test_ikm(i: usize) -> [u8; 32] {
let mut ikm = [0u8; 32];
ikm[..8].copy_from_slice(&(i as u64).to_be_bytes());
ikm[24..].copy_from_slice(&(i as u64).wrapping_add(1).to_be_bytes());
ikm
}

/// Build a distinct 32-byte message from an index, for multi-signer tests.
///
/// As with [`test_ikm`], the index is carried in full to keep messages
/// distinct past 256.
pub fn test_msg(i: usize) -> [u8; 32] {
let mut m = [0u8; 32];
m[..8].copy_from_slice(&(i as u64).to_be_bytes());
m[8..16].copy_from_slice(&(i as u64).wrapping_mul(7).to_be_bytes());
m
}

cfg_if! {
if #[cfg(test)] {
use dash_dev::Corpus;
Expand Down
Loading