@@ -8,6 +8,7 @@ use crate::{
88 error:: PepperServiceError ,
99 external_resources:: { jwk_fetcher, jwk_fetcher:: JWKCache , resource_fetcher:: CachedResources } ,
1010 metrics,
11+ vuf_keypair:: VUFKeypair ,
1112} ;
1213use aptos_keyless_pepper_common:: {
1314 jwt:: Claims ,
@@ -28,7 +29,6 @@ use aptos_types::{
2829} ;
2930use jsonwebtoken:: { Algorithm :: RS256 , DecodingKey , TokenData , Validation } ;
3031use std:: {
31- ops:: Deref ,
3232 sync:: Arc ,
3333 time:: { Instant , SystemTime , UNIX_EPOCH } ,
3434} ;
@@ -47,7 +47,7 @@ const EMAIL_UID_KEY: &str = "email";
4747
4848/// Handles the given pepper request, returning the pepper base, pepper and account address
4949pub async fn handle_pepper_request (
50- vuf_private_key : Arc < ark_bls12_381 :: Fr > ,
50+ vuf_keypair : Arc < VUFKeypair > ,
5151 jwk_cache : JWKCache ,
5252 cached_resources : CachedResources ,
5353 jwt : String ,
@@ -104,7 +104,7 @@ pub async fn handle_pepper_request(
104104
105105 // Derive the pepper and account address
106106 let derivation_result =
107- derive_pepper_and_account_address ( vuf_private_key , derivation_path, & pepper_input) ;
107+ derive_pepper_and_account_address ( vuf_keypair , derivation_path, & pepper_input) ;
108108
109109 // Update the derivation metrics
110110 metrics:: update_pepper_derivation_metrics ( derivation_result. is_ok ( ) , derivation_start_time) ;
@@ -142,7 +142,7 @@ fn create_account_address(
142142
143143/// Creates the pepper base using the VUF private key and the pepper input
144144fn create_pepper_base (
145- vuf_private_key : Arc < ark_bls12_381 :: Fr > ,
145+ vuf_keypair : Arc < VUFKeypair > ,
146146 pepper_input : & PepperInput ,
147147) -> Result < Vec < u8 > , PepperServiceError > {
148148 // Serialize the pepper input using BCS
@@ -155,14 +155,13 @@ fn create_pepper_base(
155155
156156 // Generate the pepper base and proof using the VUF
157157 let ( pepper_base, vuf_proof) =
158- vuf:: bls12381_g1_bls:: Bls12381G1Bls :: eval ( vuf_private_key . deref ( ) , & input_bytes) . map_err (
159- |error| {
158+ vuf:: bls12381_g1_bls:: Bls12381G1Bls :: eval ( vuf_keypair . vuf_private_key ( ) , & input_bytes)
159+ . map_err ( |error| {
160160 PepperServiceError :: InternalError ( format ! (
161161 "Failed to evaluate bls12381_g1_bls VUF: {}" ,
162162 error
163163 ) )
164- } ,
165- ) ?;
164+ } ) ?;
166165
167166 // Verify that the proof is empty
168167 if !vuf_proof. is_empty ( ) {
@@ -171,6 +170,18 @@ fn create_pepper_base(
171170 ) ) ;
172171 }
173172
173+ // Verify the pepper base output (this ensures we only ever return valid outputs,
174+ // and protects against various security issues, e.g., fault based side channels).
175+ vuf:: bls12381_g1_bls:: Bls12381G1Bls :: verify (
176+ vuf_keypair. vuf_public_key ( ) ,
177+ & input_bytes,
178+ & pepper_base,
179+ & vuf_proof,
180+ )
181+ . map_err ( |error| {
182+ PepperServiceError :: InternalError ( format ! ( "VUF verification failed: {}" , error) )
183+ } ) ?;
184+
174185 Ok ( pepper_base)
175186}
176187
@@ -244,12 +255,12 @@ fn derive_pepper(
244255
245256/// Derives the pepper base, pepper bytes and account address
246257fn derive_pepper_and_account_address (
247- vuf_private_key : Arc < ark_bls12_381 :: Fr > ,
258+ vuf_keypair : Arc < VUFKeypair > ,
248259 derivation_path : Option < String > ,
249260 pepper_input : & PepperInput ,
250261) -> Result < ( Vec < u8 > , Vec < u8 > , AccountAddress ) , PepperServiceError > {
251262 // Create the pepper base using the vuf private key and the pepper input
252- let pepper_base = create_pepper_base ( vuf_private_key , pepper_input) ?;
263+ let pepper_base = create_pepper_base ( vuf_keypair , pepper_input) ?;
253264
254265 // Derive the pepper using the verified derivation path and the pepper base
255266 let verified_derivation_path = get_verified_derivation_path ( derivation_path) ?;
@@ -452,8 +463,6 @@ fn verify_public_key_expiry_date_secs(
452463mod tests {
453464 use super :: * ;
454465 use crate :: { accounts:: account_managers:: AccountRecoveryManager , tests:: utils} ;
455- use aptos_keyless_pepper_common:: vuf:: slip_10:: ed25519_dalek:: Digest ;
456- use ark_ff:: PrimeField ;
457466
458467 // Test token data constants
459468 const TEST_TOKEN_ISSUER : & str = "token_issuer" ;
@@ -492,6 +501,45 @@ mod tests {
492501 "21a8d5768336a41a5872351c806d56cca994b0acbe7f054afeed22bee06ef2" ;
493502 const TEST_SUB_OVERRIDE_PEPPER_BASE_HEX : & str = "b14111748bc9bde79f0a7edea91b06432800107c448dbe9cc89b47a49ec5094e2fe8976790f6574c7eb9abdc7c5b1df5" ;
494503
504+ #[ test]
505+ fn test_create_pepper_base ( ) {
506+ // Create a test pepper input
507+ let pepper_input = PepperInput {
508+ iss : TEST_TOKEN_ISSUER . into ( ) ,
509+ uid_key : SUB_UID_KEY . into ( ) ,
510+ uid_val : TEST_TOKEN_SUB . into ( ) ,
511+ aud : TEST_TOKEN_AUD . into ( ) ,
512+ } ;
513+
514+ // Create a test VUF keypair
515+ let vuf_keypair = utils:: create_vuf_keypair ( Some ( TEST_SUB_VUF_PRIVATE_KEY_SEED ) ) ;
516+
517+ // Create the pepper base
518+ let pepper_base = create_pepper_base ( vuf_keypair. clone ( ) , & pepper_input) . unwrap ( ) ;
519+
520+ // Verify the pepper base matches the expected value
521+ assert_eq ! (
522+ hex:: encode( pepper_base) ,
523+ TEST_SUB_PEPPER_BASE_HEX . to_string( )
524+ ) ;
525+
526+ // Create an invalid keypair where the public and private keys do not match
527+ let invalid_private_key = * utils:: create_vuf_keypair ( None ) . vuf_private_key ( ) ;
528+ let invalid_vuf_keypair = VUFKeypair :: new (
529+ invalid_private_key,
530+ * vuf_keypair. vuf_public_key ( ) ,
531+ vuf_keypair. vuf_public_key_json ( ) . clone ( ) ,
532+ ) ;
533+
534+ // Create the pepper base using the invalid keypair. This should fail with
535+ // a verification error, because the public and private keys don't match.
536+ let pepper_service_error =
537+ create_pepper_base ( Arc :: new ( invalid_vuf_keypair) , & pepper_input) . unwrap_err ( ) ;
538+ assert ! ( pepper_service_error
539+ . to_string( )
540+ . contains( "VUF verification failed" ) ) ;
541+ }
542+
495543 #[ test]
496544 fn test_get_uid_key_and_value ( ) {
497545 // Create test token data
@@ -547,12 +595,12 @@ mod tests {
547595 . await
548596 . unwrap ( ) ;
549597
550- // Get the VUF private key
551- let vuf_private_key = get_test_vuf_private_key ( TEST_SUB_VUF_PRIVATE_KEY_SEED ) ;
598+ // Get the VUF keypair
599+ let vuf_keypair = utils :: create_vuf_keypair ( Some ( TEST_SUB_VUF_PRIVATE_KEY_SEED ) ) ;
552600
553601 // Verify the pepper base, derived pepper and account address
554602 verify_base_pepper_and_address_generation (
555- vuf_private_key ,
603+ vuf_keypair ,
556604 & pepper_input,
557605 TEST_SUB_PEPPER_BASE_HEX ,
558606 TEST_SUB_DERIVED_PEPPER_HEX ,
@@ -583,12 +631,12 @@ mod tests {
583631 . await
584632 . unwrap ( ) ;
585633
586- // Get the VUF private key
587- let vuf_private_key = get_test_vuf_private_key ( TEST_EMAIL_VUF_PRIVATE_KEY_SEED ) ;
634+ // Get the VUF keypair
635+ let vuf_keypair = utils :: create_vuf_keypair ( Some ( TEST_EMAIL_VUF_PRIVATE_KEY_SEED ) ) ;
588636
589637 // Verify the pepper base, derived pepper and account address
590638 verify_base_pepper_and_address_generation (
591- vuf_private_key ,
639+ vuf_keypair ,
592640 & pepper_input,
593641 TEST_EMAIL_PEPPER_BASE_HEX ,
594642 TEST_EMAIL_DERIVED_PEPPER_HEX ,
@@ -618,12 +666,12 @@ mod tests {
618666 . await
619667 . unwrap ( ) ;
620668
621- // Get the VUF private key
622- let vuf_private_key = get_test_vuf_private_key ( TEST_SUB_VUF_PRIVATE_KEY_SEED ) ;
669+ // Get the VUF keypair
670+ let vuf_keypair = utils :: create_vuf_keypair ( Some ( TEST_SUB_VUF_PRIVATE_KEY_SEED ) ) ;
623671
624672 // Verify the pepper base, derived pepper and account address
625673 verify_base_pepper_and_address_generation (
626- vuf_private_key ,
674+ vuf_keypair ,
627675 & pepper_input,
628676 TEST_SUB_PEPPER_BASE_HEX ,
629677 TEST_SUB_DERIVED_PEPPER_HEX ,
@@ -658,12 +706,12 @@ mod tests {
658706 . await
659707 . unwrap ( ) ;
660708
661- // Get the VUF private key
662- let vuf_private_key = get_test_vuf_private_key ( TEST_SUB_VUF_PRIVATE_KEY_SEED ) ;
709+ // Get the VUF keypair
710+ let vuf_keypair = utils :: create_vuf_keypair ( Some ( TEST_SUB_VUF_PRIVATE_KEY_SEED ) ) ;
663711
664712 // Verify the pepper base, derived pepper and account address
665713 verify_base_pepper_and_address_generation (
666- vuf_private_key ,
714+ vuf_keypair ,
667715 & pepper_input,
668716 TEST_SUB_OVERRIDE_PEPPER_BASE_HEX ,
669717 TEST_SUB_OVERRIDE_DERIVED_PEPPER_HEX ,
@@ -688,27 +736,17 @@ mod tests {
688736 }
689737 }
690738
691- /// Returns the test VUF private key from the given seed
692- fn get_test_vuf_private_key ( seed : [ u8 ; 32 ] ) -> Arc < ark_bls12_381:: Fr > {
693- // Derive the VUF private key from the seed
694- let mut sha3_hasher = sha3:: Sha3_512 :: new ( ) ;
695- sha3_hasher. update ( seed) ;
696- let vuf_private_key =
697- ark_bls12_381:: Fr :: from_be_bytes_mod_order ( sha3_hasher. finalize ( ) . as_slice ( ) ) ;
698- Arc :: new ( vuf_private_key)
699- }
700-
701739 /// Verifies the generated pepper base, derived pepper and account address against the expected values
702740 fn verify_base_pepper_and_address_generation (
703- vuf_private_key : Arc < ark_bls12_381 :: Fr > ,
741+ vuf_keypair : Arc < VUFKeypair > ,
704742 pepper_input : & PepperInput ,
705743 expected_pepper_base_hex : & str ,
706744 expected_derived_pepper_hex : & str ,
707745 expected_account_address : & str ,
708746 ) {
709747 // Derive the pepper base, pepper and account address
710748 let ( pepper_base, derived_pepper_bytes, address) =
711- derive_pepper_and_account_address ( vuf_private_key , None , pepper_input) . unwrap ( ) ;
749+ derive_pepper_and_account_address ( vuf_keypair , None , pepper_input) . unwrap ( ) ;
712750
713751 // Verify the pepper base, derived pepper and account address
714752 assert_eq ! ( hex:: encode( pepper_base) , expected_pepper_base_hex) ;
0 commit comments