feat(lee): make EncryptedAccountData guest-availiable

Likewise moves the epk definition outside of host-gated module
This commit is contained in:
agureev 2026-06-10 21:59:55 +04:00
parent c063872f1c
commit 6c9ee8896a
3 changed files with 49 additions and 8 deletions

View File

@ -6,7 +6,7 @@ use chacha20::{
use risc0_zkvm::sha::{Impl, Sha256 as _};
use serde::{Deserialize, Serialize};
#[cfg(feature = "host")]
pub use shared_key_derivation::{EphemeralPublicKey, MlKem768EncapsulationKey, ViewingPublicKey};
pub use shared_key_derivation::{MlKem768EncapsulationKey, ViewingPublicKey};
use crate::{Commitment, account::Account, program::PrivateAccountKind};
#[cfg(feature = "host")]
@ -17,6 +17,11 @@ pub type Scalar = [u8; 32];
#[derive(Serialize, Deserialize, Clone, Copy)]
pub struct SharedSecretKey(pub [u8; 32]);
/// The ML-KEM-768 ciphertext produced during encapsulation; transmitted on-wire in place of the
/// former ECDH ephemeral public key. Always 1088 bytes for ML-KEM-768.
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, BorshSerialize, BorshDeserialize)]
pub struct EphemeralPublicKey(pub Vec<u8>);
pub struct EncryptionScheme;
#[derive(Serialize, Deserialize, BorshSerialize, BorshDeserialize)]
@ -36,6 +41,45 @@ impl std::fmt::Debug for Ciphertext {
}
}
pub type ViewTag = u8;
/// Encrypted private-account note for one output
#[derive(Serialize, Deserialize, BorshSerialize, BorshDeserialize)]
#[cfg_attr(any(feature = "host", test), derive(Debug, Clone, PartialEq, Eq))]
pub struct EncryptedAccountData {
pub ciphertext: Ciphertext,
pub epk: EphemeralPublicKey,
pub view_tag: ViewTag,
}
#[cfg(feature = "host")]
impl EncryptedAccountData {
#[must_use]
pub fn new(
ciphertext: Ciphertext,
npk: &crate::NullifierPublicKey,
vpk: &ViewingPublicKey,
epk: EphemeralPublicKey,
) -> Self {
let view_tag = Self::compute_view_tag(npk, vpk);
Self {
ciphertext,
epk,
view_tag,
}
}
/// Computes the tag as the first byte of SHA256("/LEE/v0.3/ViewTag/" || npk || vpk).
#[must_use]
pub fn compute_view_tag(npk: &crate::NullifierPublicKey, vpk: &ViewingPublicKey) -> ViewTag {
let mut bytes = Vec::new();
bytes.extend_from_slice(b"/LEE/v0.3/ViewTag/");
bytes.extend_from_slice(&npk.to_byte_array());
bytes.extend_from_slice(vpk.to_bytes());
Impl::hash_bytes(&bytes).as_bytes()[0]
}
}
impl EncryptionScheme {
#[must_use]
pub fn encrypt(

View File

@ -2,12 +2,7 @@ use borsh::{BorshDeserialize, BorshSerialize};
use ml_kem::{Decapsulate as _, Encapsulate as _, KeyExport as _, Seed};
use serde::{Deserialize, Serialize};
use crate::SharedSecretKey;
/// The ML-KEM-768 ciphertext produced during encapsulation; transmitted on-wire in place of the
/// former ECDH ephemeral public key. Always 1088 bytes for ML-KEM-768.
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, BorshSerialize, BorshDeserialize)]
pub struct EphemeralPublicKey(pub Vec<u8>);
use crate::{EphemeralPublicKey, SharedSecretKey};
/// ML-KEM-768 encapsulation key bytes (1184 bytes, opaque to this crate).
#[derive(

View File

@ -10,7 +10,9 @@ pub use commitment::{
Commitment, CommitmentSetDigest, DUMMY_COMMITMENT, DUMMY_COMMITMENT_HASH, MembershipProof,
compute_digest_for_path,
};
pub use encryption::{EncryptionScheme, SharedSecretKey};
pub use encryption::{
EncryptedAccountData, EncryptionScheme, EphemeralPublicKey, SharedSecretKey, ViewTag,
};
pub use nullifier::{Identifier, Nullifier, NullifierPublicKey, NullifierSecretKey};
pub use program::PrivateAccountKind;