Skip to content
Snippets Groups Projects
Commit 13edaf68 authored by Ian Jackson's avatar Ian Jackson :speech_balloon:
Browse files

Merge branch 'blind' into 'main'

key blinding: Use consistent terminology

See merge request tpo/core/arti!1085
parents edb3ac26 4c2a9332
No related branches found
No related tags found
No related merge requests found
......@@ -248,9 +248,9 @@ impl HsIdKey {
) -> Result<(HsBlindIdKey, crate::Subcredential), keymanip::BlindingError> {
// TODO hs: decide whether we want to support this kind of shared secret; C Tor does not.
let secret = b"";
let param = self.blinding_parameter(secret, cur_period);
let h = self.blinding_factor(secret, cur_period);
let blinded_key = keymanip::blind_pubkey(&self.0, param)?;
let blinded_key = keymanip::blind_pubkey(&self.0, h)?;
// rend-spec-v3 section 2.1
let subcredential_bytes: [u8; 32] = {
// N_hs_subcred = H("subcredential" | N_hs_cred | blinded-public-key).
......@@ -272,11 +272,13 @@ impl HsIdKey {
Ok((blinded_key.into(), subcredential_bytes.into()))
}
/// Compute the 32-byte "blinding parameters" used to compute blinded public
/// Compute the 32-byte "blinding factor" used to compute blinded public
/// (and secret) keys.
fn blinding_parameter(&self, secret: &[u8], cur_period: TimePeriod) -> [u8; 32] {
///
/// Returns the value `h = H(...)`, from rend-spec-v3 A.2., before clamping.
fn blinding_factor(&self, secret: &[u8], cur_period: TimePeriod) -> [u8; 32] {
// rend-spec-v3 appendix A.2
// We generate our key blinding parameter as
// We generate our key blinding factor as
// h = H(BLIND_STRING | A | s | B | N)
// Where:
// H is SHA3-256.
......@@ -317,15 +319,15 @@ impl HsIdSecretKey {
let secret = b"";
// Note: This implementation is somewhat inefficient, as it recomputes
// the PublicKey, and computes our blinding parameters twice. But we
// the PublicKey, and computes our blinding factor twice. But we
// only do this on an onion service once per time period: the
// performance does not matter.
let public_key: HsIdKey = ed25519::PublicKey::from(&self.0).into();
let (blinded_public_key, subcredential) = public_key.compute_blinded_key(cur_period)?;
let param = public_key.blinding_parameter(secret, cur_period);
let blinded_secret_key = keymanip::blind_seckey(&self.0, param)?;
let h = public_key.blinding_factor(secret, cur_period);
let blinded_secret_key = keymanip::blind_seckey(&self.0, h)?;
Ok((blinded_public_key, blinded_secret_key.into(), subcredential))
}
......@@ -586,9 +588,9 @@ mod test {
.unwrap();
assert_eq!(time_period.interval_num, 1234);
let param = id_pubkey.blinding_parameter(b"", time_period);
let h = id_pubkey.blinding_factor(b"", time_period);
assert_eq!(
param,
h,
hex!("379E50DB31FEE6775ABD0AF6FB7C371E060308F4F847DB09FE4CFE13AF602287")
);
......
......@@ -126,29 +126,31 @@ impl From<ed25519_dalek::SignatureError> for BlindingError {
}
}
/// Helper: clamp a blinding parameter and use it to compute a blinding factor.
/// Helper: clamp a blinding factor and use it to compute a blinding factor.
///
/// Described in part of rend-spec-v3 A.2.
///
/// This is a common step for public-key and private-key blinding.
#[cfg(any(feature = "hsv3-client", feature = "hsv3-service"))]
fn blinding_factor(mut param: [u8; 32]) -> Scalar {
// Clamp the blinding parameter
param[0] &= 248;
param[31] &= 63;
param[31] |= 64;
fn clamp_blinding_factor(mut h: [u8; 32]) -> Scalar {
h[0] &= 248;
h[31] &= 63;
h[31] |= 64;
// Transform it into a scalar so that we can do scalar mult.
Scalar::from_bytes_mod_order(param)
Scalar::from_bytes_mod_order(h)
}
/// Blind the ed25519 public key `pk` using the blinding parameter
/// `param`, and return the blinded public key.
/// Blind the ed25519 public key `pk` using the blinding factor
/// `h`, and return the blinded public key.
///
/// This algorithm is described in `rend-spec-v3.txt`, section A.2.
/// In the terminology of that section, the value `pk` corresponds to
/// `A`, and the value `param` corresponds to `h`.
/// `A`, and
/// `h` is the value `h = H(...)`, before clamping.
///
/// Note that the approach used to clamp `param` to a scalar means
/// that different possible values for `param` may yield the same
/// Note that the approach used to clamp `h` to a scalar means
/// that different possible values for `h` may yield the same
/// output for a given `pk`. This and other limitations make this
/// function unsuitable for use outside the context of
/// `rend-spec-v3.txt` without careful analysis.
......@@ -162,10 +164,10 @@ fn blinding_factor(mut param: [u8; 32]) -> Scalar {
///
/// This function is only available when the `hsv3-client` feature is enabled.
#[cfg(feature = "hsv3-client")]
pub fn blind_pubkey(pk: &PublicKey, param: [u8; 32]) -> Result<PublicKey, BlindingError> {
pub fn blind_pubkey(pk: &PublicKey, h: [u8; 32]) -> Result<PublicKey, BlindingError> {
use curve25519_dalek::edwards::CompressedEdwardsY;
let blinding_factor = blinding_factor(param);
let blinding_factor = clamp_blinding_factor(h);
// Convert the public key to a point on the curve
let pubkey_point = CompressedEdwardsY(pk.to_bytes())
......@@ -178,13 +180,14 @@ pub fn blind_pubkey(pk: &PublicKey, param: [u8; 32]) -> Result<PublicKey, Blindi
Ok(PublicKey::from_bytes(&blinded_pubkey_point.0)?)
}
/// Blind the ed25519 secret key `sk` using the blinding parameter `param`, and
/// Blind the ed25519 secret key `sk` using the blinding factor `h`, and
/// return the blinded secret key.
///
/// This algorithm is described in `rend-spec-v3.txt`, section A.2.
/// `h` is the value `h = H(...)`, before clamping.
///
/// Note that the approach used to clamp `param` to a scalar means that
/// different possible values for `param` may yield the same output for a given
/// Note that the approach used to clamp `h` to a scalar means that
/// different possible values for `h` may yield the same output for a given
/// `pk`. This and other limitations make this function unsuitable for use
/// outside the context of `rend-spec-v3.txt` without careful analysis.
///
......@@ -211,7 +214,7 @@ pub fn blind_pubkey(pk: &PublicKey, param: [u8; 32]) -> Result<PublicKey, Blindi
#[cfg(feature = "hsv3-service")]
pub fn blind_seckey(
sk: &ExpandedSecretKey,
param: [u8; 32],
h: [u8; 32],
) -> Result<ExpandedSecretKey, BlindingError> {
use arrayref::{array_mut_ref, array_ref};
use zeroize::Zeroizing;
......@@ -221,7 +224,7 @@ pub fn blind_seckey(
/// implementations consistent.)
const RH_BLIND_STRING: &[u8] = b"Derive temporary signing key hash input";
let blinding_factor = blinding_factor(param);
let blinding_factor = clamp_blinding_factor(h);
let secret_key_bytes = Zeroizing::new(sk.to_bytes());
let mut blinded_key_bytes = Zeroizing::new([0_u8; 64]);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment