Skip to content

Commit ce9eff8

Browse files
committed
chore(crypto): CRP-1317 Removed unnecessary clone from multisig library
1 parent 01cbc1c commit ce9eff8

File tree

11 files changed

+127
-334
lines changed

11 files changed

+127
-334
lines changed

rs/crypto/internal/crypto_lib/multi_sig/bls12_381/src/api.rs

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,33 @@
11
//! External API for the multisignature library
22
use super::crypto;
33
use super::types::{
4-
CombinedSignatureBytes, IndividualSignature, IndividualSignatureBytes, Pop, PopBytes,
5-
PublicKey, PublicKeyBytes, SecretKeyBytes,
4+
CombinedSignature, CombinedSignatureBytes, IndividualSignature, IndividualSignatureBytes, Pop,
5+
PopBytes, PublicKey, PublicKeyBytes, SecretKey, SecretKeyBytes,
66
};
77
use ic_types::crypto::{AlgorithmId, CryptoError};
88
use rand::{CryptoRng, Rng};
99
use std::convert::TryFrom;
10-
use std::convert::TryInto;
1110

1211
#[cfg(test)]
1312
mod tests;
1413

1514
/// Generates a keypair using the given `rng`.
1615
pub fn keypair_from_rng<R: Rng + CryptoRng>(rng: &mut R) -> (SecretKeyBytes, PublicKeyBytes) {
1716
let (secret_key, public_key) = crypto::keypair_from_rng(rng);
18-
(secret_key.into(), public_key.into())
17+
(
18+
SecretKeyBytes::from(&secret_key),
19+
PublicKeyBytes::from(&public_key),
20+
)
1921
}
2022

2123
/// Generates a multisignature on the given `message` using the given
2224
/// `secret_key`.
2325
///
2426
/// Note: This hashes the message to be signed. If we pre-hash, the hashing
2527
/// can be skipped. https://docs.rs/threshold_crypto/0.3.2/threshold_crypto/struct.SecretKey.html#method.sign
26-
pub fn sign(message: &[u8], secret_key: SecretKeyBytes) -> IndividualSignatureBytes {
27-
crypto::sign_message(message, &secret_key.into()).into()
28+
pub fn sign(message: &[u8], secret_key: &SecretKeyBytes) -> IndividualSignatureBytes {
29+
let signature = crypto::sign_message(message, &SecretKey::from(secret_key));
30+
IndividualSignatureBytes::from(&signature)
2831
}
2932

3033
/// Creates a proof of possession (PoP) of `secret_key_bytes`.
@@ -35,11 +38,12 @@ pub fn sign(message: &[u8], secret_key: SecretKeyBytes) -> IndividualSignatureBy
3538
/// * `CryptoError::MalformedPublicKey` if `public_key_bytes` cannot be parsed
3639
/// as a valid G2 point.
3740
pub fn create_pop(
38-
public_key_bytes: PublicKeyBytes,
39-
secret_key_bytes: SecretKeyBytes,
41+
public_key_bytes: &PublicKeyBytes,
42+
secret_key_bytes: &SecretKeyBytes,
4043
) -> Result<PopBytes, CryptoError> {
41-
let public_key = public_key_bytes.try_into()?;
42-
Ok(crypto::create_pop(&public_key, &secret_key_bytes.into()).into())
44+
let public_key = PublicKey::try_from(public_key_bytes)?;
45+
let pop = crypto::create_pop(&public_key, &SecretKey::from(secret_key_bytes));
46+
Ok(PopBytes::from(&pop))
4347
}
4448

4549
/// Verifies a public key's proof of possession (PoP).
@@ -54,8 +58,8 @@ pub fn create_pop(
5458
/// as a valid G2 point.
5559
/// * `CryptoError::PopVerification` if the given PoP fails to verify.
5660
pub fn verify_pop(
57-
pop_bytes: PopBytes,
58-
public_key_bytes: PublicKeyBytes,
61+
pop_bytes: &PopBytes,
62+
public_key_bytes: &PublicKeyBytes,
5963
) -> Result<(), CryptoError> {
6064
let pop = Pop::try_from(pop_bytes)?;
6165
let public_key = PublicKey::try_from(public_key_bytes)?;
@@ -81,11 +85,10 @@ pub fn combine(
8185
) -> Result<CombinedSignatureBytes, CryptoError> {
8286
let signatures: Result<Vec<IndividualSignature>, CryptoError> = signatures
8387
.iter()
84-
.cloned()
85-
.map(|signature_bytes| signature_bytes.try_into())
88+
.map(|signature_bytes| IndividualSignature::try_from(signature_bytes))
8689
.collect();
8790
let signature = crypto::combine_signatures(&signatures?);
88-
Ok(signature.into())
91+
Ok(CombinedSignatureBytes::from(&signature))
8992
}
9093

9194
/// Verifies an individual signature over the given `message` using the given
@@ -100,11 +103,11 @@ pub fn combine(
100103
/// fails.
101104
pub fn verify_individual(
102105
message: &[u8],
103-
signature_bytes: IndividualSignatureBytes,
104-
public_key_bytes: PublicKeyBytes,
106+
signature_bytes: &IndividualSignatureBytes,
107+
public_key_bytes: &PublicKeyBytes,
105108
) -> Result<(), CryptoError> {
106-
let signature = signature_bytes.try_into()?;
107-
let public_key = public_key_bytes.try_into()?;
109+
let signature = IndividualSignature::try_from(signature_bytes)?;
110+
let public_key = PublicKey::try_from(public_key_bytes)?;
108111
if crypto::verify_individual_message_signature(message, &signature, &public_key) {
109112
Ok(())
110113
} else {
@@ -130,13 +133,16 @@ pub fn verify_individual(
130133
/// fails.
131134
pub fn verify_combined(
132135
message: &[u8],
133-
signature: CombinedSignatureBytes,
136+
signature: &CombinedSignatureBytes,
134137
public_keys: &[PublicKeyBytes],
135138
) -> Result<(), CryptoError> {
136139
let public_keys: Result<Vec<PublicKey>, CryptoError> =
137-
public_keys.iter().cloned().map(|x| x.try_into()).collect();
138-
if crypto::verify_combined_message_signature(message, &signature.try_into()?, &public_keys?[..])
139-
{
140+
public_keys.iter().map(|x| PublicKey::try_from(x)).collect();
141+
if crypto::verify_combined_message_signature(
142+
message,
143+
&CombinedSignature::try_from(signature)?,
144+
&public_keys?[..],
145+
) {
140146
Ok(())
141147
} else {
142148
Err(CryptoError::SignatureVerification {

rs/crypto/internal/crypto_lib/multi_sig/bls12_381/src/api/tests.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,11 @@ fn test_happy_path(
3636
) {
3737
let pops: CryptoResult<Vec<PopBytes>> = keys
3838
.iter()
39-
.map(|(secret_key, public_key)| multi_sig::create_pop(*public_key, secret_key.clone()))
39+
.map(|(secret_key, public_key)| multi_sig::create_pop(public_key, secret_key))
4040
.collect();
4141
let signatures: Vec<IndividualSignatureBytes> = keys
4242
.iter()
43-
.map(|(secret_key, _)| multi_sig::sign(message, secret_key.clone()))
43+
.map(|(secret_key, _)| multi_sig::sign(message, secret_key))
4444
.collect();
4545
let pops = pops.expect("PoP generation failed");
4646
let signature = multi_sig::combine(&signatures);
@@ -53,20 +53,20 @@ fn test_happy_path(
5353
let pop_verification: CryptoResult<()> = public_keys
5454
.iter()
5555
.zip(pops)
56-
.try_for_each(|(public_key, pop)| multi_sig::verify_pop(pop, *public_key));
56+
.try_for_each(|(public_key, pop)| multi_sig::verify_pop(&pop, public_key));
5757
let individual_verification: CryptoResult<()> = public_keys
5858
.iter()
5959
.zip(signatures.clone())
6060
.try_for_each(|(public_key, signature)| {
61-
multi_sig::verify_individual(message, signature, *public_key)
61+
multi_sig::verify_individual(message, &signature, public_key)
6262
});
6363
assert!(pop_verification.is_ok(), "PoP verification failed");
6464
assert!(
6565
individual_verification.is_ok(),
6666
"Individual signature verification failed"
6767
);
6868
assert!(
69-
multi_sig::verify_combined(message, signature, &public_keys).is_ok(),
69+
multi_sig::verify_combined(message, &signature, &public_keys).is_ok(),
7070
"Signature verification failed"
7171
);
7272
(signatures, signature, public_keys)
@@ -94,9 +94,9 @@ proptest! {
9494
evil_signature in arbitrary::individual_signature_bytes()
9595
) {
9696
let (secret_key, public_key) = keys;
97-
let signature = multi_sig::sign(&message, secret_key);
97+
let signature = multi_sig::sign(&message, &secret_key);
9898
prop_assume!(evil_signature != signature);
99-
assert!(multi_sig::verify_individual(&message, evil_signature, public_key).is_err())
99+
assert!(multi_sig::verify_individual(&message, &evil_signature, &public_key).is_err())
100100
}
101101

102102
#[test]
@@ -105,9 +105,9 @@ proptest! {
105105
evil_pop in arbitrary::pop_bytes()
106106
) {
107107
let (secret_key, public_key) = keys;
108-
let pop = multi_sig::create_pop(public_key, secret_key).expect("Failed to create PoP");
108+
let pop = multi_sig::create_pop(&public_key, &secret_key).expect("Failed to create PoP");
109109
prop_assume!(evil_pop != pop);
110-
assert!(multi_sig::verify_pop(evil_pop, public_key).is_err())
110+
assert!(multi_sig::verify_pop(&evil_pop, &public_key).is_err())
111111
}
112112

113113
#[test]
@@ -118,6 +118,6 @@ proptest! {
118118
) {
119119
let (_signatures, signature, public_keys) = test_happy_path(&keys, &message);
120120
prop_assume!(evil_signature != signature);
121-
assert!(multi_sig::verify_combined(&message, evil_signature, &public_keys).is_err())
121+
assert!(multi_sig::verify_combined(&message, &evil_signature, &public_keys).is_err())
122122
}
123123
}

rs/crypto/internal/crypto_lib/multi_sig/bls12_381/src/crypto.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ pub fn sign_message(message: &[u8], secret_key: &SecretKey) -> IndividualSignatu
6868
}
6969

7070
pub fn create_pop(public_key: &PublicKey, secret_key: &SecretKey) -> Pop {
71-
let public_key_bytes = PublicKeyBytes::from(public_key.clone());
71+
let public_key_bytes = PublicKeyBytes::from(public_key);
7272
let mut domain_separated_public_key: Vec<u8> = vec![];
7373
domain_separated_public_key
7474
.extend(DomainSeparationContext::new(DOMAIN_MULTI_SIG_BLS12_381_POP).as_bytes());
@@ -98,7 +98,7 @@ pub fn verify_individual_message_signature(
9898
verify_point(&hash, signature, public_key)
9999
}
100100
pub fn verify_pop(pop: &Pop, public_key: &PublicKey) -> bool {
101-
let public_key_bytes = PublicKeyBytes::from(public_key.clone());
101+
let public_key_bytes = PublicKeyBytes::from(public_key);
102102
let mut domain_separated_public_key: Vec<u8> = vec![];
103103
domain_separated_public_key
104104
.extend(DomainSeparationContext::new(DOMAIN_MULTI_SIG_BLS12_381_POP).as_bytes());

rs/crypto/internal/crypto_lib/multi_sig/bls12_381/src/tests.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ mod stability {
6464
fn public_key_to_g1() {
6565
let mut csprng = ChaCha20Rng::seed_from_u64(42);
6666
let (_secret_key, public_key) = multi_crypto::keypair_from_rng(&mut csprng);
67-
let public_key_bytes = PublicKeyBytes::from(public_key);
67+
let public_key_bytes = PublicKeyBytes::from(&public_key);
6868
assert_eq!(
6969
hex::encode(multi_crypto::hash_public_key_to_g1(&public_key_bytes.0[..]).serialize()),
7070
"b02fd0d54faab7498924d7e230f84b00519ea7f3846cd30f82b149c1f172ad79ee68adb2ea2fc8a2d40ffdf3fd5df02a"
@@ -75,14 +75,14 @@ mod stability {
7575
fn secret_key_from_fixed_rng() {
7676
let mut csprng = ChaCha20Rng::seed_from_u64(9000);
7777
let (secret_key, public_key) = multi_crypto::keypair_from_rng(&mut csprng);
78-
let secret_key_bytes = SecretKeyBytes::from(secret_key);
78+
let secret_key_bytes = SecretKeyBytes::from(&secret_key);
7979

8080
assert_eq!(
8181
hex::encode(serde_cbor::to_vec(&secret_key_bytes).unwrap()),
8282
"582020bfd7f85be7ce1f54ea1b0d750ae3324ab7897fde3235e189ec697f0fade983"
8383
);
8484

85-
let public_key_bytes = PublicKeyBytes::from(public_key);
85+
let public_key_bytes = PublicKeyBytes::from(&public_key);
8686

8787
assert_eq!(
8888
hex::encode(serde_cbor::to_vec(&public_key_bytes).unwrap()),
@@ -144,7 +144,7 @@ mod basic_functionality {
144144
let points: HashSet<_> = (0..number_of_public_keys as u64)
145145
.map(|_| {
146146
let (_secret_key, public_key) = multi_crypto::keypair_from_rng(&mut csprng);
147-
let public_key_bytes = PublicKeyBytes::from(public_key);
147+
let public_key_bytes = PublicKeyBytes::from(&public_key);
148148
let g1 = multi_crypto::hash_public_key_to_g1(&public_key_bytes.0[..]);
149149
let bytes = g1.serialize();
150150
// It suffices to prove that the first 32 bytes are distinct. More requires a
@@ -195,10 +195,10 @@ mod advanced_functionality {
195195
fn verify_pop_throws_error_on_public_key_bytes_with_unset_compressed_flag() {
196196
let (secret_key, public_key) = multi_crypto::keypair_from_seed([1, 2, 3, 4]);
197197
let pop = multi_crypto::create_pop(&public_key, &secret_key);
198-
let pop_bytes = PopBytes::from(pop);
199-
let mut public_key_bytes = PublicKeyBytes::from(public_key);
198+
let pop_bytes = PopBytes::from(&pop);
199+
let mut public_key_bytes = PublicKeyBytes::from(&public_key);
200200
public_key_bytes.0[G2Bytes::FLAG_BYTE_OFFSET] &= !G2Bytes::COMPRESSED_FLAG;
201-
match api::verify_pop(pop_bytes, public_key_bytes) {
201+
match api::verify_pop(&pop_bytes, &public_key_bytes) {
202202
Err(e) => assert!(e.to_string().contains("Point decoding failed")),
203203
Ok(_) => panic!("error should have been thrown"),
204204
}
@@ -208,16 +208,16 @@ mod advanced_functionality {
208208
fn verify_pop_throws_error_on_public_key_bytes_not_on_curve() {
209209
let (secret_key, public_key) = multi_crypto::keypair_from_seed([1, 2, 3, 4]);
210210
let pop = multi_crypto::create_pop(&public_key, &secret_key);
211-
let pop_bytes = PopBytes::from(pop);
212-
let mut public_key_bytes = PublicKeyBytes::from(public_key);
211+
let pop_bytes = PopBytes::from(&pop);
212+
let mut public_key_bytes = PublicKeyBytes::from(&public_key);
213213
// Zero out the bytes, set the compression flag.
214214
// This represents x = 0, which happens to have no solution
215215
// on the G2 curve.
216216
for i in 0..G2Bytes::SIZE {
217217
public_key_bytes.0[i] = 0;
218218
}
219219
public_key_bytes.0[G2Bytes::FLAG_BYTE_OFFSET] |= G2Bytes::COMPRESSED_FLAG;
220-
match api::verify_pop(pop_bytes, public_key_bytes) {
220+
match api::verify_pop(&pop_bytes, &public_key_bytes) {
221221
Err(e) => assert!(e.to_string().contains("Point decoding failed")),
222222
Ok(_) => panic!("error should have been thrown"),
223223
}
@@ -227,16 +227,16 @@ mod advanced_functionality {
227227
fn verify_pop_throws_error_on_public_key_bytes_not_in_subgroup() {
228228
let (secret_key, public_key) = multi_crypto::keypair_from_seed([1, 2, 3, 4]);
229229
let pop = multi_crypto::create_pop(&public_key, &secret_key);
230-
let pop_bytes = PopBytes::from(pop);
231-
let mut public_key_bytes = PublicKeyBytes::from(public_key);
230+
let pop_bytes = PopBytes::from(&pop);
231+
let mut public_key_bytes = PublicKeyBytes::from(&public_key);
232232
// By manual rejection sampling, we found an x-coordinate with a
233233
// solution, which is unlikely to have order r.
234234
for i in 0..G2Bytes::SIZE {
235235
public_key_bytes.0[i] = 0;
236236
}
237237
public_key_bytes.0[G2Bytes::FLAG_BYTE_OFFSET] |= G2Bytes::COMPRESSED_FLAG;
238238
public_key_bytes.0[5] = 3;
239-
match api::verify_pop(pop_bytes, public_key_bytes) {
239+
match api::verify_pop(&pop_bytes, &public_key_bytes) {
240240
Err(e) => assert!(e.to_string().contains("Point decoding failed")),
241241
Ok(_) => panic!("error should have been thrown"),
242242
}

rs/crypto/internal/crypto_lib/multi_sig/bls12_381/src/types/arbitrary.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,22 +37,27 @@ pub fn combined_signature() -> impl Strategy<Value = CombinedSignature> {
3737
}
3838

3939
pub fn secret_key_bytes() -> impl Strategy<Value = SecretKeyBytes> {
40-
key_pair().prop_map(|(secret_key, _public_key)| secret_key.into())
40+
key_pair().prop_map(|(secret_key, _public_key)| SecretKeyBytes::from(&secret_key))
4141
}
4242
pub fn public_key_bytes() -> impl Strategy<Value = PublicKeyBytes> {
43-
public_key().prop_map(|public_key| public_key.into())
43+
public_key().prop_map(|public_key| PublicKeyBytes::from(&public_key))
4444
}
4545
pub fn key_pair_bytes() -> impl Strategy<Value = (SecretKeyBytes, PublicKeyBytes)> {
46-
key_pair().prop_map(|(secret_key, public_key)| (secret_key.into(), public_key.into()))
46+
key_pair().prop_map(|(secret_key, public_key)| {
47+
(
48+
SecretKeyBytes::from(&secret_key),
49+
PublicKeyBytes::from(&public_key),
50+
)
51+
})
4752
}
4853
pub fn individual_signature_bytes() -> impl Strategy<Value = IndividualSignatureBytes> {
49-
individual_signature().prop_map(|signature| signature.into())
54+
individual_signature().prop_map(|signature| IndividualSignatureBytes::from(&signature))
5055
}
5156
pub fn pop_bytes() -> impl Strategy<Value = PopBytes> {
52-
pop().prop_map(|pop| pop.into())
57+
pop().prop_map(|pop| PopBytes::from(&pop))
5358
}
5459
pub fn combined_signature_bytes() -> impl Strategy<Value = CombinedSignatureBytes> {
55-
combined_signature().prop_map(|signature| signature.into())
60+
combined_signature().prop_map(|signature| CombinedSignatureBytes::from(&signature))
5661
}
5762

5863
//////////////////

0 commit comments

Comments
 (0)