Skip to content

Commit

Permalink
add trait for Keypair, and adjust project struct
Browse files Browse the repository at this point in the history
  • Loading branch information
xujian009 committed May 11, 2020
1 parent 1b32b0e commit f29725e
Show file tree
Hide file tree
Showing 12 changed files with 260 additions and 89 deletions.
4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@ rand = "0.7.3"
dislog-hal = { git = "https://github.com/Yinet-project/dislog-hal"}
tiny-keccak = { version = "2.0.0", features = ["sha3"] }
libsm = { git = "https://github.com/citahub/libsm"}
serde = { version = "1.0", features = ["derive"] }
dislog-hal-sm2 = { git = "https://github.com/Yinet-project/dislog-hal-sm2"}


[dev-dependencies]
dislog-hal-curve25519 = { git = "https://github.com/Yinet-project/dislog-hal-curve25519"}
dislog-hal-sm2 = { git = "https://github.com/Yinet-project/dislog-hal-sm2"}
byteorder = "1"

[dev-dependencies.cargo-husky]
Expand Down
3 changes: 0 additions & 3 deletions src/hasher/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,2 @@
pub mod sha3;
pub use sha3::Sha3;

pub mod sm3;
pub use sm3::Sm3;
37 changes: 1 addition & 36 deletions src/hasher/sha3.rs
Original file line number Diff line number Diff line change
@@ -1,41 +1,6 @@
use crate::prelude::Splitable;
use crate::NewU864;
use core::fmt::Debug;
use hex::{FromHex, FromHexError};

pub struct NewU864(pub [u8; 64]);

impl Debug for NewU864 {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
let mut info = f.debug_list();
for i in 0..self.0.len() {
info.entry(&self.0[i]);
}
info.finish()
}
}

impl PartialEq for NewU864 {
fn eq(&self, other: &Self) -> bool {
self.0[..] == other.0[..]
}
}

impl FromHex for NewU864 {
type Error = FromHexError;

fn from_hex<T: AsRef<[u8]>>(hex: T) -> Result<Self, Self::Error> {
match <[u8; 64]>::from_hex(hex) {
Ok(x) => Ok(Self(x)),
Err(err) => Err(err),
}
}
}

impl AsRef<[u8]> for NewU864 {
fn as_ref(&self) -> &[u8] {
&self.0
}
}

pub struct Sha3(pub tiny_keccak::Sha3);

Expand Down
1 change: 1 addition & 0 deletions src/keypair/curve25519.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

1 change: 1 addition & 0 deletions src/keypair/ed25519.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

64 changes: 46 additions & 18 deletions src/key_pair_gen.rs → src/keypair/mod.rs
Original file line number Diff line number Diff line change
@@ -1,31 +1,56 @@
pub mod curve25519;
pub mod ed25519;
pub mod sm2;

use crate::prelude::Splitable;
use crate::CryptoError;
use core::fmt::Debug;
use core::marker::PhantomData;
use dislog_hal::{Bytes, DisLogPoint, Hasher, Point, Scalar, ScalarNumber};
use dislog_hal::{DisLogPoint, Hasher, Point, Scalar, ScalarNumber};
use hex::{FromHex, ToHex};
use rand::RngCore;
use serde::{Deserialize, Serialize};

pub trait SliceN:
Default
+ AsRef<[u8]>
+ Debug
+ ToHex
+ FromHex
+ PartialEq
+ Clone
+ Serialize
+ for<'de> Deserialize<'de>
{
}

impl SliceN for [u8; 32] {}

#[derive(Debug)]
pub struct KeyPair<
N: Default + AsRef<[u8]> + AsMut<[u8]> + Sized + Debug + ToHex + FromHex + PartialEq + Clone,
#[derive(Debug, Serialize, Deserialize)]
pub struct Keypair<
N: SliceN,
H: Hasher + Default + Splitable<Half = N>,
P: DisLogPoint<Scalar = S>,
S: ScalarNumber<Point = P> + Bytes<BytesType = N>,
S: ScalarNumber<Point = P>,
> {
#[serde(bound(deserialize = "N: SliceN"))]
seed: N,
#[serde(bound(deserialize = "S: ScalarNumber"))]
secret_key: Scalar<S>,
#[serde(bound(deserialize = "P: DisLogPoint<Scalar = S>"))]
public_key: Point<P>,
#[serde(bound(deserialize = "N: SliceN"))]
code: N,
#[serde(bound(deserialize = "H: Hasher + Default + Splitable<Half = N>"))]
_hash: PhantomData<H>,
}

impl<
N: Default + AsRef<[u8]> + AsMut<[u8]> + Sized + Debug + ToHex + FromHex + PartialEq + Clone,
N: SliceN + AsMut<[u8]>,
H: Hasher + Default + Splitable<Half = N>,
P: DisLogPoint<Scalar = S>,
S: ScalarNumber<Point = P> + Bytes<BytesType = N>,
> KeyPair<N, H, P, S>
S: ScalarNumber<Point = P>,
> Keypair<N, H, P, S>
{
pub fn generate<R: RngCore>(rng: &mut R) -> Result<Self, CryptoError> {
let mut seed = N::default();
Expand All @@ -36,29 +61,32 @@ impl<
Err(_) => Err(CryptoError::KeyPairGenError),
}
}
}

impl<
N: SliceN,
H: Hasher + Default + Splitable<Half = N>,
P: DisLogPoint<Scalar = S>,
S: ScalarNumber<Point = P>,
> Keypair<N, H, P, S>
{
pub fn generate_from_seed(seed: N) -> Result<Self, CryptoError> {
let mut hasher = H::default();
hasher.update(seed.as_ref());
let (secret_key_x, code) = hasher.split_finalize();

let secret_key;
match S::from_bytes(secret_key_x) {
Ok(x) => {
secret_key = Scalar { inner: x };
}
let secret_key = match Scalar::<S>::from_bytes(secret_key_x.as_ref()) {
Ok(secret_key) => secret_key,
Err(_) => return Err(CryptoError::KeyPairGenError),
}
};

if secret_key.inner == S::zero() {
if secret_key == Scalar::<S>::zero() {
return Err(CryptoError::KeyPairGenError);
}

Ok(Self {
seed,
public_key: Point {
inner: P::generator(),
} * &secret_key,
public_key: Point::<P>::generator() * &secret_key,
secret_key,
code,
_hash: PhantomData,
Expand Down
59 changes: 59 additions & 0 deletions src/keypair/sm2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
use crate::hasher::sha3::Sha3;
use crate::keypair::Keypair;
use crate::{signature, CryptoError};
use dislog_hal::{Hasher, Point, Scalar};
use rand::RngCore;
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]
pub struct KeyPairSm2(
pub Keypair<[u8; 32], Sha3, dislog_hal_sm2::PointInner, dislog_hal_sm2::ScalarInner>,
);

impl crate::prelude::Keypair for KeyPairSm2 {
type Seed = [u8; 32];

type Secret = Scalar<dislog_hal_sm2::ScalarInner>;

type Public = Point<dislog_hal_sm2::PointInner>;

type Code = [u8; 32];

type Signature = signature::sm2::Signature<dislog_hal_sm2::ScalarInner>;

fn generate<R: RngCore>(rng: &mut R) -> Result<Self, CryptoError> {
match Keypair::generate::<R>(rng) {
Ok(x) => Ok(Self(x)),
Err(_) => Err(CryptoError::KeyPairGenError),
}
}

fn generate_from_seed(seed: Self::Seed) -> Result<Self, CryptoError> {
match Keypair::generate_from_seed(seed) {
Ok(x) => Ok(Self(x)),
Err(_) => Err(CryptoError::KeyPairGenError),
}
}

fn sign<H: Default + Hasher<Output = [u8; 32]> + Hasher, R: RngCore>(
&self,
msg: &[u8],
rng: &mut R,
) -> Result<Self::Signature, CryptoError> {
let mut hasher = H::default();
hasher.update(msg);
signature::sm2::sm2_signature::<_, H, _, _, R>(hasher, &self.0.get_secret_key(), rng)
}

fn verify<H: Default + Hasher<Output = [u8; 32]> + Hasher>(
&self,
msg: &[u8],
sig: &Self::Signature,
) -> Result<bool, CryptoError> {
Ok(signature::sm2::sm2_verify::<_, H, _, _>(
msg,
&self.0.get_public_key(),
sig,
))
}
}
47 changes: 40 additions & 7 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,47 @@
mod key_pair_gen;
pub use key_pair_gen::KeyPair;
pub mod hasher;
pub mod keypair;
pub mod signature;

mod prelude;
pub mod prelude;
pub use prelude::Splitable;

mod sigture;
pub use sigture::{sm2_signature, sm2_verify};
use core::fmt::Debug;
use hex::{FromHex, FromHexError};

mod hasher;
pub use hasher::{Sha3, Sm3};
pub struct NewU864(pub [u8; 64]);

impl Debug for NewU864 {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
let mut info = f.debug_list();
for i in 0..self.0.len() {
info.entry(&self.0[i]);
}
info.finish()
}
}

impl PartialEq for NewU864 {
fn eq(&self, other: &Self) -> bool {
self.0[..] == other.0[..]
}
}

impl FromHex for NewU864 {
type Error = FromHexError;

fn from_hex<T: AsRef<[u8]>>(hex: T) -> Result<Self, Self::Error> {
match <[u8; 64]>::from_hex(hex) {
Ok(x) => Ok(Self(x)),
Err(err) => Err(err),
}
}
}

impl AsRef<[u8]> for NewU864 {
fn as_ref(&self) -> &[u8] {
&self.0
}
}

#[derive(Debug)]
pub enum CryptoError {
Expand Down
32 changes: 32 additions & 0 deletions src/prelude.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,40 @@
use crate::CryptoError;
use core::fmt::Debug;
use dislog_hal::{Bytes, Hasher};
use hex::{FromHex, ToHex};
use rand::RngCore;
use serde::{Deserialize, Serialize};

pub trait Splitable {
type Half: Debug + ToHex + FromHex + PartialEq;

fn split_finalize(self) -> (Self::Half, Self::Half);
}

pub trait Keypair: Serialize + for<'de> Deserialize<'de> {
type Seed;

type Secret;

type Public;

type Code;

type Signature: Serialize + for<'de> Deserialize<'de> + Bytes;

fn generate<R: RngCore>(rng: &mut R) -> Result<Self, CryptoError>;

fn generate_from_seed(seed: Self::Seed) -> Result<Self, CryptoError>;

fn sign<H: Default + Hasher<Output = [u8; 32]> + Hasher, R: RngCore>(
&self,
msg: &[u8],
rng: &mut R,
) -> Result<Self::Signature, CryptoError>;

fn verify<H: Default + Hasher<Output = [u8; 32]> + Hasher>(
&self,
msg: &[u8],
sig: &Self::Signature,
) -> Result<bool, CryptoError>;
}
1 change: 1 addition & 0 deletions src/signature/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod sm2;
Loading

0 comments on commit f29725e

Please sign in to comment.