-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit ad3b85f
Showing
6 changed files
with
351 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
/target | ||
**/*.rs.bk | ||
Cargo.lock | ||
*~ | ||
*.bak |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
language: rust | ||
rust: | ||
- nightly | ||
sudo: false | ||
|
||
# only cache cargo subcommand binaries and .so libs | ||
# the build artifacts take a lot of space and are slower to | ||
# cache than to actually rebuild anyway... | ||
# We need to cache the whole .cargo directory to keep the | ||
# .crates.toml file. | ||
cache: | ||
directories: | ||
- /home/travis/install | ||
- /home/travis/.cargo | ||
|
||
# But don't cache the cargo registry | ||
before_cache: | ||
- rm -rf /home/travis/.cargo/registry | ||
before_script: | ||
- | | ||
if command -v cargo >/dev/null; then | ||
export PATH=$HOME/.cargo/bin:$PATH | ||
mkdir $(pwd)/socket | ||
export XDG_RUNTIME_DIR="$(pwd)/socket" | ||
cargo fetch | ||
rustup component add rustfmt-preview | ||
if [ -n "$CLIPPY" ]; then | ||
rustup component add clippy | ||
fi | ||
fi | ||
script: | ||
- | | ||
if [ -n "$BUILD_FMT" ]; then | ||
cargo fmt --all -- --check | ||
rustfmt --check src/*.rs | ||
elif [ -n "$CLIPPY" ]; then | ||
cargo clippy --all -- -D warnings \ | ||
-A clippy::deprecated_cfg_attr \ | ||
-A clippy::for_loop_over_option | ||
elif [ -n "$CARGO_TEST" ]; then | ||
cargo test --all --features "$FEATURES" | ||
fi | ||
matrix: | ||
include: | ||
- rust: nightly | ||
env: BUILD_FMT=1 | ||
- rust: nightly | ||
env: CLIPPY=1 | ||
- rust: nightly | ||
env: CARGO_TEST=1 | ||
notifications: | ||
slack: | ||
secure: 'UzMDp+QAQmykQRh3X2zPZnxICvEH9YPynCPQ6AEsmdVb9Or3VleaYM8i+E7x5jT1HFloBJyI1G0mqrFQIbYDQug5nFUsfB2CYi7L0dpUtvoWbDMGoJ/lDI/wJDt64lqhHf9hs1aeYq454Zqcmx6/oKCgnRSyXip6y/mtOlQYjwhGN0D+TARF+6IohqJMg5iEQg4sWvugVur3GbFbatNeevLOYuhezdun4S8vhzQKsFJBK5QnIuufEyeHHjA3Ii5/yyqXUnxtRnLctjPWR+EROBO/mgqBUXPTwheiYqg9Gw9lYSRuBrtP+eixSKWnknju12YzlhAIF/HegRGzLG2PUGgLuB0TBAraaLYOODpBanVfN7DMvhg72Embdy0lZzVYPN8ImwGIU7jisWPI3x6Zz3zdI1lXZaMFS2ijlbRbYZE1YoOhS0iFQuYUc4dwu+D9Ql+IqZZ+BwE5AOy3cY149WrwGX0xaqwPad80HNHy5PUKKLxE8ZLXD0AQsWxi5M7UrHvJ7XOMRPEkskm6zNBuSXrU1vRibbtOaAC+xdPWop5j0Chf99CuIyH6NeqWVwpvl8ddTJGFZeoNXBXOp6+WAxyAJa1Z77rOvmjhdgrvcFh0o3176KCpFBQM0rWt1IVy1LFFsCP9KzMjBN1vAeEaCJZF0yQjXg/58lUTnR5a28A=' | ||
- language: python | ||
sudo: required | ||
dist: xenial | ||
python: | ||
- '3.7' | ||
env: | ||
- COMMENT_EXTRACTION=comment-extraction-master | ||
- EXTRACTED_DIR=docs/extracted-comments | ||
- INPUT_DIR=libsignature/src | ||
- LANGUAGE=rust | ||
- ROOT_URL=https://github.com/Fantom-Foundation/libsignature-ed25519-dalek | ||
before_install: | ||
- curl -L https://github.com/dev10/comment-extraction/archive/master.tar.gz -o | ||
comment-extraction.tgz | ||
- tar xf comment-extraction.tgz | ||
install: | ||
- pip install -r $COMMENT_EXTRACTION/requirements.txt | ||
script: | ||
- > | ||
python $COMMENT_EXTRACTION/antlr.py | ||
-l $LANGUAGE | ||
-o $EXTRACTED_DIR | ||
-ct $TRAVIS_COMMIT | ||
-ru $ROOT_URL | ||
-d $INPUT_DIR | ||
after_success: | ||
- cd docs/ | ||
- pip install -r requirements.txt | ||
- make html | ||
- "./deploy.sh" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
[package] | ||
name = "libsignature-ed25519-dalek" | ||
version = "0.1.0" | ||
authors = ["Maxim Zakharov <5158255+Maxime2@users.noreply.github.com>"] | ||
edition = "2018" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] | ||
libcommon-rs = { git = "https://github.com/Fantom-foundation/libcommon-rs" } | ||
libhash = { git = "https://github.com/Fantom-foundation/libhash" } | ||
libsignature = { git = "https://github.com/Fantom-foundation/libsignature" } | ||
serde = "1.0.80" | ||
serde_derive = "1.0.80" | ||
|
||
[dependencies.ed25519-dalek] | ||
version = "1.0.0-pre.1" | ||
features = ["serde"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
MIT License | ||
|
||
Copyright (c) 2018 Fantom Foundation | ||
|
||
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
libsignature-ed25519-dalek | ||
============ | ||
[![Build Status](https://travis-ci.org/Fantom-foundation/libsignature-ed25519-dalek.svg?branch=master)](https://travis-ci.org/Fantom-foundation/libsignature-ed25519-dalek) | ||
|
||
libsignature-ed25519-dalek in Rust. | ||
|
||
## RFCs | ||
|
||
https://github.com/Fantom-foundation/fantom-rfcs | ||
|
||
# Developer guide | ||
|
||
Install the latest version of [Rust](https://www.rust-lang.org). We tend to use nightly versions. [CLI tool for installing Rust](https://rustup.rs). | ||
|
||
We use [rust-clippy](https://github.com/rust-lang-nursery/rust-clippy) linters to improve code quality. | ||
|
||
There are plenty of [IDEs](https://areweideyet.com) and other [Rust development tools to consider](https://github.com/rust-unofficial/awesome-rust#development-tools). | ||
|
||
### Description | ||
|
||
For an example of the traits see: | ||
https://github.com/Fantom-foundation/libsignature. | ||
|
||
### Step-by-step guide | ||
```bash | ||
# Install Rust (nightly) | ||
$ curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain nightly | ||
# Install cargo-make (cross-platform feature-rich reimplementation of Make) | ||
$ cargo install --force cargo-make | ||
# Install rustfmt (Rust formatter) | ||
$ rustup component add rustfmt | ||
# Clone this repo | ||
$ git clone https://github.com/Fantom-foundation/libsignature-ed25519-dalek && cd libsignature-ed25519-dalek | ||
# Run tests | ||
$ cargo test | ||
# Format, build and test | ||
$ cargo make | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,185 @@ | ||
use core::convert::TryInto; | ||
use core::fmt::Display; | ||
use core::fmt::Formatter; | ||
use core::hash::Hash; | ||
use core::hash::Hasher; | ||
use core::marker::PhantomData; | ||
use ed25519_dalek::{PUBLIC_KEY_LENGTH, SECRET_KEY_LENGTH, SIGNATURE_LENGTH}; | ||
use libhash::Hash as LibHash; | ||
use libsignature::Signature as LibSignature; | ||
use serde::{Deserialize, Deserializer, Serialize, Serializer}; | ||
|
||
#[derive(Clone, PartialOrd, Ord, Debug, Deserialize, Serialize)] | ||
pub struct PublicKey([u8; PUBLIC_KEY_LENGTH]); | ||
|
||
#[derive(Clone, PartialOrd, Ord, Debug, Deserialize, Serialize)] | ||
pub struct SecretKey([u8; SECRET_KEY_LENGTH]); | ||
|
||
#[derive(Clone, Copy, Deserialize, Serialize)] | ||
pub struct Signature<H>( | ||
#[serde(serialize_with = "serialize_array")] | ||
#[serde(deserialize_with = "deserialize_array")] | ||
[u8; SIGNATURE_LENGTH], | ||
PhantomData<H>, | ||
); | ||
|
||
const DEFAULT_PUBLIC_KEY: PublicKey = PublicKey { | ||
0: [0; PUBLIC_KEY_LENGTH], | ||
}; | ||
const DEFAULT_SECRET_KEY: SecretKey = SecretKey { | ||
0: [0; SECRET_KEY_LENGTH], | ||
}; | ||
|
||
impl<H: LibHash> LibSignature for Signature<H> { | ||
type Hash = H; | ||
type PublicKey = PublicKey; | ||
type SecretKey = SecretKey; | ||
type Error = ed25519_dalek::SignatureError; | ||
fn sign(hash: H, key: SecretKey) -> Result<Self, Self::Error> { | ||
let keypair = ed25519_dalek::Keypair { | ||
secret: key.try_into()?, | ||
public: DEFAULT_PUBLIC_KEY.try_into()?, | ||
}; | ||
Ok(keypair.sign(hash.as_ref()).into()) | ||
} | ||
fn verify(&self, hash: H, key: PublicKey) -> Result<bool, Self::Error> { | ||
let pubkey: ed25519_dalek::PublicKey = key.try_into()?; | ||
let sig: ed25519_dalek::Signature = (*self).try_into()?; | ||
Ok(pubkey.verify(hash.as_ref(), &sig).is_ok()) | ||
} | ||
} | ||
|
||
impl From<ed25519_dalek::PublicKey> for PublicKey { | ||
fn from(k: ed25519_dalek::PublicKey) -> Self { | ||
PublicKey { 0: k.to_bytes() } | ||
} | ||
} | ||
|
||
impl TryInto<ed25519_dalek::PublicKey> for PublicKey { | ||
type Error = ed25519_dalek::SignatureError; | ||
fn try_into(self) -> Result<ed25519_dalek::PublicKey, Self::Error> { | ||
ed25519_dalek::PublicKey::from_bytes(&(self.0)) | ||
} | ||
} | ||
|
||
impl From<ed25519_dalek::SecretKey> for SecretKey { | ||
fn from(k: ed25519_dalek::SecretKey) -> Self { | ||
SecretKey { 0: k.to_bytes() } | ||
} | ||
} | ||
|
||
impl TryInto<ed25519_dalek::SecretKey> for SecretKey { | ||
type Error = ed25519_dalek::SignatureError; | ||
fn try_into(self) -> Result<ed25519_dalek::SecretKey, Self::Error> { | ||
ed25519_dalek::SecretKey::from_bytes(&(self.0)) | ||
} | ||
} | ||
|
||
impl<H> From<ed25519_dalek::Signature> for Signature<H> { | ||
fn from(s: ed25519_dalek::Signature) -> Self { | ||
Signature { | ||
0: s.to_bytes(), | ||
1: PhantomData, | ||
} | ||
} | ||
} | ||
|
||
impl<H> TryInto<ed25519_dalek::Signature> for Signature<H> { | ||
type Error = ed25519_dalek::SignatureError; | ||
fn try_into(self) -> Result<ed25519_dalek::Signature, Self::Error> { | ||
ed25519_dalek::Signature::from_bytes(&(self.0)) | ||
} | ||
} | ||
|
||
impl Default for PublicKey { | ||
fn default() -> Self { | ||
DEFAULT_PUBLIC_KEY | ||
} | ||
} | ||
impl Default for SecretKey { | ||
fn default() -> Self { | ||
DEFAULT_SECRET_KEY | ||
} | ||
} | ||
|
||
impl Eq for PublicKey {} | ||
|
||
impl Eq for SecretKey {} | ||
|
||
impl PartialEq for PublicKey { | ||
#[inline] | ||
fn eq(&self, other: &PublicKey) -> bool { | ||
self.0[..] == other.0[..] | ||
} | ||
} | ||
|
||
impl PartialEq for SecretKey { | ||
#[inline] | ||
fn eq(&self, other: &SecretKey) -> bool { | ||
self.0[..] == other.0[..] | ||
} | ||
} | ||
|
||
impl Hash for PublicKey { | ||
fn hash<H: Hasher>(&self, state: &mut H) { | ||
self.0.hash(state) | ||
} | ||
} | ||
impl Hash for SecretKey { | ||
fn hash<H: Hasher>(&self, state: &mut H) { | ||
self.0.hash(state) | ||
} | ||
} | ||
|
||
impl Display for PublicKey { | ||
fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { | ||
let mut formatted = String::new(); | ||
formatted.push_str(&self.0[0].to_string()); | ||
for num in &self.0[1..self.0.len()] { | ||
formatted.push_str(", "); | ||
formatted.push_str(&num.to_string()); | ||
} | ||
write!(f, "{}", formatted) | ||
} | ||
} | ||
|
||
impl Display for SecretKey { | ||
fn fmt(&self, f: &mut Formatter) -> core::fmt::Result { | ||
let mut formatted = String::new(); | ||
formatted.push_str(&self.0[0].to_string()); | ||
for num in &self.0[1..self.0.len()] { | ||
formatted.push_str(", "); | ||
formatted.push_str(&num.to_string()); | ||
} | ||
write!(f, "{}", formatted) | ||
} | ||
} | ||
|
||
fn serialize_array<S, T>(array: &[T], serializer: S) -> Result<S::Ok, S::Error> | ||
where | ||
S: Serializer, | ||
T: Serialize, | ||
{ | ||
array.serialize(serializer) | ||
} | ||
|
||
fn deserialize_array<'de, D>(deserializer: D) -> Result<[u8; 64], D::Error> | ||
where | ||
D: Deserializer<'de>, | ||
{ | ||
let mut result: [u8; 64] = [0; 64]; | ||
let slice: Vec<u8> = Deserialize::deserialize(deserializer)?; | ||
if slice.len() != 64 { | ||
return Err(::serde::de::Error::custom("input slice has wrong length")); | ||
} | ||
result.copy_from_slice(&slice); | ||
Ok(result) | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
#[test] | ||
fn it_works() { | ||
assert_eq!(2 + 2, 4); | ||
} | ||
} |