threshold_crypto.rs
1 use std::io::{Error, Read, Write}; 2 3 use threshold_crypto::group::Curve; 4 use threshold_crypto::{G1Affine, G1Projective}; 5 6 use crate::encoding::{Decodable, DecodeError, Encodable}; 7 use crate::module::registry::ModuleDecoderRegistry; 8 9 impl Encodable for threshold_crypto::PublicKeySet { 10 fn consensus_encode<W: Write>(&self, writer: &mut W) -> Result<usize, Error> { 11 let mut len = 0; 12 let num_coeff = self.coefficients().len() as u64; 13 len += num_coeff.consensus_encode(writer)?; 14 for coefficient in self.coefficients() { 15 len += coefficient 16 .to_affine() 17 .to_compressed() 18 .consensus_encode(writer)?; 19 } 20 Ok(len) 21 } 22 } 23 24 impl Decodable for threshold_crypto::PublicKeySet { 25 fn consensus_decode<R: Read>( 26 r: &mut R, 27 modules: &ModuleDecoderRegistry, 28 ) -> Result<Self, DecodeError> { 29 let num_coeff = u64::consensus_decode(r, modules)?; 30 (0..num_coeff) 31 .map(|_| { 32 let bytes: [u8; 48] = Decodable::consensus_decode(r, modules)?; 33 let point = G1Affine::from_compressed(&bytes); 34 if point.is_some().unwrap_u8() == 1 { 35 let affine = point.unwrap(); 36 Ok(G1Projective::from(affine)) 37 } else { 38 Err(crate::encoding::DecodeError::from_str( 39 "Error decoding public key", 40 )) 41 } 42 }) 43 .collect::<Result<Vec<_>, _>>() 44 .map(|coefficients| { 45 threshold_crypto::PublicKeySet::from(threshold_crypto::poly::Commitment::from( 46 coefficients, 47 )) 48 }) 49 } 50 } 51 52 impl Encodable for threshold_crypto::PublicKey { 53 fn consensus_encode<W: Write>(&self, writer: &mut W) -> Result<usize, Error> { 54 self.to_bytes().consensus_encode(writer) 55 } 56 } 57 58 impl Decodable for threshold_crypto::PublicKey { 59 fn consensus_decode<R: Read>( 60 r: &mut R, 61 modules: &ModuleDecoderRegistry, 62 ) -> Result<Self, DecodeError> { 63 let bytes: [u8; 48] = Decodable::consensus_decode(r, modules)?; 64 threshold_crypto::PublicKey::from_bytes(bytes).map_err(DecodeError::from_err) 65 } 66 } 67 68 impl Encodable for threshold_crypto::Ciphertext { 69 fn consensus_encode<W: Write>(&self, writer: &mut W) -> Result<usize, Error> { 70 self.to_bytes().consensus_encode(writer) 71 } 72 } 73 74 impl Decodable for threshold_crypto::Ciphertext { 75 fn consensus_decode<R: Read>( 76 reader: &mut R, 77 modules: &ModuleDecoderRegistry, 78 ) -> Result<Self, DecodeError> { 79 let ciphertext_bytes = Vec::<u8>::consensus_decode(reader, modules)?; 80 threshold_crypto::Ciphertext::from_bytes(&ciphertext_bytes).ok_or_else(|| { 81 DecodeError::from_str("Error decoding threshold_crypto::Ciphertext from bytes") 82 }) 83 } 84 } 85 86 impl Encodable for threshold_crypto::DecryptionShare { 87 fn consensus_encode<W: Write>(&self, writer: &mut W) -> Result<usize, Error> { 88 self.to_bytes().consensus_encode(writer) 89 } 90 } 91 92 impl Decodable for threshold_crypto::DecryptionShare { 93 fn consensus_decode<R: Read>( 94 reader: &mut R, 95 modules: &ModuleDecoderRegistry, 96 ) -> Result<Self, DecodeError> { 97 let decryption_share_bytes = <[u8; 48]>::consensus_decode(reader, modules)?; 98 threshold_crypto::DecryptionShare::from_bytes(&decryption_share_bytes).ok_or_else(|| { 99 DecodeError::from_str("Error decoding threshold_crypto::DecryptionShare from bytes") 100 }) 101 } 102 } 103 104 #[cfg(test)] 105 mod tests { 106 use super::super::tests::test_roundtrip; 107 108 #[test_log::test] 109 fn test_ciphertext() { 110 let sks = threshold_crypto::SecretKeySet::random(1, &mut rand::thread_rng()); 111 let pks = sks.public_keys(); 112 let pk = pks.public_key(); 113 114 let message = b"Hello world!"; 115 let ciphertext = pk.encrypt(message); 116 let decryption_share = sks.secret_key_share(0).decrypt_share(&ciphertext).unwrap(); 117 118 test_roundtrip(ciphertext); 119 test_roundtrip(decryption_share); 120 } 121 }