pub struct EncNetworkAddress { /* private fields */ }
Expand description

An encrypted NetworkAddress.

Threat Model

Encrypting the on-chain network addresses is purely a defense-in-depth mitigation to minimize attack surface and reduce DDoS attacks on the validators by restricting the visibility of their public-facing network addresses only to other validators.

These encrypted network addresses are intended to be stored on-chain under each validator’s advertised network addresses in their ValidatorConfigs. All validators share the secret shared_val_netaddr_key, though each validator’s addresses are encrypted using a per-validator derived_key.

Account Key

derived_key := HKDF-SHA3-256::extract_and_expand(
    salt=HKDF_SALT,
    ikm=shared_val_netaddr_key,
    info=account_address,
    output_length=32,
)

where HKDF-SHA3-256::extract_and_expand is HKDF extract-and-expand with SHA3-256, HKDF_SALT is a constant salt for application separation, shared_val_netaddr_key is the shared secret distributed amongst all the validators, and account_address is the specific validator’s AccountAddress.

We use per-validator derived_keys to limit the “blast radius” of nonce reuse to each validator, i.e., a validator that accidentally reuses a nonce will only leak information about their network addresses or derived_key.

Encryption

A raw network address, addr, is then encrypted using AES-256-GCM like:

enc_addr := AES-256-GCM::encrypt(
    key=derived_key,
    nonce=nonce,
    ad=key_version,
    message=addr,
)

where nonce is a 96-bit integer as described below, key_version is the key version as a u32 big-endian integer, addr is the serialized NetworkAddress, and enc_addr is the encrypted network address concatenated with the 16-byte authentication tag.

Nonce

nonce := seq_num || addr_idx

where seq_num is the seq_num field as a u64 big-endian integer and addr_idx is the index of the encrypted network address in the list of network addresses as a u32 big-endian integer.

Sequence Number

In order to reduce the probability of nonce reuse, validators should use the sequence number of the rotation transaction in the seq_num field.

Key Rotation

The EncNetworkAddress struct contains a key_version field, which identifies the specific shared_val_netaddr_key used to encrypt/decrypt the EncNetworkAddress.

Implementations§

source§

impl EncNetworkAddress

source

pub fn encrypt( addr: NetworkAddress, shared_val_netaddr_key: &Key, key_version: KeyVersion, account: &AccountAddress, seq_num: u64, addr_idx: u32 ) -> Result<Self, ParseError>

Panics

encrypt will panic if addr length > 64 GiB.

source

pub fn decrypt( self, shared_val_netaddr_key: &Key, account: &AccountAddress, addr_idx: u32 ) -> Result<NetworkAddress, ParseError>

source

pub fn key_version(&self) -> KeyVersion

source

pub fn seq_num(&self) -> u64

Trait Implementations§

source§

impl Arbitrary for EncNetworkAddress

§

type Parameters = ()

The type of parameters that arbitrary_with accepts for configuration of the generated Strategy. Parameters must implement Default.
§

type Strategy = BoxedStrategy<EncNetworkAddress>

The type of Strategy used to generate values of type Self.
source§

fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy

Generates a Strategy for producing arbitrary values of type the implementing type (Self). The strategy is passed the arguments given in args. Read more
§

fn arbitrary() -> Self::Strategy

Generates a Strategy for producing arbitrary values of type the implementing type (Self). Read more
source§

impl Clone for EncNetworkAddress

source§

fn clone(&self) -> EncNetworkAddress

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for EncNetworkAddress

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'de> Deserialize<'de> for EncNetworkAddress

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl PartialEq<EncNetworkAddress> for EncNetworkAddress

source§

fn eq(&self, other: &EncNetworkAddress) -> bool

This method tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

impl Serialize for EncNetworkAddress

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
source§

impl Eq for EncNetworkAddress

source§

impl StructuralEq for EncNetworkAddress

source§

impl StructuralPartialEq for EncNetworkAddress

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

const: unstable · source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

const: unstable · source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<Q, K> Equivalent<K> for Qwhere Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

source§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

const: unstable · source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for Twhere U: From<T>,

const: unstable · source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> Same<T> for T

§

type Output = T

Should always be Self
source§

impl<T> TestOnlyHash for Twhere T: Serialize + ?Sized,

source§

fn test_only_hash(&self) -> HashValue

Generates a hash used only for tests.
source§

impl<T> ToOwned for Twhere T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
const: unstable · source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
const: unstable · source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for Twhere V: MultiLane<T>,

§

fn vzip(self) -> V

source§

impl<T> DeserializeOwned for Twhere T: for<'de> Deserialize<'de>,