1414 * limitations under the License.
1515 */
1616
17- use super :: utils:: { cross_product_32 , h2, h3, h4} ;
17+ use super :: utils:: { cross_product_const , h2, h3, h4} ;
1818use alloc:: vec;
1919use ark_ec:: PrimeGroup ;
2020use ark_serialize:: { CanonicalDeserialize , CanonicalSerialize } ;
2121use ark_std:: { ops:: Mul , rand:: Rng , vec:: Vec } ;
2222use serde:: { Deserialize , Serialize } ;
2323
24- use crate :: Message ;
25-
2624use crate :: engines:: EngineBLS ;
25+ use crate :: { Hash , HASH_LENGTH , Message } ;
26+
27+ /// Represents a serialized field element of a scalar field
28+ pub type SerializedFieldElement = [ u8 ; 32 ] ;
2729
2830/// Represents a ciphertext in the BF-IBE FullIdent scheme
2931#[ derive(
3032 Debug , Clone , PartialEq , CanonicalDeserialize , CanonicalSerialize , Serialize , Deserialize ,
3133) ]
34+ #[ repr( C ) ] // since we know the exact size at compile time
3235pub struct Ciphertext < E : EngineBLS > {
3336 /// U = rP
3437 pub u : E :: PublicKeyGroup ,
3538 /// V = sigma (+) H_2(g_id^r)
36- pub v : Vec < u8 > ,
39+ pub v : Hash ,
3740 /// W = message (+) H_4(sigma)
38- pub w : Vec < u8 > ,
41+ pub w : Hash ,
3942}
4043
4144#[ derive( Debug , Clone , PartialEq ) ]
@@ -55,17 +58,10 @@ pub struct Input<E: EngineBLS> {
5558}
5659
5760impl < E : EngineBLS > Input < E > {
58- pub fn new ( data : Vec < u8 > ) -> Result < Self , InputError > {
59- if data. len ( ) != E :: SECRET_KEY_SIZE {
60- return Err ( InputError :: InvalidLength ) ;
61- }
61+ pub fn new ( data : SerializedFieldElement ) -> Result < Self , InputError > {
6262 Ok ( Self { data, _phantom : ark_std:: marker:: PhantomData } )
6363 }
6464
65- pub fn from_array ( data : [ u8 ; 32 ] ) -> Result < Self , InputError > {
66- Self :: new ( data. to_vec ( ) )
67- }
68-
6965 pub fn as_bytes ( & self ) -> & [ u8 ] {
7066 & self . data
7167 }
@@ -77,10 +73,8 @@ pub struct Identity(pub Message);
7773
7874impl Identity {
7975 /// construct a new identity from a string
80- pub fn new ( ctx : & [ u8 ] , bytes : Vec < u8 > ) -> Self {
81- Self (
82- Message :: new ( ctx, & bytes)
83- )
76+ pub fn new ( ctx : & [ u8 ] , identity : & [ u8 ] ) -> Self {
77+ Self ( Message :: new ( ctx, & identity) )
8478 }
8579
8680 /// The IBE extract function on a given secret key
@@ -113,7 +107,7 @@ impl Identity {
113107 {
114108 let bytes = message. as_bytes ( ) ;
115109 // sigma <- {0, 1}^d
116- let mut sigma = vec ! [ 0u8 ; E :: SECRET_KEY_SIZE ] ;
110+ let mut sigma = vec ! [ 0u8 ; E :: SECRET_KEY_SIZE ] ;
117111 rng. fill_bytes ( & mut sigma) ;
118112 // r= H3(sigma, message)
119113 let r: E :: Scalar = h3 :: < E > ( & sigma, bytes) ;
@@ -124,12 +118,12 @@ impl Identity {
124118 let g_id = E :: pairing ( p_pub. mul ( r) , self . public :: < E > ( ) ) ;
125119 // sigma (+) H2(e(P_pub, Q_id))
126120 let v_rhs = h2 ( g_id) ;
127- let v_out = cross_product_32 ( & sigma, & v_rhs) ;
121+ let v = cross_product_const :: < HASH_LENGTH > ( & sigma, & v_rhs) ;
128122 // message (+) H4(sigma)
129123 let w_rhs = h4 ( & sigma) ;
130- let w_out = cross_product_32 ( bytes, & w_rhs) ;
124+ let w = cross_product_const :: < HASH_LENGTH > ( bytes, & w_rhs) ;
131125 // (rP, sigma (+) H2(e(Q_id, P_pub)), message (+) H4(sigma))
132- Ciphertext :: < E > { u, v : v_out . to_vec ( ) , w : w_out . to_vec ( ) }
126+ Ciphertext :: < E > { u, v, w }
133127 }
134128}
135129
@@ -138,23 +132,21 @@ impl Identity {
138132pub struct IBESecret < E : EngineBLS > ( pub E :: SignatureGroup ) ;
139133
140134impl < E : EngineBLS > IBESecret < E > {
141- /// BF-IBE decryption of a
142- /// * `ciphertext`: C = <U, V, W>
135+ /// BF-IBE decryption of a
136+ /// * `ciphertext`: C = <U, V, W>
143137 ///
144138 /// Attempts to decrypt under the given IBESecret (in G1)
145- pub fn decrypt ( & self , ciphertext : & Ciphertext < E > ) -> Result < Vec < u8 > , IbeError > {
139+ pub fn decrypt ( & self , ciphertext : & Ciphertext < E > ) -> Result < Hash , IbeError > {
146140 // sigma = V (+) H2(e(d_id, U))
147141 let sigma_rhs = h2 ( E :: pairing ( ciphertext. u , self . 0 ) ) ;
148- let sigma = cross_product_32 ( & ciphertext. v , & sigma_rhs) ;
142+ let sigma = cross_product_const :: < HASH_LENGTH > ( & ciphertext. v , & sigma_rhs) ;
149143 // m = W (+) H4(sigma)
150144 let m_rhs = h4 ( & sigma) ;
151- let m = cross_product_32 ( & ciphertext. w , & m_rhs) ;
145+ let m = cross_product_const :: < HASH_LENGTH > ( & ciphertext. w , & m_rhs) ;
152146 // check: U == rP
153147 let p = E :: PublicKeyGroup :: generator ( ) ;
154148 let r = h3 :: < E > ( & sigma, & m) ;
155149 let u_check = p * r;
156-
157- // TODO: timing attack? should do a constant-time check
158150 if !u_check. eq ( & ciphertext. u ) {
159151 return Err ( IbeError :: DecryptionFailed ) ;
160152 }
@@ -172,7 +164,7 @@ mod test {
172164
173165 // this enum represents the conditions or branches that I want to test
174166 enum TestStatusReport {
175- DecryptionResult { data : Vec < u8 > , verify : Vec < u8 > } ,
167+ DecryptionResult { data : [ u8 ; 32 ] , verify : Vec < u8 > } ,
176168 DecryptionFailure { error : IbeError } ,
177169 }
178170
@@ -198,10 +190,10 @@ mod test {
198190
199191 let p_pub = <<EB as EngineBLS >:: PublicKeyGroup as PrimeGroup >:: generator ( ) * msk;
200192
201- let mut ct = Ciphertext { u : EB :: PublicKeyGroup :: generator ( ) , v : vec ! [ ] , w : vec ! [ ] } ;
193+ let mut ct = Ciphertext { u : EB :: PublicKeyGroup :: generator ( ) , v : [ 0u8 ; 32 ] , w : [ 0u8 ; 32 ] } ;
202194
203195 if !insert_bad_ciphertext {
204- ct = identity. encrypt ( & Input :: from_array ( message) . unwrap ( ) , p_pub, & mut test_rng ( ) ) ;
196+ ct = identity. encrypt ( & Input :: new ( message) . unwrap ( ) , p_pub, & mut test_rng ( ) ) ;
205197 }
206198
207199 match sk. decrypt ( & ct) {
@@ -226,22 +218,21 @@ mod test {
226218
227219 #[ test]
228220 pub fn fullident_identity_construction_works ( ) {
229- let id_string = b"example@test.com" ;
230- let identity = Identity :: new ( b"" , id_string . to_vec ( ) ) ;
231- let expected_message = Message :: new ( b"" , id_string ) ;
221+
222+ let identity = Identity :: new ( b"" , & [ 1 , 2 , 3 ] ) ;
223+ let expected_message = Message :: new ( b"" , & [ 1 , 2 , 3 ] ) ;
232224 assert_eq ! ( identity. 0 , expected_message) ;
233225 }
234226
235227 #[ test]
236228 pub fn fullident_encrypt_and_decrypt ( ) {
237- let id_string = b"example@test.com" ;
238- let identity = Identity :: new ( b"" , id_string. to_vec ( ) ) ;
229+ let identity = Identity :: new ( b"" , & [ 1 , 2 , 3 ] ) ;
239230 let message: [ u8 ; 32 ] = [ 2 ; 32 ] ;
240231
241232 run_test :: < TinyBLS381 > ( identity, message, false , false , & |status : TestStatusReport | {
242233 match status {
243234 TestStatusReport :: DecryptionResult { data, verify } => {
244- assert_eq ! ( data, verify) ;
235+ assert_eq ! ( data. to_vec ( ) , verify) ;
245236 } ,
246237 _ => panic ! ( "Decryption should work" ) ,
247238 }
@@ -250,8 +241,7 @@ mod test {
250241
251242 #[ test]
252243 pub fn fullident_decryption_fails_with_bad_ciphertext ( ) {
253- let id_string = b"example@test.com" ;
254- let identity = Identity :: new ( b"" , id_string. to_vec ( ) ) ;
244+ let identity = Identity :: new ( b"" , & [ 1 , 2 , 3 ] ) ;
255245 let message: [ u8 ; 32 ] = [ 2 ; 32 ] ;
256246
257247 run_test :: < TinyBLS381 > ( identity, message, false , true , & |status : TestStatusReport | {
@@ -266,8 +256,7 @@ mod test {
266256
267257 #[ test]
268258 pub fn fullident_decryption_fails_with_bad_key ( ) {
269- let id_string = b"example@test.com" ;
270- let identity = Identity :: new ( b"" , id_string. to_vec ( ) ) ;
259+ let identity = Identity :: new ( b"" , & [ 1 , 2 , 3 ] ) ;
271260 let message: [ u8 ; 32 ] = [ 2 ; 32 ] ;
272261
273262 run_test :: < TinyBLS381 > ( identity, message, true , false , & |status : TestStatusReport | {
0 commit comments