Skip to content

Commit 0d7d83a

Browse files
authored
Merge pull request #277 from oauth-wg/276-size-comparison
size comparison
2 parents 026614e + 299d671 commit 0d7d83a

File tree

6 files changed

+108
-6
lines changed

6 files changed

+108
-6
lines changed

.github/workflows/ghpages.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ jobs:
3131
- name: "Generate examples"
3232
run: |
3333
npm install -g cborg
34-
python3 -m pip install --upgrade pip wheel setuptools
34+
python3 -m pip install --upgrade pip wheel setuptools==76.1.0
3535
python3 -m pip install -r src/requirements.txt
3636
python3 src/main.py
3737

.github/workflows/publish.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ jobs:
3030
- name: "Generate examples"
3131
run: |
3232
npm install -g cborg
33-
python3 -m pip install --upgrade pip wheel setuptools
33+
python3 -m pip install --upgrade pip wheel setuptools==76.1.0
3434
python3 -m pip install -r src/requirements.txt
3535
python3 src/main.py
3636

draft-ietf-oauth-status-list.md

+29-1
Original file line numberDiff line numberDiff line change
@@ -844,7 +844,7 @@ An Issuer MAY support any of these mechanisms:
844844
- Issuer metadata: The Issuer of the Referenced Token publishes an URI which links to Status List Aggregation, e.g. in publicly available metadata of an issuance protocol
845845
- Status List Parameter: The Status Issuer includes an additional claim in the Status List Token that contains the Status List Aggregation URI.
846846

847-
~~~ ascii art
847+
~~~ ascii-art
848848
┌─────────────────┐
849849
│ │
850850
│ Issuer Metadata │
@@ -1453,6 +1453,33 @@ Torsten Lodderstedt
14531453

14541454
for their valuable contributions, discussions and feedback to this specification.
14551455

1456+
# Size comparison {#size-comparison}
1457+
{:unnumbered}
1458+
1459+
The following tables show a size comparison for a Status List (compressed byte array as defined in [](#status-list-byte-array) and a compressed Byte Array of UUIDs (as an approximation for a Certificate Revocation List). Readers must be aware that these are not sizes for complete Status List Tokens in JSON/CBOR nor Certificate Revocation Lists (CRLs), as they don't contain metadata, certificates and signatures.
1460+
1461+
## Status List size for varying sizes and revocation rates
1462+
{:unnumbered}
1463+
1464+
| Size | 0.01% | 0.1% | 1% | 2% | 5% | 10% | 25% | 50% | 75% | 100% |
1465+
| 100k | 81 B | 252 B | 1.4 KB | 2.3 KB | 4.5 KB | 6.9 KB | 10.2 KB | 12.2 KB | 10.2 KB | 35 B |
1466+
| 1M | 442 B | 2.2 KB | 13.7 KB | 23.0 KB | 43.9 KB | 67.6 KB | 102.2 KB | 122.1 KB | 102.4 KB | 144 B |
1467+
| 10M | 3.8 KB | 21.1 KB | 135.4 KB | 230.0 KB | 437.0 KB | 672.9 KB | 1023.4 KB | 1.2 MB | 1023.5 KB | 1.2 KB |
1468+
| 100M | 38.3 KB | 213.0 KB | 1.3 MB | 2.2 MB | 4.3 MB | 6.6 MB | 10.0 MB | 11.9 MB | 10.0 MB | 11.9 KB |
1469+
{: title="Status List Size examples for varying sizes and revocation rates"}
1470+
1471+
## Compressed array of UUIDv4 (128 bit UUIDs) for varying sizes and revocation rates
1472+
{:unnumbered}
1473+
1474+
This is a simple approximation of a Certificate Revocation List using an array of UUIDs without any additional metadata (128 bit UUID per revoked entry).
1475+
1476+
| Size | 0.01% | 0.1% | 1% | 2% | 5% | 10% | 25% | 50% | 75% | 100% |
1477+
| 100k | 219 B | 1.6 KB | 15.4 KB | 29.7 KB | 78.1 KB | 154.9 KB | 392.9 KB | 783.1 KB | 1.1 MB | 1.5 MB |
1478+
| 1M | 1.6 KB | 16.4 KB | 157.7 KB | 310.4 KB | 781 KB | 1.5 MB | 3.8 MB | 7.6 MB | 11.4 MB | 15.3 MB |
1479+
| 10M | 15.3 KB | 155.9 KB | 1.5 MB | 3.1 MB | 7.6 MB | 15.2 MB | 38.2 MB | 76.3 MB | 114.4 MB | 152.6 MB |
1480+
| 100M | 157.6 KB | 1.5 MB | 15.3 MB | 30.5 MB | 76.3 MB | 152.6 MB | 381.4 MB | 762.9 MB | 1.1 GB | 1.5 GB |
1481+
{: title="Size examples for 128 bit UUIDs for varying sizes and revocation rates"}
1482+
14561483
# Test vectors for Status List encoding {#test-vectors}
14571484
{:unnumbered}
14581485

@@ -1839,6 +1866,7 @@ CBOR encoding:
18391866

18401867
-10
18411868

1869+
* Add size comparison for status list and compressed uuids
18421870
* Change Controller IESG for OAuths Parameters Registration
18431871

18441872
-09

src/bench.py

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import math
2+
import zlib
3+
from random import choices
4+
from uuid import uuid4
5+
6+
from py_markdown_table.markdown_table import markdown_table
7+
8+
from status_list import StatusList
9+
10+
11+
def display_size(size_bytes):
12+
if size_bytes == 0:
13+
return "0B"
14+
size_name = ("B", "KB", "MB", "GB")
15+
floored = int(math.floor(math.log(size_bytes, 1024)))
16+
p = math.pow(1024, floored)
17+
rounded = round(size_bytes / p, 1)
18+
return "%s %s" % (rounded, size_name[floored])
19+
20+
21+
sizes = [100000, 1000000, 10000000, 100000000]
22+
rev_rates = [0.0001, 0.001, 0.01, 0.02, 0.05, 0.1, 0.25, 0.5, 0.75, 1]
23+
24+
data_sl = []
25+
data_uuid = []
26+
27+
for size in sizes:
28+
newdata_sl = {"size": size}
29+
newdata_uuid = {"size": size}
30+
for rev_rate in rev_rates:
31+
print(f"Revocation Rate: {rev_rate}")
32+
vals = [0, 1]
33+
p = [1 - rev_rate, rev_rate]
34+
sample = choices(population=vals, weights=p, k=size)
35+
36+
statuslist = StatusList(size, 1)
37+
idlist = bytearray()
38+
for idx, val in enumerate(sample):
39+
statuslist.set(idx, val)
40+
if val == 1:
41+
idlist.extend(uuid4().bytes)
42+
43+
rawsl = statuslist.encodeAsBytes()
44+
rawidlist = zlib.compress(idlist, level=9)
45+
46+
percentage = str(rev_rate * 100) + "%"
47+
newdata_sl[percentage] = display_size(len(rawsl))
48+
newdata_uuid[percentage] = display_size(len(rawidlist))
49+
print(f"Size in Bytes: {display_size(len(rawsl))}")
50+
print(f"Size in Bytes uuid: {display_size(len(rawidlist))}")
51+
data_sl.append(newdata_sl)
52+
data_uuid.append(newdata_uuid)
53+
54+
markdown_sl = (
55+
markdown_table(data_sl)
56+
.set_params(
57+
padding_width=3,
58+
padding_weight="centerleft",
59+
)
60+
.get_markdown()
61+
)
62+
print(markdown_sl)
63+
markdown_uuid = (
64+
markdown_table(data_uuid)
65+
.set_params(
66+
padding_width=3,
67+
padding_weight="centerleft",
68+
)
69+
.get_markdown()
70+
)
71+
print(markdown_uuid)

src/requirements.txt

+1
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ git+https://github.com/wbond/oscrypto.git@1547f535001ba568b239b8797465536759c742
44
jwcrypto==1.5.6
55
cbor2==5.6.2
66
cwt==2.7.4
7+
py_markdown_table==1.3.0

src/status_list.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
import math
12
import zlib
23
from base64 import urlsafe_b64decode, urlsafe_b64encode
34
from typing import Dict
45

56
from cbor2 import dumps, loads
67

8+
LEVEL=9
79

810
class StatusList:
911
list: bytearray
@@ -13,7 +15,7 @@ class StatusList:
1315

1416
def __init__(self, size: int, bits: int):
1517
self.divisor = 8 // bits
16-
self.list = bytearray([0] * (size // self.divisor))
18+
self.list = bytearray([0] * math.ceil(size / self.divisor))
1719
self.bits = bits
1820
self.size = size
1921

@@ -24,11 +26,11 @@ def fromEncoded(cls, encoded: str, bits: int = 1):
2426
return new
2527

2628
def encodeAsString(self) -> str:
27-
zipped = zlib.compress(self.list, level=9)
29+
zipped = zlib.compress(self.list, level=LEVEL)
2830
return urlsafe_b64encode(zipped).decode().strip("=")
2931

3032
def encodeAsBytes(self) -> bytes:
31-
return zlib.compress(self.list, level=9)
33+
return zlib.compress(self.list, level=LEVEL)
3234

3335
def encodeAsJSON(self) -> Dict:
3436
encoded_list = self.encodeAsString()

0 commit comments

Comments
 (0)