Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/remove zksk #3

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ env/
*.eggs
*.egg-info
.pytest_cache
dist
34 changes: 34 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
CURRENT_VERSION ?= `poetry version -s`
SEMVERS := major minor patch

install_dependencies:
sudo apt-get install python-dev
sudo apt-get install libssl-dev
sudo apt-get install libffi-dev

install: install_poetry

install_poetry:
poetry install

tests:
poetry run pytest

clean:
find . -name "*.pyc" -exec rm -rf {} \;
rm -rf dist *.egg-info __pycache__ .eggs

dist:
poetry build

tag_version:
git commit -m "build: bump to ${CURRENT_VERSION}" pyproject.toml
git tag ${CURRENT_VERSION}

$(SEMVERS):
poetry version $@
$(MAKE) tag_version

set_version:
poetry version ${CURRENT_VERSION}
$(MAKE) tag_version
120 changes: 42 additions & 78 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,47 @@
> Disclaimer: this is a fork of https://github.com/spring-epfl/SSCred/ where we removed `zksk` dependency and therefore the use of commitment and ACL. Only Abe's blind signature.

# SSCred

A python library to facilitate anonymous authentication. SSCred provides the following primitives:

* Anonymous credential light (ACL)<sup>[1](#cn1)</sup>
* Abe's Blind signature<sup>[2](#cn2)</sup>
* Blinded Pedersen commitment
- Anonymous credential light (ACL)<sup>[1](#cn1)</sup>
- Abe's Blind signature<sup>[2](#cn2)</sup>

## Requirement
SSCred depends on the `petlib` and `zksk` libraries. Before installing the library make sure that `libssl-dev`, `python-dev`, and `libffi-dev` packages are installed on your machine. You can use following commands on Ubuntu/Debian to install them.

SSCred depends on the `petlib` libraries. Before installing the library make sure that `libssl-dev`, `python-dev`, and `libffi-dev` packages are installed on your machine. You can use following commands on Ubuntu/Debian to install them.

```
sudo apt-get install python-dev
sudo apt-get install libssl-dev
sudo apt-get install libffi-dev
```

Note: Only blinded Pederson commitment and ACL depend on `zksk` and you can use the blind signature without relying on `zksk`.

## Installing

### With poetry

Install system dependencies once and for all::

```
make install_dependencies
```

To develop, `install Poetry <https://python-poetry.org/docs/#installation>`\_ then just run::

```
make install
make tests
```

To run the server:

```
make run
```

### With pip

You can use `pip` to install the library.

```
Expand All @@ -31,6 +55,7 @@ python -m pytest
```

### Development

If you are interested in contributing to this library, you can clone the code and
install the library in the development mode.

Expand All @@ -43,47 +68,16 @@ pip install -e .
python -m pytest
```

## Usage
### Anonymous credential light
Provides an one-time-use anonymous credential based on ACL<sup>[1](#cn1)</sup>. The user decides on a list of attributes and a message and engages in an interactive protocol with the issuer. At the end of the protocol, the user computes a credential which is verifiable using the issuer's public key. During this process, the issuer does not learn any information about the attributes or the message.
At a later time, users can show the credential to a verifier to authorize their attributes and the message. This credential is publicly verifiable and anyone who knows the issuer public key can check it. This credential is not linked to the identity of the user. However, using a credential more than once is detectable and the verifier can link interactions with the same credential. In other words, if the user uses the credential more than once, then the credential becomes a pseudo-identity for the user. As a safeguard, the library raises an exception if the user tries to use a credential more than once.

Attributes can be either `int`, `petlib.Bn`, `str`, or `bytes`. The library hashes attributes for internal use but keeps a copy of raw attribute values as private variables. The user can embed a public key in attributes to be able to sign with the credential after receiving it.

*Warning*: There is a new attack <sup>[2](#cn2)</sup> that breaks the ROS security assumption. This means that running concurrent ACL signing sessions is insecure.

How to use:
```python
>>> # generating keys and wrappers
>>> issuer_priv, issuer_pk = ACLParam().generate_new_key_pair()
>>> issuer = ACLIssuer(issuer_priv, issuer_pk)
>>> user = ACLUser(issuer_pk)
>>> message = "Hello world"

>>> # Issuance
>>> attributes = [Bn(13), "Hello", "WoRlD", "Hidden"]
>>> attr_proof = user.prove_attr_knowledge(attributes)
>>> com, issuer_state = issuer.commit(attr_proof)
>>> challenge, user_state = user.compute_blind_challenge(com, message)
>>> resp = issuer.respond(challenge, issuer_state)
>>> cred_private = user.compute_credential(resp, user_state)

>>> # show credential
>>> # Reveal attributes 0, 1, and 2.
>>> cred = cred_private.show_credential([True, True, True, False])
>>> assert cred.verify_credential(issuer_pk)
>>> print(cred.get_message())
b'Hello world'
>>> print(cred.get_attributes())
[13, 'Hello', 'WoRlD', None]
```
## Usage

### Abe's blind signature

The user decides on a message and engages in an interactive protocol with the signer to compute a signature on the message. This protocol prevents the signer from learning the content of the message. The signature is verifiable by anyone who knows the signer's public key. No one, including the signer, can determine the user's identity when he reveals his signature. This blind signature is similar to an ACL credential with an empty attribute list. This signature is based on Abe's blind signature<sup>[3](#cn3)</sup>.

*Note*: The ROS attack <sup>[2](#cn2)</sup> does **not** impact the security of Abe's signature.
_Note_: The ROS attack <sup>[2](#cn2)</sup> does **not** impact the security of Abe's signature.

How to use:

How to use:
```python
>>> # generating keys and wrappers
>>> priv, pk = AbeParam().generate_new_key_pair()
Expand All @@ -103,55 +97,25 @@ The user decides on a message and engages in an interactive protocol with the si
b'Hello world'
```

### Blinded Pedersen Commitment
This scheme allows a party to prove the knowledge of a commitment without revealing any information about underlying values or the commitment itself. This primitive is mainly intended as a building block for more complicated primitives rather than direct use. This commitment only accepts values of type `int`, `petlib.Bn`, `str`, or `bytes`.

How to use:
```python
>>> values = [Bn(123), Bn(456), 'hello', b"world"]
>>> param = BlindedPedersenParam(hs_size=len(values))

>>> # reveal nothing
>>> bcommit, bpriv = param.blind_commit(values)
>>> bproof = bcommit.prove_values(bpriv)
>>> assert bcommit.verify_proof(param, bproof)

>>> # revealing some values
>>> bproof = bcommit.prove_values(bpriv, reveal_mask=[True, False, True, True])
>>> assert bcommit.verify_proof(param, bproof)
>>> print(bproof.revealed_values)
[123, None, 'hello', b'world']
```

## Performance

We used the `benchmark.py` to evaluate the performance. This scripts runs operations of ACL and Abe's signature 1000 times and records the cost. `benchmarkStats.py` is a script that compiles statistics based on the measurements of `benchmark.py`.

Curve P-224 and P-256 provide 112-bit and 128-bit security respectively. Curve P-256 is heavily optimized for performance. That is why it has better performance despite higher security.

All measurements are done on a desktop equipped with Intel(R) Core(TM) i7-9700 CPU @ 3.00GHz and 16GiB of RAM running Debian 10.

### Abe's signature

The size of the message and raw values is not included in the credential as it depends on the user input.
The communication cost shows the transfer cost of running the protocol, and the signature size shows the size of the resulting signature.

| Curve | Key gen (ms) | Signer (ms) | User (ms) | Verification (ms) | Signature size (B) | Communication (B) |
|-------|:------------:|:-----------:|:----------:|:-----------------:|:------------------:|:-----------------:|
| P-224 | 0.84 | 1.13 | 1.63 | 0.68 | 324 | 367 |
| P-256 | 0.13 | 0.32 | 0.62 | 0.4 | 360 | 413 |

### ACL
We evaluated ACL credential with 4 attributes; we reveal 3 of these attributes in the showing credential process.

The communication cost shows the transfer cost of the issuance protocol, and the credential size is the transfer cost of showing the credential. The size of the message and raw values are not included in the credential size as they depend on the user's input. The communication cost of showing the credential is higher than issuance because of large NIZK proofs.

| Curve | Key gen (ms) | Issuer (ms) | User (ms) | Showing cred(ms)| Verification (ms) | Credential size (B) | Communication (B) |
|-------|:------------:|:-----------:|:----------:|:---------------:|:-----------------:|:-------------------:|:-----------------:|
| P-224 | 4.96 | 0.80 | 2.02 | 1.92 | 2.52 | 1160 | 772 |
| P-256 | 0.36 | 0.48 | 0.95 | 1.32 | 1.65 | 1284 | 864 |

| Curve | Key gen (ms) | Signer (ms) | User (ms) | Verification (ms) | Signature size (B) | Communication (B) |
| ----- | :----------: | :---------: | :-------: | :---------------: | :----------------: | :---------------: |
| P-224 | 0.84 | 1.13 | 1.63 | 0.68 | 324 | 367 |
| P-256 | 0.13 | 0.32 | 0.62 | 0.4 | 360 | 413 |

## Reference
<a id="cn1">1</a>: Baldimtsi, F., & Lysyanskaya, A. (2013). Anonymous credentials light, 1087–1098. https://doi.org/10.1145/2508859.2516687

<a id="cn2">2</a>: Benhamouda F, Lepoint T, Loss J, Orrù M, Raykova M. On the (in) security of ROS. EuroCrypt 2021

Expand Down
58 changes: 0 additions & 58 deletions docs/examples.py
Original file line number Diff line number Diff line change
@@ -1,42 +1,9 @@
from petlib.bn import Bn

from sscred.commitment import *
from sscred.blind_pedersen import *
from sscred.blind_signature import *
from sscred.acl import *
from sscred.pack import *


def pederson_commitment_example():
values = [Bn(2651), Bn(1), Bn(98)]
pparam = PedersenParameters(hs_size=len(values))
pcommit, prand = pparam.commit(values)

# reveal the opening
valid = pcommit.verify(pparam, prand, values)
assert valid

# Prove the knowledge of opening with a nzkp
proof = pcommit.prove_knowledge(pparam, prand, values)
valid = pcommit.verify_proof(pparam, proof)
print(valid)


def blinded_pederson_commitment_example():
values = [Bn(123), Bn(456), "hello", b"world"]
param = BlindedPedersenParam(hs_size=len(values))

# reveal nothing
bcommit, bpriv = param.blind_commit(values)
bproof = bcommit.prove_values(bpriv)
assert bcommit.verify_proof(param, bproof)

# revealing some values
bproof2 = bcommit.prove_values(bpriv, reveal_mask=[True, False, True, True])
assert bcommit.verify_proof(param, bproof)
print(bproof2.revealed_values)


def blind_signature_example():
# generating keys and wrappers
priv, pk = AbeParam().generate_new_key_pair()
Expand All @@ -55,28 +22,6 @@ def blind_signature_example():
print(sig.message)


def acl_example():
# generating keys and wrappers
issuer_priv, issuer_pk = ACLParam().generate_new_key_pair()
issuer = ACLIssuer(issuer_priv, issuer_pk)
user = ACLUser(issuer_pk)
message = "Hello world"

# Issuance
attributes = [Bn(13), "Hello", "WoRlD", "Hidden"]
attr_proof = user.prove_attr_knowledge(attributes)
com, com_params = issuer.commit(attr_proof)
challenge, challenge_params = user.compute_blind_challenge(com, message)
resp = issuer.respond(challenge, com_params)
cred_private = user.compute_credential(resp, challenge_params)

# show credential
cred = cred_private.show_credential([True, True, True, False])
assert cred.verify_credential(issuer_pk)
print(cred.message())
print(cred.attributes())


def pack_example():
priv, pk = AbeParam().generate_new_key_pair()
signer = AbeSigner(priv, pk)
Expand Down Expand Up @@ -108,10 +53,7 @@ def pack_example():


def main():
pederson_commitment_example()
blinded_pederson_commitment_example()
blind_signature_example()
acl_example()
pack_example()


Expand Down
Loading