Skip to content

Commit 40bb694

Browse files
committed
[Keyless] Add verify() call to pepper base logic.
1 parent 6200465 commit 40bb694

File tree

9 files changed

+217
-136
lines changed

9 files changed

+217
-136
lines changed

keyless/pepper/service/src/dedicated_handlers/handlers.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use crate::{
88
dedicated_handlers::pepper_request::handle_pepper_request,
99
error::PepperServiceError,
1010
external_resources::{jwk_fetcher, jwk_fetcher::JWKCache, resource_fetcher::CachedResources},
11+
vuf_keypair::VUFKeypair,
1112
};
1213
use aptos_crypto::ed25519::Ed25519PublicKey;
1314
use aptos_keyless_pepper_common::{
@@ -40,7 +41,7 @@ pub trait HandlerTrait<TRequest, TResponse>: Send + Sync {
4041
// TODO: is there a way we can remove the vuf_private_key param here?
4142
async fn handle_request(
4243
&self,
43-
vuf_private_key: Arc<ark_bls12_381::Fr>,
44+
vuf_keypair: Arc<VUFKeypair>,
4445
jwk_cache: JWKCache,
4546
cached_resources: CachedResources,
4647
request: TRequest,
@@ -56,7 +57,7 @@ pub struct V0DelegatedFetchHandler;
5657
impl HandlerTrait<PepperRequestV2, PepperResponse> for V0DelegatedFetchHandler {
5758
async fn handle_request(
5859
&self,
59-
vuf_private_key: Arc<ark_bls12_381::Fr>,
60+
vuf_keypair: Arc<VUFKeypair>,
6061
jwk_cache: JWKCache,
6162
cached_resources: CachedResources,
6263
request: PepperRequestV2,
@@ -79,7 +80,7 @@ impl HandlerTrait<PepperRequestV2, PepperResponse> for V0DelegatedFetchHandler {
7980

8081
// Fetch the pepper
8182
let (_pepper_base, pepper, address) = handle_pepper_request(
82-
vuf_private_key,
83+
vuf_keypair,
8384
jwk_cache,
8485
cached_resources,
8586
jwt,
@@ -109,7 +110,7 @@ pub struct V0FetchHandler;
109110
impl HandlerTrait<PepperRequest, PepperResponse> for V0FetchHandler {
110111
async fn handle_request(
111112
&self,
112-
vuf_private_key: Arc<ark_bls12_381::Fr>,
113+
vuf_keypair: Arc<VUFKeypair>,
113114
jwk_cache: JWKCache,
114115
cached_resources: CachedResources,
115116
request: PepperRequest,
@@ -128,7 +129,7 @@ impl HandlerTrait<PepperRequest, PepperResponse> for V0FetchHandler {
128129

129130
// Fetch the pepper
130131
let (_pepper_base, pepper, address) = handle_pepper_request(
131-
vuf_private_key,
132+
vuf_keypair,
132133
jwk_cache,
133134
cached_resources,
134135
jwt,
@@ -158,7 +159,7 @@ pub struct V0SignatureHandler;
158159
impl HandlerTrait<PepperRequest, SignatureResponse> for V0SignatureHandler {
159160
async fn handle_request(
160161
&self,
161-
vuf_private_key: Arc<ark_bls12_381::Fr>,
162+
vuf_keypair: Arc<VUFKeypair>,
162163
jwk_cache: JWKCache,
163164
cached_resources: CachedResources,
164165
request: PepperRequest,
@@ -177,7 +178,7 @@ impl HandlerTrait<PepperRequest, SignatureResponse> for V0SignatureHandler {
177178

178179
// Fetch the pepper base (i.e., VUF signature)
179180
let (pepper_base, _pepper, _address) = handle_pepper_request(
180-
vuf_private_key,
181+
vuf_keypair,
181182
jwk_cache,
182183
cached_resources,
183184
jwt,
@@ -207,7 +208,7 @@ pub struct V0VerifyHandler;
207208
impl HandlerTrait<VerifyRequest, VerifyResponse> for V0VerifyHandler {
208209
async fn handle_request(
209210
&self,
210-
_: Arc<ark_bls12_381::Fr>,
211+
_: Arc<VUFKeypair>,
211212
jwk_cache: JWKCache,
212213
cached_resources: CachedResources,
213214
request: VerifyRequest,

keyless/pepper/service/src/dedicated_handlers/pepper_request.rs

Lines changed: 74 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -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
};
1213
use aptos_keyless_pepper_common::{
1314
jwt::Claims,
@@ -28,7 +29,6 @@ use aptos_types::{
2829
};
2930
use jsonwebtoken::{Algorithm::RS256, DecodingKey, TokenData, Validation};
3031
use 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
4949
pub 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
144144
fn 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
246257
fn 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(
452463
mod 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);

keyless/pepper/service/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ pub mod external_resources;
88
pub mod metrics;
99
pub mod request_handler;
1010
pub mod utils;
11-
pub mod vuf_pub_key;
11+
pub mod vuf_keypair;
1212

1313
#[cfg(test)]
1414
mod tests;

keyless/pepper/service/src/main.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ use aptos_keyless_pepper_service::{
1818
metrics::DEFAULT_METRICS_SERVER_PORT,
1919
request_handler,
2020
request_handler::DEFAULT_PEPPER_SERVICE_PORT,
21-
utils, vuf_pub_key,
21+
utils, vuf_keypair,
22+
vuf_keypair::VUFKeypair,
2223
};
2324
use aptos_logger::{error, info, warn};
2425
use clap::Parser;
@@ -125,11 +126,14 @@ async fn main() {
125126

126127
// Fetch the VUF public and private keypair (this will load the private key into memory)
127128
info!("Fetching the VUF public and private keypair for the pepper service...");
128-
let (vuf_public_key, vuf_private_key) = vuf_pub_key::get_pepper_service_vuf_keypair(
129+
let vuf_keypair = vuf_keypair::get_pepper_service_vuf_keypair(
129130
args.vuf_private_key_hex,
130131
args.vuf_private_key_seed_hex,
131132
);
132-
info!("Retrieved the VUF public key: {:?}", vuf_public_key);
133+
info!(
134+
"Retrieved the VUF public key: {:?}",
135+
vuf_keypair.vuf_public_key_json()
136+
);
133137

134138
// Collect the account recovery managers
135139
info!("Collecting the account recovery managers...");
@@ -168,7 +172,7 @@ async fn main() {
168172
let jwk_cache = jwk_fetcher::start_jwk_fetchers(args.jwk_issuers_override.clone());
169173

170174
// Start the pepper service
171-
let vuf_keypair = Arc::new((vuf_public_key, Arc::new(vuf_private_key)));
175+
let vuf_keypair = Arc::new(vuf_keypair);
172176
start_pepper_service(
173177
args.pepper_service_port,
174178
vuf_keypair,
@@ -202,7 +206,7 @@ fn start_metrics_server() {
202206
// Starts the pepper service
203207
async fn start_pepper_service(
204208
pepper_service_port: u16,
205-
vuf_keypair: Arc<(String, Arc<ark_bls12_381::Fr>)>,
209+
vuf_keypair: Arc<VUFKeypair>,
206210
jwk_cache: JWKCache,
207211
cached_resources: CachedResources,
208212
account_recovery_managers: Arc<AccountRecoveryManagers>,

0 commit comments

Comments
 (0)