Skip to content
This repository has been archived by the owner on Mar 7, 2024. It is now read-only.

Commit

Permalink
Split crate into core and main, and use build script for const/const_…
Browse files Browse the repository at this point in the history
…gen generation (paritytech#40)

* Rename the library exposed name to just libsecp256k1

This reduces confusion and avoids conflicts in the case when both `secp256k1` and `libsecp256k1` needs to be used.

* Move all const context related code to a separate module

* Split create into core and main

* Fix all tests

* Use build script to generate const.rs file

* Use build script to generate const_gen.rs file

* Change back CI to test --all

* Set all sub-crates' version to 0.1.0 before 0.4.0 is released

* Fix version pins

* Add missing descriptions for crate

* typo: keyword style fix

* Update core/src/lib.rs

Co-Authored-By: Marcio Diaz <[email protected]>

Co-authored-by: Marcio Diaz <[email protected]>
  • Loading branch information
2 people authored and trevor-crypto committed May 31, 2022
1 parent b052d4f commit def7e06
Show file tree
Hide file tree
Showing 22 changed files with 209 additions and 17,691 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ matrix:
- beta
script:
- cargo build --verbose --all
- cargo test --verbose
- cargo test --verbose --all
- cargo build --verbose --no-default-features
23 changes: 11 additions & 12 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,19 @@ license = "Apache-2.0"
version = "0.4.0"
authors = ["Wei Tang <[email protected]>"]
repository = "https://github.com/paritytech/libsecp256k1"
keywords = [ "crypto", "ECDSA", "secp256k1", "bitcoin", "no_std" ]
keywords = ["crypto", "ECDSA", "secp256k1", "bitcoin", "no_std"]
edition = "2018"

[lib]
name = "secp256k1"

[dependencies]
libsecp256k1-core = { version = "0.1.0", path = "core", default-features = false }
arrayref = "0.3"
rand = { version = "0.7", default-features = false }
digest = "0.8"
base64 = { version = "0.11.0", default-features = false }
hmac-drbg = { version = "0.2", optional = true }
sha2 = { version = "0.8", optional = true, default-features = false }
digest = "0.8"
typenum = { version = "1.11", optional = true }
arrayref = "0.3"
subtle = { version = "2.2", default-features = false }
serde = { version = "1.0.104", features = ["derive"], default-features = false }
base64 = { version = "0.11.0", default-features = false }
crunchy = "0.2"
serde = { version = "1.0.104", features = ["derive"], default-features = false }

[dev-dependencies]
secp256k1-test = "0.7"
Expand All @@ -30,11 +26,14 @@ rand-test = { package = "rand", version = "0.4" }
serde_json = "1.0"
hex-literal = "0.2.1"

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

[features]
default = ["std", "hmac"]
std = ["subtle/std", "rand/std", "sha2/std", "serde/std", "base64/std"]
std = ["libsecp256k1-core/std", "sha2/std", "rand/std", "serde/std", "base64/std"]
hmac = ["hmac-drbg", "sha2", "typenum"]
noconst = []

[workspace]
members = [
Expand Down
15 changes: 15 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use std::{env, io::Write, fs::File, path::Path};

fn main() {
let out_dir = env::var_os("OUT_DIR").unwrap();

let const_path = Path::new(&out_dir).join("const.rs");
let mut const_file = File::create(&const_path).expect("Create const.rs file failed");
libsecp256k1_gen_ecmult::generate_to(&mut const_file).expect("Write const.rs file failed");
const_file.flush().expect("Flush const.rs file failed");

let gen_path = Path::new(&out_dir).join("const_gen.rs");
let mut gen_file = File::create(&gen_path).expect("Create const_gen.rs file failed");
libsecp256k1_gen_genmult::generate_to(&mut gen_file).expect("Write const_gen.rs file failed");
gen_file.flush().expect("Flush const_gen.rs file failed");
}
18 changes: 18 additions & 0 deletions core/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[package]
name = "libsecp256k1-core"
description = "Core functions for pure Rust secp256k1 implementation."
license = "Apache-2.0"
version = "0.1.0"
authors = ["Wei Tang <[email protected]>"]
repository = "https://github.com/paritytech/libsecp256k1"
keywords = ["crypto", "ECDSA", "secp256k1", "bitcoin", "no_std"]
edition = "2018"

[dependencies]
subtle = { version = "2.2", default-features = false }
crunchy = "0.2"
digest = "0.8"

[features]
default = ["std"]
std = ["subtle/std"]
File renamed without changes.
File renamed without changes.
File renamed without changes.
42 changes: 21 additions & 21 deletions src/ecmult/mod.rs → core/src/ecmult.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,36 +14,36 @@ pub struct ECMultContext {
pre_g: [AffineStorage; ECMULT_TABLE_SIZE_G],
}

impl ECMultContext {
/// Create a new `ECMultContext`.
pub const fn new(pre_g: [AffineStorage; ECMULT_TABLE_SIZE_G]) -> Self {
Self { pre_g }
}
}

/// Context for accelerating the computation of a*G.
pub struct ECMultGenContext {
prec: [[AffineStorage; 16]; 64],
blind: Scalar,
initial: Jacobian,
}

#[cfg(not(feature = "noconst"))]
/// A static ECMult context.
pub static ECMULT_CONTEXT: ECMultContext = ECMultContext {
pre_g: include!("const.rs"),
};

#[cfg(not(feature = "noconst"))]
/// A static ECMultGen context.
pub static ECMULT_GEN_CONTEXT: ECMultGenContext = ECMultGenContext {
prec: include!("const_gen.rs"),
blind: Scalar([2217680822, 850875797, 1046150361, 1330484644,
4015777837, 2466086288, 2052467175, 2084507480]),
initial: Jacobian {
x: Field::new_raw(586608, 43357028, 207667908, 262670128, 142222828, 38529388, 267186148, 45417712, 115291924, 13447464),
y: Field::new_raw(12696548, 208302564, 112025180, 191752716, 143238548, 145482948, 228906000, 69755164, 243572800, 210897016),
z: Field::new_raw(3685368, 75404844, 20246216, 5748944, 73206666, 107661790, 110806176, 73488774, 5707384, 104448710),
infinity: false,
impl ECMultGenContext {
/// Create a new `ECMultGenContext`.
pub const fn new(
prec: [[AffineStorage; 16]; 64],
blind: Scalar,
initial: Jacobian
) -> Self {
Self { prec, blind, initial }
}
};
}

pub fn odd_multiples_table(prej: &mut [Jacobian],
zr: &mut [Field],
a: &Jacobian) {
pub fn odd_multiples_table(
prej: &mut [Jacobian],
zr: &mut [Field],
a: &Jacobian
) {
debug_assert!(prej.len() == zr.len());
debug_assert!(prej.len() > 0);
debug_assert!(!a.is_infinity());
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
58 changes: 58 additions & 0 deletions core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
//! Pure Rust implementation of the secp256k1 curve and fast ECDSA
//! signatures. The secp256k1 curve is used exclusively in Bitcoin and
//! Ethereum alike cryptocurrencies.
#![deny(unused_import_braces, unused_imports,
unused_comparisons, unused_must_use,
unused_variables, non_shorthand_field_patterns,
unreachable_code, unused_parens)]

#![cfg_attr(not(feature = "std"), no_std)]

#[macro_use]
mod field;
#[macro_use]
mod group;
mod scalar;
mod error;
mod der;
mod ecmult;
mod ecdsa;
mod ecdh;

extern crate alloc;

pub use crate::error::Error;

/// Curve related structs.
pub mod curve {
pub use crate::field::{Field, FieldStorage};
pub use crate::group::{Affine, Jacobian, AffineStorage, AFFINE_G, CURVE_B};
pub use crate::scalar::Scalar;

pub use crate::ecmult::{ECMultContext, ECMultGenContext};
}

/// Utilities to manipulate the secp256k1 curve parameters.
pub mod util {
pub const TAG_PUBKEY_EVEN: u8 = 0x02;
pub const TAG_PUBKEY_ODD: u8 = 0x03;
pub const TAG_PUBKEY_FULL: u8 = 0x04;
pub const TAG_PUBKEY_HYBRID_EVEN: u8 = 0x06;
pub const TAG_PUBKEY_HYBRID_ODD: u8 = 0x07;

pub const MESSAGE_SIZE: usize = 32;
pub const SECRET_KEY_SIZE: usize = 32;
pub const RAW_PUBLIC_KEY_SIZE: usize = 64;
pub const FULL_PUBLIC_KEY_SIZE: usize = 65;
pub const COMPRESSED_PUBLIC_KEY_SIZE: usize = 33;
pub const SIGNATURE_SIZE: usize = 64;
pub const DER_MAX_SIGNATURE_SIZE: usize = 72;

pub use crate::group::{AFFINE_INFINITY, JACOBIAN_INFINITY,
set_table_gej_var, globalz_set_table_gej};
pub use crate::ecmult::{WINDOW_A, WINDOW_G, ECMULT_TABLE_SIZE_A, ECMULT_TABLE_SIZE_G,
odd_multiples_table};

pub use crate::der::{Decoder, SignatureArray};
}
File renamed without changes.
9 changes: 7 additions & 2 deletions gen/ecmult/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
[package]
name = "libsecp256k1-gen-ecmult"
version = "0.0.0"
description = "Generator function of const_gen for libsecp256k1."
license = "Apache-2.0"
version = "0.1.0"
authors = ["Wei Tang <[email protected]>"]
edition = "2018"
repository = "https://github.com/paritytech/libsecp256k1"
keywords = ["crypto", "ECDSA", "secp256k1", "bitcoin", "no_std"]

[dependencies]
libsecp256k1 = { path = "../..", features = ["noconst"] }
libsecp256k1-core = { version = "0.1.0", path = "../../core" }
27 changes: 16 additions & 11 deletions gen/ecmult/src/main.rs → gen/ecmult/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
extern crate secp256k1;

use secp256k1::curve::{Jacobian, Field, AffineStorage, Affine, AFFINE_G};
use secp256k1::util::{odd_multiples_table, ECMULT_TABLE_SIZE_G,
set_table_gej_var};
use std::{io::{Write, Error}, fs::File};
use libsecp256k1_core::curve::{Jacobian, Field, AffineStorage, Affine, AFFINE_G};
use libsecp256k1_core::util::{odd_multiples_table, ECMULT_TABLE_SIZE_G,
set_table_gej_var};

fn odd_multiples_table_storage_var(pre: &mut [AffineStorage],
a: &Jacobian) {
Expand All @@ -27,19 +26,25 @@ fn odd_multiples_table_storage_var(pre: &mut [AffineStorage],
}
}

fn main() {
pub fn generate_to(file: &mut File) -> Result<(), Error> {
let mut gj = Jacobian::default();
gj.set_ge(&AFFINE_G);
let mut pre_g = Vec::with_capacity(ECMULT_TABLE_SIZE_G);
for _ in 0..ECMULT_TABLE_SIZE_G {
pre_g.push(AffineStorage::default());
}
odd_multiples_table_storage_var(&mut pre_g, &gj);
println!("[");
file.write_fmt(format_args!("["))?;
for pg in pre_g {
println!(" crate::curve::AffineStorage::new(crate::curve::FieldStorage::new({}, {}, {}, {}, {}, {}, {}, {}), crate::curve::FieldStorage::new({}, {}, {}, {}, {}, {}, {}, {})),",
pg.x.0[7], pg.x.0[6], pg.x.0[5], pg.x.0[4], pg.x.0[3], pg.x.0[2], pg.x.0[1], pg.x.0[0],
pg.y.0[7], pg.y.0[6], pg.y.0[5], pg.y.0[4], pg.y.0[3], pg.y.0[2], pg.y.0[1], pg.y.0[0]);
file.write_fmt(
format_args!(
" crate::curve::AffineStorage::new(crate::curve::FieldStorage::new({}, {}, {}, {}, {}, {}, {}, {}), crate::curve::FieldStorage::new({}, {}, {}, {}, {}, {}, {}, {})),",
pg.x.0[7], pg.x.0[6], pg.x.0[5], pg.x.0[4], pg.x.0[3], pg.x.0[2], pg.x.0[1], pg.x.0[0],
pg.y.0[7], pg.y.0[6], pg.y.0[5], pg.y.0[4], pg.y.0[3], pg.y.0[2], pg.y.0[1], pg.y.0[0]
)
)?;
}
println!("]");
file.write_fmt(format_args!("]"))?;

Ok(())
}
9 changes: 7 additions & 2 deletions gen/genmult/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
[package]
name = "libsecp256k1-gen-genmult"
version = "0.0.0"
description = "Generator function of const for libsecp256k1."
license = "Apache-2.0"
version = "0.1.0"
authors = ["Wei Tang <[email protected]>"]
edition = "2018"
repository = "https://github.com/paritytech/libsecp256k1"
keywords = ["crypto", "ECDSA", "secp256k1", "bitcoin", "no_std"]

[dependencies]
libsecp256k1 = { path = "../..", features = ["noconst"] }
libsecp256k1-core = { version = "0.1.0", path = "../../core" }
25 changes: 14 additions & 11 deletions gen/genmult/src/main.rs → gen/genmult/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
extern crate secp256k1;

use secp256k1::curve::{Jacobian, Field, AffineStorage, Affine, AFFINE_G};
use std::{io::{Write, Error}, fs::File};
use libsecp256k1_core::curve::{Jacobian, Field, AffineStorage, Affine, AFFINE_G};

pub fn set_all_gej_var(a: &[Jacobian]) -> Vec<Affine> {
let mut az: Vec<Field> = Vec::with_capacity(a.len());
Expand Down Expand Up @@ -58,7 +57,7 @@ pub fn inv_all_var(fields: &[Field]) -> Vec<Field> {
ret
}

fn main() {
pub fn generate_to(file: &mut File) -> Result<(), Error> {
let mut gj = Jacobian::default();
gj.set_ge(&AFFINE_G);

Expand Down Expand Up @@ -98,16 +97,20 @@ fn main() {
}
}
let prec = set_all_gej_var(&precj);
println!("[");
file.write_fmt(format_args!("["))?;
for j in 0..64 {
println!(" [");
file.write_fmt(format_args!(" ["))?;
for i in 0..16 {
let pg: AffineStorage = prec[j*16 + i].clone().into();
println!(" crate::curve::AffineStorage::new(crate::curve::FieldStorage::new({}, {}, {}, {}, {}, {}, {}, {}), crate::curve::FieldStorage::new({}, {}, {}, {}, {}, {}, {}, {})),",
pg.x.0[7], pg.x.0[6], pg.x.0[5], pg.x.0[4], pg.x.0[3], pg.x.0[2], pg.x.0[1], pg.x.0[0],
pg.y.0[7], pg.y.0[6], pg.y.0[5], pg.y.0[4], pg.y.0[3], pg.y.0[2], pg.y.0[1], pg.y.0[0]);
file.write_fmt(format_args!(
" crate::curve::AffineStorage::new(crate::curve::FieldStorage::new({}, {}, {}, {}, {}, {}, {}, {}), crate::curve::FieldStorage::new({}, {}, {}, {}, {}, {}, {}, {})),",
pg.x.0[7], pg.x.0[6], pg.x.0[5], pg.x.0[4], pg.x.0[3], pg.x.0[2], pg.x.0[1], pg.x.0[0],
pg.y.0[7], pg.y.0[6], pg.y.0[5], pg.y.0[4], pg.y.0[3], pg.y.0[2], pg.y.0[1], pg.y.0[0]
))?;
}
println!(" ],");
file.write_fmt(format_args!(" ],"))?;
}
println!("]");
file.write_fmt(format_args!("]"))?;

Ok(())
}
Loading

0 comments on commit def7e06

Please sign in to comment.