Skip to content

Commit acc406d

Browse files
majectymergify[bot]
authored andcommitted
Add seal and open in the key crate
1 parent 403f4b3 commit acc406d

File tree

6 files changed

+228
-1
lines changed

6 files changed

+228
-1
lines changed

key/src/encryption.rs

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright 2020 Kodebox, Inc.
2+
// This file is part of CodeChain.
3+
//
4+
// This program is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU General Public License as
6+
// published by the Free Software Foundation, either version 3 of the
7+
// License, or (at your option) any later version.
8+
//
9+
// This program is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU General Public License
15+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
16+
17+
mod keypair;
18+
mod private;
19+
mod public;
20+
21+
pub use keypair::KeyPair;
22+
pub use private::Private;
23+
pub use public::Public;
24+
use sodiumoxide::crypto::sealedbox;
25+
26+
pub fn encrypt(message: &[u8], public: &Public) -> Vec<u8> {
27+
let Public(public) = public;
28+
sealedbox::seal(message, public)
29+
}
30+
31+
pub fn decrypt(encrypted: &[u8], public: &Public, private: &Private) -> Result<Vec<u8>, ()> {
32+
let Private(private) = private;
33+
let Public(public) = public;
34+
sealedbox::open(encrypted, public, private)
35+
}
36+
37+
#[cfg(test)]
38+
mod tests {
39+
use super::keypair::KeyPair;
40+
use crate::{decrypt, encrypt, Generator, KeyPairTrait, Random};
41+
#[test]
42+
fn open_and_seal() {
43+
let secret_data = b"Dr. Crowe was dead";
44+
let keypair: KeyPair = Random.generate().unwrap();
45+
let encrypted = encrypt(secret_data, keypair.public());
46+
let decrypted = decrypt(&encrypted, keypair.public(), keypair.private()).unwrap();
47+
assert_eq!(secret_data[..], decrypted[..]);
48+
}
49+
}

key/src/encryption/keypair.rs

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright 2020 Kodebox, Inc.
2+
// This file is part of CodeChain.
3+
//
4+
// This program is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU General Public License as
6+
// published by the Free Software Foundation, either version 3 of the
7+
// License, or (at your option) any later version.
8+
//
9+
// This program is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU General Public License
15+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
16+
17+
use super::private::Private;
18+
use super::public::Public;
19+
use crate::KeyPairTrait;
20+
21+
#[derive(Debug, Clone, PartialEq)]
22+
pub struct KeyPair {
23+
private: Private,
24+
public: Public,
25+
}
26+
27+
impl KeyPairTrait for KeyPair {
28+
type Private = Private;
29+
type Public = Public;
30+
31+
fn from_private(private: Self::Private) -> Self {
32+
KeyPair {
33+
public: private.public_key(),
34+
private,
35+
}
36+
}
37+
38+
fn from_keypair(private: Self::Private, public: Self::Public) -> Self {
39+
KeyPair {
40+
private,
41+
public,
42+
}
43+
}
44+
45+
fn private(&self) -> &Self::Private {
46+
&self.private
47+
}
48+
49+
fn public(&self) -> &Self::Public {
50+
&self.public
51+
}
52+
}

key/src/encryption/private.rs

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Copyright 2020 Kodebox, Inc.
2+
// This file is part of CodeChain.
3+
//
4+
// This program is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU General Public License as
6+
// published by the Free Software Foundation, either version 3 of the
7+
// License, or (at your option) any later version.
8+
//
9+
// This program is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU General Public License
15+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
16+
17+
use super::public::Public;
18+
use sodiumoxide::crypto::box_::SecretKey;
19+
20+
#[derive(Debug, Clone, PartialEq)]
21+
pub struct Private(pub(crate) SecretKey);
22+
23+
impl Private {
24+
pub fn from_slice(slice: &[u8]) -> Option<Self> {
25+
SecretKey::from_slice(slice).map(Self)
26+
}
27+
28+
pub fn public_key(&self) -> Public {
29+
self.0.public_key().into()
30+
}
31+
}
32+
33+
impl AsRef<[u8]> for Private {
34+
fn as_ref(&self) -> &[u8] {
35+
self.0.as_ref()
36+
}
37+
}
38+
39+
impl From<SecretKey> for Private {
40+
fn from(k: SecretKey) -> Self {
41+
Private(k)
42+
}
43+
}

key/src/encryption/public.rs

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright 2020 Kodebox, Inc.
2+
// This file is part of CodeChain.
3+
//
4+
// This program is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU General Public License as
6+
// published by the Free Software Foundation, either version 3 of the
7+
// License, or (at your option) any later version.
8+
//
9+
// This program is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU General Public License
15+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
16+
17+
use sodiumoxide::crypto::box_::PublicKey;
18+
19+
#[derive(Clone, Eq, PartialEq, Debug)]
20+
pub struct Public(pub(crate) PublicKey);
21+
22+
impl Public {
23+
pub fn from_slice(slice: &[u8]) -> Option<Self> {
24+
PublicKey::from_slice(slice).map(Self)
25+
}
26+
}
27+
28+
impl AsRef<[u8]> for Public {
29+
fn as_ref(&self) -> &[u8] {
30+
self.0.as_ref()
31+
}
32+
}
33+
34+
impl From<PublicKey> for Public {
35+
fn from(k: PublicKey) -> Self {
36+
Public(k)
37+
}
38+
}

key/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ extern crate codechain_crypto as crypto;
1919
extern crate serde_derive;
2020

2121
mod ed25519;
22+
mod encryption;
2223
mod error;
2324
mod keypair;
2425
mod network;
@@ -31,6 +32,7 @@ pub use crate::ed25519::{
3132
sign, verify, KeyPair as Ed25519KeyPair, Private as Ed25519Private, Public as Ed25519Public, Signature,
3233
SIGNATURE_LENGTH,
3334
};
35+
pub use crate::encryption::{decrypt, encrypt, KeyPair as SealKeyPair, Private as SealPrivate, Public as SealPublic};
3436
pub use crate::error::Error;
3537
pub use crate::keypair::KeyPair as KeyPairTrait;
3638
pub use crate::network::NetworkId;

key/src/random.rs

+44-1
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@
1414
// You should have received a copy of the GNU General Public License
1515
// along with this program. If not, see <https://www.gnu.org/licenses/>.
1616

17-
use crate::{Ed25519KeyPair, Generator, KeyPairTrait, X25519KeyPair, X25519Private, X25519Public};
17+
use crate::{Ed25519KeyPair, Generator, KeyPairTrait, SealKeyPair, X25519KeyPair, X25519Private, X25519Public};
1818
use never_type::Never;
1919
use rand::rngs::OsRng;
2020
#[cfg(test)]
2121
use rand::SeedableRng;
2222
use rand_xorshift::XorShiftRng;
23+
use sodiumoxide::crypto::box_::gen_keypair as gen_curve25519xsalsa20poly1305;
2324
use sodiumoxide::crypto::kx::gen_keypair as gen_x25519;
2425
use sodiumoxide::crypto::sign::gen_keypair as gen_ed25519;
2526
#[cfg(test)]
@@ -126,3 +127,45 @@ impl Generator<X25519KeyPair> for XorShiftRng {
126127
Ok(X25519KeyPair::from_keypair(sec, publ))
127128
}
128129
}
130+
131+
impl Generator<SealKeyPair> for Random {
132+
type Error = ::std::io::Error;
133+
134+
//FIXME: there is no distinction between the two generate functions
135+
#[cfg(not(test))]
136+
fn generate(&mut self) -> Result<SealKeyPair, Self::Error> {
137+
let mut rng = OsRng::new()?;
138+
match rng.generate() {
139+
Ok(pair) => Ok(pair),
140+
Err(never) => match never {}, // LLVM unreachable
141+
}
142+
}
143+
144+
#[cfg(test)]
145+
fn generate(&mut self) -> Result<SealKeyPair, Self::Error> {
146+
RNG.with(|rng| {
147+
match rng.borrow_mut().generate() {
148+
Ok(pair) => Ok(pair),
149+
Err(never) => match never {}, // LLVM unreachable
150+
}
151+
})
152+
}
153+
}
154+
155+
impl Generator<SealKeyPair> for OsRng {
156+
type Error = Never;
157+
158+
fn generate(&mut self) -> Result<SealKeyPair, Self::Error> {
159+
let (publ, sec) = gen_curve25519xsalsa20poly1305();
160+
Ok(SealKeyPair::from_keypair(sec.into(), publ.into()))
161+
}
162+
}
163+
164+
impl Generator<SealKeyPair> for XorShiftRng {
165+
type Error = Never;
166+
167+
fn generate(&mut self) -> Result<SealKeyPair, Self::Error> {
168+
let (publ, sec) = gen_curve25519xsalsa20poly1305();
169+
Ok(SealKeyPair::from_keypair(sec.into(), publ.into()))
170+
}
171+
}

0 commit comments

Comments
 (0)