Skip to main content

Module sso

Module sso 

Source
Expand description

Data structures related to the authentication of users towards hubs.

§Overview

§Pseudonyms

The pseudonym a user $U$ gets in a hub $H$ is $$\mathrm{Sha512}(g_H \cdot \mathrm{Id}_U )$$ mapped to a CurvePoint, where:

  • $\mathrm{Id}_U$ is a permanent unchanging secret user identifier (a random CurvePoint). The secret user identifier is known to no one, not even the user itself. PHC and the transcryptor only get to see the ElGamal encrypted form known as the polymorphic pseudonym (see below).

    Note: The secret user identifier should not be confused with the user_id used by PHC internally to identify a user.)

  • $g_H$ is the pseudonymisation factor, a scalar unique to the hub $H$, known only by the transcryptor: $$g_H := \mathrm{Sha512}(H \Vert \ell_d \Vert d \Vert \ell_g \Vert g)$$ where $H$ is the hub id (32 bytes), $d := \text{“pubhubs-pseud-factor”}$, $g$ is the transcryptor’s pseudonymisation-factor secret, and $\ell_d, \ell_g$ are the byte lengths of $d, g$ encoded as 8-byte big-endian unsigned integers.

    Expand example

    Example

    use sha2::Digest; // brings `chain_update` and `new` into scope
    let h = pubhubs::id::Id::from([7u8; 32]);
    let g: &[u8] = b"abc";          // 3 bytes
    let d = "pubhubs-pseud-factor"; // 20 bytes
    assert_eq!(
        pubhubs::phcrypto::pseud_factor_for_hub(g, h),
        curve25519_dalek::Scalar::from_hash(
            sha2::Sha512::new()
                .chain_update(h.as_slice())
                .chain_update([0, 0, 0, 0, 0, 0, 0, 20u8])
                .chain_update(d.as_bytes())
                .chain_update([0, 0, 0, 0, 0, 0, 0, 3u8])
                .chain_update(g),
        ),
    );

Note: The white paper uses $g_H\cdot \mathrm{Id}_U$ instead of $\mathrm{Sha512}(g_H\cdot \mathrm{Id}_U)$. The hash has been added to protect the pseudonym against harvest-now-decrypt-later-by-a-quantum-computer attacks.

The SSO flow described below gets the pseudonym $\mathrm{Sha512}(g_H \cdot \mathrm{Id}_U )$ of a user $U$ to the hub $H$ in such a way that:

  • The hub learns only this pseudonym.
  • PHC learns $U$, but not what hub $H$ they are visiting.
  • The transcryptor learns $H$ (and knows $g_H$), but can not* deduce $U$.

§Polymorphic pseudonyms

A polymorphic pseudonym $\mathrm{PP}_U$ for the user $U$ is an ElGamal encryption of $\mathrm{Id}_U$ of the form $$ \mathrm{PP}_U \ :=\ (rB,\ \mathrm{Id}_U + rxB,\ xB).$$ Here:

  • $B$ denotes the base point used by CurvePoint.
  • $x := x_{\mathrm{T}} x_{\mathrm{PHC}}$ is the master encryption key, that splits into two master encryption key parts, $x_{\mathrm{T}}$ and $x_{\mathrm{PHC}}$, picked by the transcryptor and PHC, respectively.
  • $r$ is a random Scalar.

While each user has just one $\mathrm{Id}_U$, it has many different polymorphic pseudonyms on account of the random factor $r$. The polymorphic pseudonym serves two purposes:

  1. It ‘identifies’ the user $U$ (towards the transcryptor) without always having the same shape, so it can not be used to track logins of the same user.

  2. It allows operations to be performed on $\mathrm{Id}_U$ without revealing $\mathrm{Id}_U$ itself (via the homomorphic properties of ElGamal encryption, see elgamal::Triple::rsk.)

§Flow

  1. The user first obtains a PolymorphicPseudonymPackage (PPP) from PHC, which contains a polymorphic pseudonym nonce (ppnonce) and a polymorphic pseudonym. The polymorphic pseudonym is the ElGamal encryption of

Structs§

EncryptedHubPseudonymPackage
Returned (in sealed form) by tr::EhppEP, needed for phc::user::HhppEP.
HashedHubPseudonymPackage
Returned (in sealed form) by phc::user::HhppEP, needed for hub::EnterCompleteEP.
PolymorphicPseudonymPackage
Returned (in sealed form) by phc::user::PppEP, needed for tr::EhppEP.