@@ -169,30 +169,30 @@ fn benchmark_attributes(
169169
170170fn print_summary_table ( results : & [ BenchmarkResult ] ) {
171171 println ! ( "\n " ) ;
172- println ! ( "╔═════════════════════════════════════════════════════════════════════════════════════════════════╗" ) ;
173- println ! ( "║ BENCHMARK SUMMARY TABLE ║" ) ;
174- println ! ( "╠═══════════════════╦═════════════╦═════════════╦═════════════╦═════════════╦═════════════╦ ═══════╣" ) ;
172+ println ! ( "╔═══════════════════════════════════════════════════════════════════════════════════════════════════ ╗" ) ;
173+ println ! ( "║ BENCHMARK SUMMARY TABLE ║" ) ;
174+ println ! ( "╠═══════════════════╦═════════════╦═════════════╦═════════════╦═════════════╦═══════╦ ════════ ═══════╣" ) ;
175175 println ! (
176- "║ {:^17} ║ {:>11} ║ {:>11} ║ {:>11} ║ {:>11} ║ {:>11 } ║ {:^5 } ║" ,
177- "Test Case" , "Orig Mean" , "Orig p95" , "Opt Mean" , "Opt p95" , "Speedup " , "Unit "
176+ "║ {:^17} ║ {:>11} ║ {:>11} ║ {:>11} ║ {:>11} ║ {:^5 } ║ {:^13 } ║" ,
177+ "Test Case" , "Orig Mean" , "Orig p95" , "Opt Mean" , "Opt p95" , "Unit " , "Speedup "
178178 ) ;
179- println ! ( "╠═══════════════════╬═════════════╬═════════════╬═════════════╬═════════════╬═════════════╬ ═══════╣" ) ;
179+ println ! ( "╠═══════════════════╬═════════════╬═════════════╬═════════════╬═════════════╬═══════╬ ════════ ═══════╣" ) ;
180180
181181 // Each row is a test case
182182 for result in results {
183183 println ! (
184- "║ {:17} ║ {:11.2} ║ {:11.2} ║ {:11.2} ║ {:11.2} ║ {:11.2 } ║ {:>5 } ║" ,
184+ "║ {:17} ║ {:11.2} ║ {:11.2} ║ {:11.2} ║ {:11.2} ║ {:>5 } ║ {:>13 } ║" ,
185185 result. label,
186186 result. stats_old. mean / 1000.0 ,
187187 result. stats_old. p95 / 1000.0 ,
188188 result. stats_optimized. mean / 1000.0 ,
189189 result. stats_optimized. p95 / 1000.0 ,
190- result . speedup_mean ( ) ,
191- "µs/x"
190+ "µs" ,
191+ format! ( "x {:.2}" , result . speedup_mean ( ) )
192192 ) ;
193193 }
194194
195- println ! ( "╚═══════════════════╩═════════════╩═════════════╩═════════════╩═════════════╩═════════════╩ ═══════╝" ) ;
195+ println ! ( "╚═══════════════════╩═════════════╩═════════════╩═════════════╩═════════════╩═══════╩ ════════ ═══════╝" ) ;
196196}
197197
198198fn main ( ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
@@ -206,8 +206,11 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
206206 . unwrap_or_else ( |_| "/usr/lib/softhsm/libsofthsm2.so" . to_string ( ) ) ,
207207 ) ?;
208208
209+ let pin = env:: var ( "TEST_PKCS11_PIN" ) . unwrap_or_else ( |_| "fedcba123456" . to_string ( ) ) ;
209210 pkcs11. initialize ( CInitializeArgs :: OsThreads ) ?;
210211
212+ let nogenerate = env:: var ( "TEST_PKCS11_NO_KEYGEN" ) . is_ok ( ) ;
213+
211214 let slot = pkcs11
212215 . get_slots_with_token ( ) ?
213216 . into_iter ( )
@@ -216,44 +219,64 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
216219
217220 let session = pkcs11. open_rw_session ( slot) ?;
218221
219- session. login ( UserType :: User , Some ( & AuthPin :: new ( "fedcba123456" . into ( ) ) ) ) ?;
220-
221- // Generate a test RSA key pair
222- let mechanism = Mechanism :: RsaPkcsKeyPairGen ;
223- let public_exponent: Vec < u8 > = vec ! [ 0x01 , 0x00 , 0x01 ] ;
224- let modulus_bits = 2048 ;
225-
226- let pub_key_template = vec ! [
227- Attribute :: Token ( false ) , // Don't persist
228- Attribute :: Private ( false ) ,
229- Attribute :: PublicExponent ( public_exponent) ,
230- Attribute :: ModulusBits ( modulus_bits. into( ) ) ,
231- Attribute :: Verify ( true ) ,
232- Attribute :: Label ( "Benchmark Key" . into( ) ) ,
233- Attribute :: Id ( vec![ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ] ) ,
234- ] ;
235-
236- let priv_key_template = vec ! [ Attribute :: Token ( false ) , Attribute :: Sign ( true ) ] ;
237-
238- println ! ( "Generating RSA key pair for benchmarking..." ) ;
239- let ( public, _private) =
240- session. generate_key_pair ( & mechanism, & pub_key_template, & priv_key_template) ?;
222+ session. login ( UserType :: User , Some ( & AuthPin :: new ( pin. into ( ) ) ) ) ?;
223+
224+ let public;
225+ let _private;
226+
227+ if nogenerate {
228+ // search for an elliptic curve public key.
229+ // if more than one, take the first that comes.
230+ println ! ( "Using existing EC public key for benchmarking..." ) ;
231+ let template = vec ! [
232+ Attribute :: Class ( cryptoki:: object:: ObjectClass :: PUBLIC_KEY ) ,
233+ Attribute :: KeyType ( cryptoki:: object:: KeyType :: EC ) ,
234+ ] ;
235+ let objects = session. find_objects ( & template) ?;
236+ if objects. is_empty ( ) {
237+ return Err (
238+ "No EC public key found on the token. Cannot proceed with benchmarks." . into ( ) ,
239+ ) ;
240+ }
241+ public = objects[ 0 ] ;
242+ } else {
243+ // Generate a test EC key pair (P-256 curve)
244+ let mechanism = Mechanism :: EccKeyPairGen ;
245+
246+ // ANSI X9.62 prime256v1 (P-256) curve OID: 1.2.840.10045.3.1.7
247+ let ec_params = vec ! [ 0x06 , 0x08 , 0x2a , 0x86 , 0x48 , 0xce , 0x3d , 0x03 , 0x01 , 0x07 ] ;
248+
249+ let pub_key_template = vec ! [
250+ Attribute :: Token ( false ) , // Don't persist
251+ Attribute :: Private ( false ) ,
252+ Attribute :: EcParams ( ec_params) ,
253+ Attribute :: Verify ( true ) ,
254+ Attribute :: Label ( "Benchmark EC Key" . into( ) ) ,
255+ Attribute :: Id ( vec![ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ] ) ,
256+ ] ;
257+
258+ let priv_key_template = vec ! [ Attribute :: Token ( false ) , Attribute :: Sign ( true ) ] ;
259+
260+ println ! ( "Generating EC key pair for benchmarking..." ) ;
261+ ( public, _private) =
262+ session. generate_key_pair ( & mechanism, & pub_key_template, & priv_key_template) ?;
263+ }
241264
242265 let mut results = Vec :: new ( ) ;
243266
244267 // Test 1: Multiple attributes (mix of fixed and variable length)
245268 let multiple_attributes = vec ! [
246- AttributeType :: Class , // CK_ULONG (fixed, 8 bytes)
247- AttributeType :: Label , // Variable length
248- AttributeType :: Id , // Variable length
249- AttributeType :: KeyType , // CK_ULONG (fixed, 8 bytes)
250- AttributeType :: Token , // CK_BBOOL as CK_ULONG (fixed, 8 bytes)
251- AttributeType :: Private , // CK_BBOOL as CK_ULONG (fixed, 8 bytes)
252- AttributeType :: Modulus , // Large variable (256 bytes for 2048-bit key )
253- AttributeType :: PublicExponent , // Variable, typically 3 bytes
254- AttributeType :: Verify , // CK_BBOOL as CK_ULONG (fixed, 8 bytes)
255- AttributeType :: Encrypt , // CK_BBOOL as CK_ULONG (fixed, 8 bytes)
256- AttributeType :: ModulusBits , // CK_ULONG (fixed, 8 bytes)
269+ AttributeType :: Class , // CK_ULONG (fixed, 8 bytes)
270+ AttributeType :: Label , // Variable length
271+ AttributeType :: Id , // Variable length
272+ AttributeType :: KeyType , // CK_ULONG (fixed, 8 bytes)
273+ AttributeType :: Token , // CK_BBOOL as CK_ULONG (fixed, 8 bytes)
274+ AttributeType :: Private , // CK_BBOOL as CK_ULONG (fixed, 8 bytes)
275+ AttributeType :: EcPoint , // Variable length (~65 bytes for P-256 uncompressed )
276+ AttributeType :: EcParams , // Variable length (10 bytes for P-256 OID)
277+ AttributeType :: Verify , // CK_BBOOL as CK_ULONG (fixed, 8 bytes)
278+ AttributeType :: Encrypt , // CK_BBOOL as CK_ULONG (fixed, 8 bytes)
279+ AttributeType :: Local , // CK_BBOOL as CK_ULONG (fixed, 8 bytes)
257280 ] ;
258281
259282 results. push ( benchmark_attributes (
@@ -275,19 +298,19 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
275298 "Single-fixed" ,
276299 ) ?) ;
277300
278- // Test 3: Single variable-length attribute (large )
279- let single_variable_large = vec ! [ AttributeType :: Modulus ] ;
301+ // Test 3: Single variable-length attribute (EC point, ~65 bytes for P-256 )
302+ let single_variable = vec ! [ AttributeType :: EcPoint ] ;
280303
281304 results. push ( benchmark_attributes (
282305 & session,
283306 public,
284- & single_variable_large ,
307+ & single_variable ,
285308 iterations,
286309 "Single-variable" ,
287310 ) ?) ;
288311
289- // Test 4: Single attribute that doesn't exist (EC point for RSA key)
290- let single_nonexistent = vec ! [ AttributeType :: EcPoint ] ;
312+ // Test 4: Single attribute that doesn't exist (Modulus for EC key)
313+ let single_nonexistent = vec ! [ AttributeType :: Modulus ] ;
291314
292315 results. push ( benchmark_attributes (
293316 & session,
@@ -301,7 +324,9 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
301324 print_summary_table ( & results) ;
302325
303326 // Clean up
304- session. destroy_object ( public) ?;
327+ if !nogenerate {
328+ session. destroy_object ( public) ?;
329+ }
305330
306331 Ok ( ( ) )
307332}
0 commit comments