Skip to content
This repository has been archived by the owner on Jan 16, 2025. It is now read-only.

Commit

Permalink
No-Std compatibility
Browse files Browse the repository at this point in the history
  • Loading branch information
vlopes11 committed Nov 17, 2020
1 parent 00ce62d commit 668f3d7
Show file tree
Hide file tree
Showing 11 changed files with 251 additions and 159 deletions.
45 changes: 45 additions & 0 deletions .github/workflows/dusk_ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,21 @@ jobs:
command: check

test_nightly:
name: Nightly tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: nightly
override: true
- uses: actions-rs/cargo@v1
with:
command: test
args: --release

test_nightly_canon:
name: Nightly tests
runs-on: ubuntu-latest
steps:
Expand All @@ -50,6 +65,36 @@ jobs:
command: test
args: --release --features canon

test_nightly_nostd:
name: Nightly tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: nightly
override: true
- uses: actions-rs/cargo@v1
with:
command: test
args: --release --no-default-features

test_nightly_nostd_canon:
name: Nightly tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: nightly
override: true
- uses: actions-rs/cargo@v1
with:
command: test
args: --release --no-default-features --features canon

fmt:
name: Rustfmt
runs-on: ubuntu-latest
Expand Down
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

## [0.4.0] - 17-11-20
### Changed
- No-Std compatibility.
38 changes: 25 additions & 13 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,23 +1,35 @@
[package]
name = "dusk-pki"
version = "0.3.1"
version = "0.4.0"
authors = ["zer0 <[email protected]>", "Victor Lopez <[email protected]"]
edition = "2018"

[dependencies]
poseidon252 = { git = "https://github.com/dusk-network/Poseidon252", tag = "v0.13.2"}
dusk-jubjub = "0.5"
rand_core = "0.5.1"
dusk-bls12_381 = {version = "0.3", default-features = false}
dusk-jubjub = {version = "0.5", default-features = false}
hades252 = {git = "https://github.com/dusk-network/hades252", tag = "v0.10.1", default-features = false}
hex = {version = "^0.4", default-features = false}
subtle = {version = "^2.2.1", default-features = false}
canonical = {version = "0.4", optional = true}
canonical_derive = {version = "0.4", optional = true}
hex = "^0.4"
rand = "^0.7"
sha2 = "0.8"
anyhow = "1.0"
thiserror = "1.0"

[dependencies.subtle]
version = "^2.2.1"
default-features = false
rand = {version = "0.7", optional = true}
sha2 = {version = "0.8", optional = true}

[features]
canon = ["canonical", "canonical_derive", "dusk-jubjub/canon", "poseidon252/canon"]
default = ["std"]
std = [
"dusk-jubjub/default",
"dusk-bls12_381/default",
"hades252/default",
"subtle/default",
"hex/default",
"rand/default",
"sha2/default"
]
canon = [
"canonical",
"canonical_derive",
"dusk-bls12_381/canon",
"dusk-jubjub/canon"
]
22 changes: 8 additions & 14 deletions src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,28 @@
//
// Copyright (c) DUSK NETWORK. All rights reserved.

use std::io;
use thiserror::Error;
#[cfg(feature = "std")]
use std::fmt;

/// Errors for Dusk PKI
#[derive(Error, Debug)]
#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub enum Error {
/// Invalid Compressed Point
#[error("Invalid Compressed Point Provided")]
/// Invalid Compressed Point"
InvalidPoint,
#[error("Invalid Parameters provided to the function")]
/// Invalid Parameters
InvalidParameters,
/// Bad Length
#[error("Bad Length (expected {expected:?}, got {found:?})")]
BadLength {
/// The found length
found: usize,
/// The expected length
expected: usize,
},
// TODO: this should be handled better, it's too generic
#[doc(hidden)]
#[error("Invalid I/O operation")]
Io(#[from] io::Error),
}

impl From<Error> for io::Error {
fn from(err: Error) -> io::Error {
io::Error::new(io::ErrorKind::Other, format!("{}", err))
#[cfg(feature = "std")]
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Dusk PKI Error: {:?}", &self)
}
}
4 changes: 3 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@
//! This repository has been created so there's a unique library that holds the
//! types and functions required to perform keys operations.
#![cfg_attr(not(feature = "std"), no_std)]
#![deny(missing_docs)]
#![allow(non_snake_case)]

pub use decode::decode as jubjub_decode;

/// PKI Errors
pub use errors::Error;
/// Public Spend Key
Expand All @@ -30,8 +32,8 @@ pub use view::ViewKey;

mod decode;
mod errors;
mod permutation;
mod spend;
mod sponge;
mod view;

use dusk_jubjub::{JubJubAffine, JubJubExtended, JubJubScalar};
16 changes: 14 additions & 2 deletions src/sponge.rs → src/permutation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,21 @@
// Copyright (c) DUSK NETWORK. All rights reserved.

use crate::{JubJubExtended, JubJubScalar};
use poseidon252::sponge::sponge::sponge_hash;

use dusk_bls12_381::BlsScalar;
use hades252::{ScalarStrategy, Strategy};

use core::cmp;

/// Hashes a JubJub's ExtendedPoint into a JubJub's Scalar
pub fn hash(p: &JubJubExtended) -> JubJubScalar {
JubJubScalar::from_raw(sponge_hash(&p.to_hash_inputs()).reduce().0)
let mut perm = [BlsScalar::zero(); hades252::WIDTH];
let p = p.to_hash_inputs();

let n = cmp::min(hades252::WIDTH, p.len());

perm[0..n].copy_from_slice(&p[0..n]);
ScalarStrategy::new().perm(&mut perm);

JubJubScalar::from_raw(perm[1].reduce().0)
}
22 changes: 14 additions & 8 deletions src/spend/public.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,26 @@
//
// Copyright (c) DUSK NETWORK. All rights reserved.

use super::secret::SecretKey;
use super::stealth::StealthAddress;

use crate::sponge;
#[cfg(feature = "std")]
use crate::Error;
use crate::{
decode::decode, Error, JubJubAffine, JubJubExtended, JubJubScalar,
permutation, JubJubAffine, JubJubExtended, JubJubScalar, StealthAddress,
};

use super::secret::SecretKey;

#[cfg(feature = "canon")]
use canonical::Canon;
#[cfg(feature = "canon")]
use canonical_derive::Canon;

use dusk_jubjub::GENERATOR_EXTENDED;
use std::convert::TryFrom;
use std::fmt;
use subtle::{Choice, ConstantTimeEq};

#[cfg(feature = "std")]
use core::convert::TryFrom;
use core::fmt;

/// Public pair of `a·G` and `b·G`
#[derive(Debug, Clone, Copy)]
#[cfg_attr(feature = "canon", derive(Canon))]
Expand Down Expand Up @@ -52,7 +55,7 @@ impl PublicKey {
let R = G * r;

let rA = self.A * r;
let rA = sponge::hash(&rA);
let rA = permutation::hash(&rA);
let rA = G * rA;

let pk_r = rA + self.B;
Expand Down Expand Up @@ -102,10 +105,13 @@ impl From<&PublicKey> for [u8; 64] {
}
}

#[cfg(feature = "std")]
impl TryFrom<String> for PublicKey {
type Error = Error;

fn try_from(s: String) -> Result<Self, Self::Error> {
use crate::decode::decode;

if s.len() != 128 {
return Err(Error::BadLength {
found: s.len(),
Expand Down
47 changes: 23 additions & 24 deletions src/spend/secret.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,39 +4,32 @@
//
// Copyright (c) DUSK NETWORK. All rights reserved.

use crate::{permutation, JubJubScalar, ViewKey};

use super::public::PublicKey;
use super::stealth::StealthAddress;

use crate::sponge;
use crate::{JubJubScalar, ViewKey};

use dusk_jubjub::GENERATOR_EXTENDED;

use std::fmt;

#[cfg(feature = "canon")]
use canonical::Canon;
#[cfg(feature = "canon")]
use canonical_derive::Canon;
use rand::rngs::StdRng;

use dusk_jubjub::GENERATOR_EXTENDED;
use rand_core::{CryptoRng, RngCore};

use core::fmt;

#[cfg(feature = "std")]
use rand::SeedableRng;
use rand::{CryptoRng, RngCore};
use sha2::{Digest, Sha256};

/// Secret pair of `a` and `b`
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "canon", derive(Canon))]
pub struct SecretKey {
a: JubJubScalar,
b: JubJubScalar,
}

impl Default for SecretKey {
fn default() -> Self {
SecretKey::random(&mut rand::thread_rng())
}
}

impl SecretKey {
/// This method is used to construct a new `SecretKey` from the given secret
/// pair of `a` and `b`.
Expand All @@ -54,13 +47,6 @@ impl SecretKey {
&self.b
}

/// Generate a `sk_r = H(a · R) + b`
pub fn sk_r(&self, sa: &StealthAddress) -> JubJubScalar {
let aR = sa.R() * self.a;
let aR = sponge::hash(&aR);
aR + self.b
}

/// Deterministically create a new [`SecretKey`] from a random number
/// generator
pub fn random<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
Expand All @@ -70,6 +56,14 @@ impl SecretKey {
SecretKey::new(a, b)
}

/// Generate a `sk_r = H(a · R) + b`
pub fn sk_r(&self, sa: &StealthAddress) -> JubJubScalar {
let aR = sa.R() * self.a;
let aR = permutation::hash(&aR);

aR + self.b
}

/// Derive the secret to deterministically construct a [`PublicKey`]
pub fn public_key(&self) -> PublicKey {
let A = GENERATOR_EXTENDED * self.a;
Expand All @@ -95,8 +89,12 @@ impl From<&SecretKey> for [u8; 64] {
}
}

#[cfg(feature = "std")]
impl From<&[u8]> for SecretKey {
fn from(bytes: &[u8]) -> Self {
use rand::rngs::StdRng;
use sha2::{Digest, Sha256};

let mut hasher = Sha256::default();
hasher.input(bytes);
let bytes = hasher.result();
Expand All @@ -108,6 +106,7 @@ impl From<&[u8]> for SecretKey {
}
}

#[cfg(feature = "std")]
impl From<String> for SecretKey {
fn from(s: String) -> Self {
Self::from(s.into_bytes().as_slice())
Expand Down
Loading

0 comments on commit 668f3d7

Please sign in to comment.