Skip to content

Commit 68a495d

Browse files
Merge pull request #10 from andrewwhitehead/updates
Update dependencies, enable MacOS universal build
2 parents 9aa8f60 + c663e39 commit 68a495d

File tree

9 files changed

+99
-57
lines changed

9 files changed

+99
-57
lines changed

.github/workflows/build.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,10 @@ jobs:
5555
strategy:
5656
matrix:
5757
include:
58-
- os: macos-latest # macos-11.0 for universal
58+
- os: macos-11
5959
lib: libindy_credx.dylib
60-
# target: apple-darwin
61-
toolchain: stable # beta for universal
60+
target: apple-darwin
61+
toolchain: beta # beta required for Darwin build
6262
- os: windows-latest
6363
lib: indy_credx.dll
6464
toolchain: stable
@@ -109,13 +109,13 @@ jobs:
109109

110110
strategy:
111111
matrix:
112-
os: [ubuntu-latest, macos-latest, windows-latest]
112+
os: [ubuntu-latest, macos-11, windows-latest]
113113
python-version: [3.6]
114114
include:
115115
- os: ubuntu-latest
116116
plat-name: manylinux2014_x86_64
117-
- os: macos-latest
118-
plat-name: macosx_10_9_x86_64 # macosx_10_9_universal2
117+
- os: macos-11
118+
plat-name: macosx_10_9_universal2 # macosx_10_9_x86_64
119119
- os: windows-latest
120120
plat-name: win_amd64
121121

indy-credx/Cargo.toml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "indy-credx"
3-
version = "0.3.0"
3+
version = "0.3.1"
44
authors = ["Hyperledger Indy Contributors <[email protected]>"]
55
description = "Verifiable credential issuance and presentation for Hyperledger Indy (https://www.hyperledger.org/projects), which provides a distributed-ledger-based foundation for self-sovereign identity (https://sovrin.org)."
66
edition = "2018"
@@ -24,24 +24,24 @@ vendored = ["indy-data-types/vendored"]
2424
[dependencies]
2525
env_logger = { version = "0.7.1", optional = true }
2626
ffi-support = { version = "0.4.0", optional = true }
27-
log = "0.4.8"
28-
once_cell = "1.4"
27+
log = "0.4"
28+
once_cell = "1.9"
2929
rand = "0.7"
3030
regex = "1.2.1"
3131
serde = { version = "1.0", features = ["derive"] }
3232
serde_json = "1.0"
3333
sha2 = "0.9"
3434
tempfile = "3.1.0"
35-
thiserror = "1.0.9"
36-
zeroize = { version = "1.1", optional = true }
35+
thiserror = "1.0"
36+
zeroize = { version = "1.3", optional = true }
3737

3838
[dependencies.indy-data-types]
3939
version = "0.5"
4040
path = "../indy-data-types"
4141
features = ["cl_native"]
4242

4343
[dependencies.indy-utils]
44-
version = "0.4"
44+
version = "0.5"
4545
path = "../indy-utils"
4646
default-features = false
4747
features = ["wql"]

indy-data-types/Cargo.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "indy-data-types"
3-
version = "0.5.0"
3+
version = "0.5.1"
44
authors = ["Hyperledger Indy Contributors <[email protected]>"]
55
description = "Common data types for Hyperledger Indy (https://www.hyperledger.org/projects), which provides a distributed-ledger-based foundation for self-sovereign identity (https://sovrin.org)."
66
edition = "2018"
@@ -27,15 +27,15 @@ vendored = ["openssl", "openssl/vendored"]
2727
[dependencies]
2828
hex = { version = "0.4", optional = true }
2929
openssl = { version = "0.10", optional = true }
30-
once_cell = "1.4"
30+
once_cell = "1.9"
3131
regex = "1.3"
3232
serde = { version = "1.0", optional = true, features = ["derive"] }
3333
serde_json = { version = "1.0", optional = true, features = ["raw_value"] }
34-
ursa = { version = "0.3.5", default-features = false, optional = true }
34+
ursa = { version = "=0.3.6", default-features = false, optional = true }
3535
zeroize = { version = "1.1", features = ["zeroize_derive"] }
3636

3737
[dependencies.indy-utils]
38-
version = "0.4"
38+
version = "0.5"
3939
path = "../indy-utils"
4040
default-features = false
4141
features = ["wql"]

indy-data-types/src/macros.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@ macro_rules! unwrap_opt_or_return {
33
match $opt {
44
Some(val) => val,
55
None => return $err,
6-
};
6+
}
77
};
88
}

indy-utils/Cargo.toml

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "indy-utils"
3-
version = "0.4.0"
3+
version = "0.5.0"
44
authors = ["Hyperledger Indy Contributors <[email protected]>"]
55
description = "Utilities for Hyperledger Indy (https://www.hyperledger.org/projects), which provides a distributed-ledger-based foundation for self-sovereign identity (https://sovrin.org)."
66
edition = "2018"
@@ -18,25 +18,27 @@ crate-type = ["rlib"]
1818
[features]
1919
default = ["ed25519", "hash", "txn_signature", "wql"]
2020
base64 = ["base64_rs"]
21-
ed25519 = ["ursa", "ursa/ed25519", "ursa/x25519"]
21+
ed25519 = ["curve25519-dalek", "ed25519-dalek", "rand", "sha2", "x25519-dalek"]
2222
hash = ["sha2"]
2323
txn_signature = ["hex", "sha2", "serde", "serde_json"]
2424
wql = ["indy-wql", "serde", "serde_json"]
2525

2626
[dependencies]
27-
aead = "0.3"
2827
base64_rs = { package = "base64", version = "0.12", optional = true }
2928
bs58 = "0.3"
29+
curve25519-dalek = { version = "3.1", default-features = false, features = ["u64_backend"], optional = true }
30+
ed25519-dalek = { version = "1.0", default-features = false, features = ["u64_backend"], optional = true }
3031
hex = { version = "0.4", optional = true }
3132
indy-wql = { version = "0.4", optional = true, path = "../indy-wql" }
32-
once_cell = "1.4"
33+
once_cell = "1.9"
34+
rand = { version = "0.8", optional = true }
3335
regex = "1.3"
3436
serde = { version = "1.0", optional = true, features = ["derive"] }
3537
serde_json = { version = "1.0", optional = true }
3638
sha2 = { version = "0.9", optional = true }
3739
thiserror = "1.0"
38-
ursa = { version = "0.3.5", default-features = false, optional = true }
39-
zeroize = { version = "1.1" }
40+
x25519-dalek = { version = "=1.1", default-features = false, features = ["u64_backend"], optional = true }
41+
zeroize = { version = "1.3" }
4042

4143
[dev-dependencies]
4244
async-global-executor = "1.2"

indy-utils/src/keys/mod.rs

Lines changed: 72 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
#[cfg(feature = "ed25519")]
2-
use ursa::signatures::{ed25519::Ed25519Sha512, SignatureScheme};
2+
use curve25519_dalek::edwards::CompressedEdwardsY;
3+
#[cfg(feature = "ed25519")]
4+
use ed25519_dalek::{ExpandedSecretKey, PublicKey, SecretKey, Signature};
5+
#[cfg(feature = "ed25519")]
6+
use rand::{thread_rng, RngCore};
7+
#[cfg(feature = "ed25519")]
8+
use sha2::digest::Digest;
9+
10+
#[cfg(feature = "ed25519")]
11+
use std::convert::TryFrom;
312

413
use zeroize::Zeroize;
514

@@ -35,20 +44,22 @@ impl PrivateKey {
3544
let alg = alg.unwrap_or_default();
3645
match alg {
3746
KeyType::ED25519 => {
38-
let (_pk, sk) = Ed25519Sha512
39-
.keypair(None)
40-
.map_err(|_| "Error creating signing key")?;
41-
Ok(Self::new(sk, Some(KeyType::ED25519)))
47+
let mut sk = [0u8; 32];
48+
thread_rng().fill_bytes(&mut sk[..]);
49+
Self::from_seed(&sk[..])
4250
}
4351
_ => Err("Unsupported key type".into()),
4452
}
4553
}
4654

4755
#[cfg(feature = "ed25519")]
4856
pub fn from_seed(seed: &[u8]) -> Result<Self, ConversionError> {
49-
let (_pk, sk) = Ed25519Sha512::expand_keypair(seed)
57+
let sk = SecretKey::from_bytes(seed)
5058
.map_err(|err| format!("Error creating signing key: {}", err))?;
51-
Ok(Self::new(sk, Some(KeyType::ED25519)))
59+
let mut esk = [0u8; 64];
60+
esk[..32].copy_from_slice(sk.as_bytes());
61+
esk[32..].copy_from_slice(PublicKey::from(&sk).as_bytes());
62+
Ok(Self::new(esk, Some(KeyType::ED25519)))
5263
}
5364

5465
pub fn public_key(&self) -> Result<VerKey, ConversionError> {
@@ -66,10 +77,11 @@ impl PrivateKey {
6677
pub fn key_exchange(&self) -> Result<Self, ConversionError> {
6778
match self.alg {
6879
KeyType::ED25519 => {
69-
let sk = ursa::keys::PrivateKey(self.key_bytes());
70-
let x_sk = Ed25519Sha512::sign_key_to_key_exchange(&sk)
71-
.map_err(|err| format!("Error converting to x25519 key: {}", err))?;
72-
Ok(Self::new(&x_sk, Some(KeyType::X25519)))
80+
let mut hash = sha2::Sha512::digest(&self.key[..32]);
81+
let x_sk =
82+
x25519_dalek::StaticSecret::from(<[u8; 32]>::try_from(&hash[..32]).unwrap());
83+
hash.zeroize();
84+
Ok(Self::new(&x_sk.to_bytes(), Some(KeyType::X25519)))
7385
}
7486
_ => Err("Unsupported key format for key exchange".into()),
7587
}
@@ -79,10 +91,10 @@ impl PrivateKey {
7991
pub fn sign<M: AsRef<[u8]>>(&self, message: M) -> Result<Vec<u8>, ConversionError> {
8092
match self.alg {
8193
KeyType::ED25519 => {
82-
let sk = ursa::keys::PrivateKey(self.key_bytes());
83-
Ok(Ed25519Sha512
84-
.sign(message.as_ref(), &sk)
85-
.map_err(|err| format!("Error signing payload: {}", err))?)
94+
let esk = ExpandedSecretKey::from(&SecretKey::from_bytes(&self.key[..32]).unwrap());
95+
let pk = PublicKey::from_bytes(&self.key[32..]).unwrap();
96+
let sig = esk.sign(message.as_ref(), &pk);
97+
Ok(sig.to_bytes().into())
8698
}
8799
_ => Err("Unsupported key format for signing".into()),
88100
}
@@ -164,11 +176,15 @@ impl VerKey {
164176
pub fn key_exchange(&self) -> Result<Self, ConversionError> {
165177
match self.alg {
166178
KeyType::ED25519 => {
167-
let vk = ursa::keys::PublicKey(self.key_bytes());
168-
let x_vk = Ed25519Sha512::ver_key_to_key_exchange(&vk).map_err(|err| {
169-
format!("Error converting to x25519 key: {}", err.to_string())
170-
})?;
171-
Ok(Self::new(&x_vk, Some(KeyType::X25519)))
179+
let vky = CompressedEdwardsY::from_slice(&self.key[..]);
180+
if let Some(x_vk) = vky.decompress() {
181+
Ok(Self::new(
182+
x_vk.to_montgomery().as_bytes().to_vec(),
183+
Some(KeyType::X25519),
184+
))
185+
} else {
186+
Err("Error converting to x25519 key".into())
187+
}
172188
}
173189
_ => Err("Unsupported verkey type".into()),
174190
}
@@ -182,10 +198,12 @@ impl VerKey {
182198
) -> Result<bool, ConversionError> {
183199
match self.alg {
184200
KeyType::ED25519 => {
185-
let vk = ursa::keys::PublicKey(self.key_bytes());
186-
Ok(Ed25519Sha512
187-
.verify(message.as_ref(), signature.as_ref(), &vk)
188-
.map_err(|err| format!("Error validating message signature: {}", err))?)
201+
let vk = PublicKey::from_bytes(&self.key[..]).unwrap();
202+
if let Ok(sig) = Signature::try_from(signature.as_ref()) {
203+
Ok(vk.verify_strict(message.as_ref(), &sig).is_ok())
204+
} else {
205+
Err("Error validating message signature".into())
206+
}
189207
}
190208
_ => Err("Unsupported verkey type".into()),
191209
}
@@ -258,13 +276,11 @@ impl EncodedVerKey {
258276
if key.chars().next() == Some('~') {
259277
let mut vk_bytes = base58::decode(&key[1..])?;
260278
if vk_bytes.len() != 16 {
261-
return Err(ConversionError::from_msg(
262-
"Expected 16-byte abbreviated verkey",
263-
));
279+
return Err("Expected 16-byte abbreviated verkey".into());
264280
}
265281
let mut did_bytes = base58::decode(did)?;
266282
if did_bytes.len() != 16 {
267-
return Err(ConversionError::from_msg("DID must be 16 bytes in length"));
283+
return Err("DID must be 16 bytes in length".into());
268284
}
269285
did_bytes.append(&mut vk_bytes);
270286
Ok(Self::new(
@@ -284,11 +300,11 @@ impl EncodedVerKey {
284300
pub fn abbreviated_for_did(&self, did: &str) -> Result<String, ConversionError> {
285301
let did_bytes = base58::decode(did)?;
286302
if did_bytes.len() != 16 {
287-
return Err(ConversionError::from_msg("DID must be 16 bytes in length"));
303+
return Err("DID must be 16 bytes in length".into());
288304
}
289305
let vk = self.key_bytes()?;
290306
if vk.len() != 32 {
291-
return Err(ConversionError::from_msg("Expected 32-byte verkey"));
307+
return Err("Expected 32-byte verkey".into());
292308
}
293309
if &vk[..16] == did_bytes.as_slice() {
294310
let mut result = "~".to_string();
@@ -487,6 +503,30 @@ mod tests {
487503
)
488504
}
489505

506+
#[cfg(feature = "ed25519")]
507+
#[test]
508+
fn key_from_seed() {
509+
const SEED: &[u8; 32] = b"aaaabbbbccccddddeeeeffffgggghhhh";
510+
let sk = PrivateKey::from_seed(&SEED[..]).unwrap();
511+
assert_eq!(
512+
&sk.as_ref()[..],
513+
&[
514+
97, 97, 97, 97, 98, 98, 98, 98, 99, 99, 99, 99, 100, 100, 100, 100, 101, 101, 101,
515+
101, 102, 102, 102, 102, 103, 103, 103, 103, 104, 104, 104, 104, 113, 22, 13, 44,
516+
71, 184, 166, 148, 196, 234, 85, 148, 234, 22, 204, 148, 187, 247, 77, 119, 250,
517+
28, 37, 255, 29, 31, 159, 159, 245, 68, 107, 235
518+
]
519+
);
520+
let xk = sk.key_exchange().unwrap();
521+
assert_eq!(
522+
&xk.as_ref(),
523+
&[
524+
208, 235, 232, 147, 241, 214, 250, 182, 45, 157, 20, 202, 31, 184, 226, 115, 149,
525+
82, 210, 89, 50, 100, 22, 67, 21, 8, 124, 198, 100, 252, 237, 107
526+
]
527+
);
528+
}
529+
490530
#[cfg(feature = "ed25519")]
491531
#[test]
492532
fn sign_and_verify() {
@@ -495,6 +535,8 @@ mod tests {
495535
let sig = sk.sign(&message).unwrap();
496536
let vk = sk.public_key().unwrap();
497537
assert!(vk.verify_signature(&message, &sig).unwrap());
538+
assert!(vk.verify_signature(&message, &[]).is_err());
539+
assert!(!vk.verify_signature(&"goodbye", &sig).unwrap());
498540
}
499541

500542
#[cfg(feature = "ed25519")]

indy-utils/src/lib.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
pub extern crate aead;
2-
31
#[cfg(any(feature = "serde", test))]
42
#[macro_use]
53
pub extern crate serde;

indy-utils/src/macros.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ macro_rules! unwrap_opt_or_return {
33
match $opt {
44
Some(val) => val,
55
None => return $err,
6-
};
6+
}
77
};
88
}
99

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
"""indy_credx library wrapper version."""
22

3-
__version__ = "0.3.0"
3+
__version__ = "0.3.1"

0 commit comments

Comments
 (0)