Skip to content

Commit

Permalink
Merge pull request #82 from dusk-network/fix_attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
xevisalle authored Oct 23, 2023
2 parents 6e28483 + 88bc3fb commit 223428c
Show file tree
Hide file tree
Showing 12 changed files with 60 additions and 56 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed

- fixed benches
- Change `attr` to `attr_data`[#80]

## [0.5.0] - 2023-10-12

Expand Down Expand Up @@ -80,6 +81,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Add workflows for the Github Actions

<!-- ISSUES -->
[#80]: https://github.com/dusk-network/citadel/issues/80
[#54]: https://github.com/dusk-network/citadel/issues/54
[#41]: https://github.com/dusk-network/citadel/issues/41
[#40]: https://github.com/dusk-network/citadel/issues/40
Expand Down
8 changes: 4 additions & 4 deletions specs/images/circuit_prove_nft.eps

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 11 additions & 11 deletions specs/images/circuit_prove_nft.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified specs/main.pdf
Binary file not shown.
2 changes: 2 additions & 0 deletions specs/main.tex
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@
\newcommand{\lsig}{\mathsf{sig_{lic}}}
\newcommand{\tsig}{\mathsf{sig_{tx}}}
\newcommand{\attr}{\mathsf{attr}}
\newcommand{\attrhash}{\mathsf{attr\_hash}}
\newcommand{\attrdata}{\mathsf{attr\_data}}
\newcommand{\sign}{\mathsf{sign\_single\_key}}
\newcommand{\signd}{\mathsf{sign\_double\_key}}
\newcommand{\verify}{\mathsf{verify\_sig\_single\_key}}
Expand Down
10 changes: 5 additions & 5 deletions specs/sections/definitions.tex
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ \subsection{The Elements Involved}
\textbf{Element} & \textbf{Type} & \textbf{Info.} \\
\hline
$(\lpk, R_{\lic})$ & StealthAddress & It is a license stealth address of the user. \\
$\enc$ & PoseidonCipher[4] & It is the encryption of some user attributes and the signature of these attributes. \\
$\enc$ & PoseidonCipher[4] & It is the encryption of the data of some user attributes and the signature of this data. \\
$\nonce$ & BlsScalar & Randomness needed to compute $\enc$. \\
$\pos$ & BlsScalar & It is the position of the license in the Merkle tree of licenses. \\
\hline
Expand All @@ -47,9 +47,9 @@ \subsection{The Elements Involved}
\hline
$\lpk$ & JubJubAffine & The license public key of the user.\\
$\lpk'$ & JubJubAffine & A variation of the license public key of the user computed with a different generator.\\
$\lsig$ & Signature & The signature of the license attributes. \\
$\lsig$ & Signature & The signature of the license attributes data. \\
$\com_0^{hash}$ & BlsScalar & A hash of the public key of the LP. \\
$\com_1$ & JubJubExtended & A Pedersen commitment of the attributes. \\
$\com_1$ & JubJubExtended & A Pedersen commitment of the attributes data. \\
$\com_2$ & JubJubExtended & A Pedersen commitment of the $c$ value. \\
$\mathsf{session\_hash}$ & BlsScalar & The hash of the public key of the SP together with some randomness. \\
$\mathsf{sig\_session\_hash}$ & dusk\_schnorr::Proof & The signature of the session hash signed by the user. \\
Expand All @@ -69,7 +69,7 @@ \subsection{The Elements Involved}
$\mathsf{session\_hash}$ & BlsScalar & The hash of the public key of the SP together with some randomness. \\
$\sessionid$ & BlsScalar & The id of a session open using a given license. \\
$\com_0^{hash}$ & BlsScalar & A hash of the public key of the LP. \\
$\com_1$ & JubJubExtended & A Pedersen commitment of the attributes. \\
$\com_1$ & JubJubExtended & A Pedersen commitment of the attributes data. \\
$\com_2$ & JubJubExtended & A Pedersen commitment of the $c$ value. \\
\hline
\end{tabular}
Expand All @@ -86,7 +86,7 @@ \subsection{The Elements Involved}
$r_\mathsf{session}$ & BlsScalar & Randomness for computing the session hash. \\
$\sessionid$ & BlsScalar & The id of a session open using a given license. \\
$\pk_{\LP}$ & JubJubAffine & The public key of the LP. \\
$\attr$ & JubJubScalar & The attributes of the user. \\
$\attrdata$ & JubJubScalar & Specific data concerning the attributes of the user. \\
$c$ & JubJubScalar & The challenge value. \\
$\mathsf{s_0}$ & JubJubScalar & Randomness used to compute $\com_0^{hash}$. \\
$\mathsf{s_1}$ & BlsScalar & Randomness used to compute $\com_1$. \\
Expand Down
2 changes: 1 addition & 1 deletion specs/sections/overview.tex
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ \subsection{What is Citadel}

A Self-Sovereign Identity (SSI) protocol serves the purpose of allowing users of a given service to manage their identities in a fully transparent manner. In other words, every user can know which information about them is shared with other parties, and accept or deny any request for personal information.

\verb!Citadel! is a SSI protocol built on top of Dusk Network. Users of a service can get a \textit{license}, which represents their \textit{right} to use such a service. In particular, \verb!Citadel! allows for the following properties:
\verb!Citadel! is a SSI protocol built on top of Dusk. Users of a service can get a \textit{license}, which represents their \textit{right} to use such a service. In particular, \verb!Citadel! allows for the following properties:

\begin{itemize}
\item \textbf{Proof of Ownership:} users can prove ownership of a license that allows them to use a given service.
Expand Down
12 changes: 6 additions & 6 deletions specs/sections/protocol.tex
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,17 @@

\item (\textbf{LP}) $\mathsf{get\_license\_request}$ : continuously check the network for incoming license requests, by checking if $\rpk \stackrel{?}{=} \hb(\tkreq) G + B_{\LP}$, where $\tkreq = a_{\LP}R_{\req}$.

\item (\textbf{LP}) $\mathsf{issue\_license}$ : upon receiving a request from a user, define a set of attributes $\attr$ representing the license, and compute a digital signature as follows:
\item (\textbf{LP}) $\mathsf{issue\_license}$ : upon receiving a request from a user, define a set of attributes $\attr$ representing the license, collect them (e.g. by concatenation) resulting in $\attrdata$, and compute a digital signature as follows:

$$\lsig = \sign_{\sk_{\SP}}(\lpk, \attr).$$
$$\lsig = \sign_{\sk_{\SP}}(\lpk, \attrdata).$$

Then, send the following license to the network:

$$\lic = ((\lpk, R_{\lic}), \enc, \nonce, \pos),$$

where

$$\enc = \Enc_{\klic} (\lsig || \attr; \nonce).$$
$$\enc = \Enc_{\klic} (\lsig || \attrdata; \nonce).$$

\item (\textbf{user}) $\mathsf{get\_license}$ : receive the license by scanning the incoming transactions, and checking if $\lpk \stackrel{?}{=} \hb(\tklic) G + B_{\user}$, where $\tklic = \hb(\lsk)G$.

Expand All @@ -74,16 +74,16 @@

\item (\textbf{user}) $\mathsf{request\_service}$ : request the service to the SP, establishing communication using a secure channel, and providing the session cookie that follows.

$$\SessionCookie = \{\pk_{\mathsf{SP}}, r_\mathsf{session}, \sessionid, \pk_{\LP}, \attr, c, \mathsf{s_0}, \mathsf{s_1}, \mathsf{s_2}\}$$
$$\SessionCookie = \{\pk_{\mathsf{SP}}, r_\mathsf{session}, \sessionid, \pk_{\LP}, \attrdata, c, \mathsf{s_0}, \mathsf{s_1}, \mathsf{s_2}\}$$

\item (\textbf{SSP}) $\mathsf{get\_session}$ : receive a $\Session$ from the list of sessions, where $\Session.\sessionid = \SessionCookie.\sessionid$.

\item (\textbf{SSP}) $\mathsf{grant\_service}$ : grant or deny the service upon verification of the following steps:

\begin{itemize}
\item Check whether the values $(\attr, \pk_{\LP}, c)$ included in the $\SessionCookie$ are correct.
\item Check whether the values $(\attrdata, \pk_{\LP}, c)$ included in the $\SessionCookie$ are correct.
\item Check whether the opening $(\pk_{\SP}, r_\mathsf{session})$ included in the $\SessionCookie$ matches the $\mathsf{session\_hash}$ found in the $\Session$.
\item Check whether the openings $((\pk_{\LP}, \mathsf{s_0}), (\attr, \mathsf{s_1}), (c, \mathsf{s_2}))$ included in the $\SessionCookie$ match the commitments ($\com_0^{hash}, \com_1, \com_2$) found in the $\Session$.
\item Check whether the openings $((\pk_{\LP}, \mathsf{s_0}), (\attrdata, \mathsf{s_1}), (c, \mathsf{s_2}))$ included in the $\SessionCookie$ match the commitments ($\com_0^{hash}, \com_1, \com_2$) found in the $\Session$.
\end{itemize}

\end{enumerate}
Expand Down
14 changes: 7 additions & 7 deletions src/gadgets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ pub fn use_license_citadel<C: Composer, const DEPTH: usize, const ARITY: usize>(
// VERIFY THE LICENSE SIGNATURE
let (sig_lic_u, sig_lic_r) = cpp.sig_lic.to_witness(composer);
let pk_lp = composer.append_point(sc.pk_lp);
let attr = composer.append_witness(sc.attr);
let attr_data = composer.append_witness(sc.attr_data);

let message = sponge::gadget(composer, &[*lpk.x(), *lpk.y(), attr]);
let message = sponge::gadget(composer, &[*lpk.x(), *lpk.y(), attr_data]);
gadgets::single_key_verify(composer, sig_lic_u, sig_lic_r, pk_lp, message)?;

// VERIFY THE SESSION HASH SIGNATURE
Expand All @@ -71,9 +71,9 @@ pub fn use_license_citadel<C: Composer, const DEPTH: usize, const ARITY: usize>(

composer.assert_equal(com_0, com_0_pi);

// COMMIT TO THE ATTRIBUTE
// COMMIT TO THE ATTRIBUTE DATA
let s_1 = composer.append_witness(sc.s_1);
let pc_1_1 = composer.component_mul_generator(attr, GENERATOR);
let pc_1_1 = composer.component_mul_generator(attr_data, GENERATOR);
let pc_1_2 = composer.component_mul_generator(s_1, GENERATOR_NUMS);
let com_1 = composer.component_add_point(pc_1_1.unwrap(), pc_1_2.unwrap());

Expand Down Expand Up @@ -105,7 +105,7 @@ pub fn use_license_citadel<C: Composer, const DEPTH: usize, const ARITY: usize>(
// public_inputs[1]: c
// public_inputs[2]: pk_lp.x
// public_inputs[3]: pk_lp.y
// public_inputs[4]: attr
// public_inputs[4]: attr_data
// public_inputs[5]: root

pub fn use_license_shelter<C: Composer, const DEPTH: usize, const ARITY: usize>(
Expand All @@ -128,9 +128,9 @@ pub fn use_license_shelter<C: Composer, const DEPTH: usize, const ARITY: usize>(
// VERIFY THE LICENSE SIGNATURE
let (sig_lic_u, sig_lic_r) = spp.sig_lic.to_witness(composer);
let pk_lp = composer.append_public_point(spp.pk_lp);
let attr = composer.append_public(spp.attr);
let attr_data = composer.append_public(spp.attr_data);

let message = sponge::gadget(composer, &[*lpk.x(), *lpk.y(), attr]);
let message = sponge::gadget(composer, &[*lpk.x(), *lpk.y(), attr_data]);
gadgets::single_key_verify(composer, sig_lic_u, sig_lic_r, pk_lp, message)?;

// COMPUTE THE HASH OF THE LICENSE
Expand Down
36 changes: 18 additions & 18 deletions src/license.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ impl Session {
let com_0 = sponge::hash(&[pk_lp.get_u(), pk_lp.get_v(), sc.s_0]);
assert_eq!(com_0, self.com_0);

let com_1 = (GENERATOR_EXTENDED * sc.attr) + (GENERATOR_NUMS_EXTENDED * sc.s_1);
let com_1 = (GENERATOR_EXTENDED * sc.attr_data) + (GENERATOR_NUMS_EXTENDED * sc.s_1);
assert_eq!(com_1, self.com_1);

let com_2 = (GENERATOR_EXTENDED * sc.c) + (GENERATOR_NUMS_EXTENDED * sc.s_2);
Expand All @@ -141,9 +141,9 @@ pub struct SessionCookie {
pub r: BlsScalar, // randomness for session_hash
pub session_id: BlsScalar,

pub pk_lp: JubJubAffine, // public key of the LP
pub attr: JubJubScalar, // attributes of the license
pub c: JubJubScalar, // challenge value
pub pk_lp: JubJubAffine, // public key of the LP
pub attr_data: JubJubScalar, // attribute data of the license
pub c: JubJubScalar, // challenge value

pub s_0: BlsScalar, // randomness for com_0
pub s_1: JubJubScalar, // randomness for com_1
Expand All @@ -158,15 +158,15 @@ pub struct SessionCookie {
#[derive(Default, Debug, Clone)]
pub struct License {
pub lsa: StealthAddress, // license stealth address
pub enc_1: PoseidonCipher, // encryption of the license signature and attributes
pub enc_1: PoseidonCipher, // encryption of the license signature and attribute data
pub nonce_1: BlsScalar, // IV for the encryption
pub enc_2: PoseidonCipher, // encryption of the license signature and attributes
pub enc_2: PoseidonCipher, // encryption of the license signature and attribute data
pub nonce_2: BlsScalar, // IV for the encryption
}

impl License {
pub fn new<R: RngCore + CryptoRng>(
attr: &JubJubScalar,
attr_data: &JubJubScalar,
ssk_lp: &SecretSpendKey,
req: &Request,
mut rng: &mut R,
Expand All @@ -192,7 +192,7 @@ impl License {
let r = JubJubAffine::from_raw_unchecked(dec_2[0], dec_2[1]);
let k_lic = JubJubAffine::from_raw_unchecked(dec_3[0], dec_3[1]);

let message = sponge::hash(&[lpk.get_u(), lpk.get_v(), BlsScalar::from(*attr)]);
let message = sponge::hash(&[lpk.get_u(), lpk.get_v(), BlsScalar::from(*attr_data)]);

let sig_lic = Signature::new(&SecretKey::from(ssk_lp.a()), rng, message);
let sig_lic_r = JubJubAffine::from(sig_lic.R());
Expand All @@ -201,7 +201,7 @@ impl License {
let nonce_2 = BlsScalar::random(&mut rng);

let enc_1 = PoseidonCipher::encrypt(
&[BlsScalar::from(*sig_lic.u()), BlsScalar::from(*attr)],
&[BlsScalar::from(*sig_lic.u()), BlsScalar::from(*attr_data)],
&k_lic,
&nonce_1,
);
Expand Down Expand Up @@ -293,7 +293,7 @@ impl<const DEPTH: usize, const ARITY: usize> CitadelProverParameters<DEPTH, ARIT
.decrypt(&k_lic, &lic.nonce_2)
.expect("decryption should succeed");

let attr = JubJubScalar::from_bytes(&dec_1[1].to_bytes()).unwrap();
let attr_data = JubJubScalar::from_bytes(&dec_1[1].to_bytes()).unwrap();
let sig_lic = Signature::from_bytes(
&[
dec_1[0].to_bytes(),
Expand Down Expand Up @@ -326,7 +326,7 @@ impl<const DEPTH: usize, const ARITY: usize> CitadelProverParameters<DEPTH, ARIT
let pk_lp = JubJubAffine::from(*psk_lp.A());

let com_0 = sponge::hash(&[pk_lp.get_u(), pk_lp.get_v(), s_0]);
let com_1 = (GENERATOR_EXTENDED * attr) + (GENERATOR_NUMS_EXTENDED * s_1);
let com_1 = (GENERATOR_EXTENDED * attr_data) + (GENERATOR_NUMS_EXTENDED * s_1);
let com_2 = (GENERATOR_EXTENDED * c) + (GENERATOR_NUMS_EXTENDED * s_2);

(
Expand All @@ -348,7 +348,7 @@ impl<const DEPTH: usize, const ARITY: usize> CitadelProverParameters<DEPTH, ARIT
r,
session_id,
pk_lp,
attr,
attr_data,
c: *c,
s_0,
s_1,
Expand All @@ -362,9 +362,9 @@ impl<const DEPTH: usize, const ARITY: usize> CitadelProverParameters<DEPTH, ARIT
pub struct ShelterProverParameters<const DEPTH: usize, const ARITY: usize> {
pub lsk: JubJubScalar, // license secret key

pub sig_lic: Signature, // signature of the licensee
pub pk_lp: JubJubAffine, // public key of the LP
pub attr: JubJubScalar, // attributes of the license
pub sig_lic: Signature, // signature of the licensee
pub pk_lp: JubJubAffine, // public key of the LP
pub attr_data: JubJubScalar, // attribute data of the license

pub c: JubJubScalar, // challenge value
pub session_id: BlsScalar,
Expand All @@ -386,7 +386,7 @@ impl<const DEPTH: usize, const ARITY: usize> Default for ShelterProverParameters

sig_lic: Signature::default(),
pk_lp: JubJubAffine::default(),
attr: JubJubScalar::default(),
attr_data: JubJubScalar::default(),

c: JubJubScalar::default(),
session_id: BlsScalar::default(),
Expand Down Expand Up @@ -420,7 +420,7 @@ impl<const DEPTH: usize, const ARITY: usize> ShelterProverParameters<DEPTH, ARIT
.decrypt(&k_lic, &lic.nonce_2)
.expect("decryption should succeed");

let attr = JubJubScalar::from_bytes(&dec_1[1].to_bytes()).unwrap();
let attr_data = JubJubScalar::from_bytes(&dec_1[1].to_bytes()).unwrap();
let sig_lic = Signature::from_bytes(
&[
dec_1[0].to_bytes(),
Expand All @@ -443,7 +443,7 @@ impl<const DEPTH: usize, const ARITY: usize> ShelterProverParameters<DEPTH, ARIT

sig_lic,
pk_lp,
attr,
attr_data,

c: *c,
session_id,
Expand Down
6 changes: 3 additions & 3 deletions src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use poseidon_merkle::{Item, Opening, Tree};
use rand_core::{CryptoRng, RngCore};

// Example values
const USER_ATTRIBUTES: u64 = 112233445566778899u64;
const ATTRIBUTE_DATA: u64 = 112233445566778899u64;
const CHALLENGE: u64 = 20221126u64;

pub struct CitadelUtils {}
Expand All @@ -38,8 +38,8 @@ impl CitadelUtils {
let req = Request::new(&psk_lp, &lsa, &k_lic, rng);

// Second, the LP computes these values and grants the License
let attr = JubJubScalar::from(USER_ATTRIBUTES);
let lic = License::new(&attr, &ssk_lp, &req, rng);
let attr_data = JubJubScalar::from(ATTRIBUTE_DATA);
let lic = License::new(&attr_data, &ssk_lp, &req, rng);

let mut tree = Tree::<(), DEPTH, ARITY>::new();
let lpk = JubJubAffine::from(lic.lsa.pk_r().as_ref());
Expand Down
2 changes: 1 addition & 1 deletion tests/citadel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ fn test_citadel_false_session_cookie() {
r: sc.r,
session_id: sc.session_id,
pk_lp: sc.pk_lp,
attr: JubJubScalar::from(1234u64),
attr_data: JubJubScalar::from(1234u64),
c: sc.c,
s_0: sc.s_0,
s_1: sc.s_1,
Expand Down

0 comments on commit 223428c

Please sign in to comment.