Created
June 16, 2025 15:45
-
-
Save lukehinds/56a80397ba4f908541dabf7ceedd3582 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "code", | |
"execution_count": 1, | |
"id": "fd416903", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"Requirement already satisfied: cbor2 in ./.venv/lib/python3.11/site-packages (5.6.5)\n", | |
"Requirement already satisfied: cose in ./.venv/lib/python3.11/site-packages (0.9.dev8)\n", | |
"Requirement already satisfied: cryptography in ./.venv/lib/python3.11/site-packages (45.0.4)\n", | |
"Requirement already satisfied: ecdsa in ./.venv/lib/python3.11/site-packages (from cose) (0.19.1)\n", | |
"Requirement already satisfied: attrs in ./.venv/lib/python3.11/site-packages (from cose) (25.3.0)\n", | |
"Requirement already satisfied: certvalidator in ./.venv/lib/python3.11/site-packages (from cose) (0.11.1)\n", | |
"Requirement already satisfied: cffi>=1.14 in ./.venv/lib/python3.11/site-packages (from cryptography) (1.17.1)\n", | |
"Requirement already satisfied: pycparser in ./.venv/lib/python3.11/site-packages (from cffi>=1.14->cryptography) (2.22)\n", | |
"Requirement already satisfied: asn1crypto>=0.18.1 in ./.venv/lib/python3.11/site-packages (from certvalidator->cose) (1.5.1)\n", | |
"Requirement already satisfied: oscrypto>=0.16.1 in ./.venv/lib/python3.11/site-packages (from certvalidator->cose) (1.3.0)\n", | |
"Requirement already satisfied: six>=1.9.0 in ./.venv/lib/python3.11/site-packages (from ecdsa->cose) (1.17.0)\n", | |
"\n", | |
"\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m24.3.1\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m25.1.1\u001b[0m\n", | |
"\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n", | |
"Note: you may need to restart the kernel to use updated packages.\n" | |
] | |
} | |
], | |
"source": [ | |
"\n", | |
"%pip install cbor2 cose cryptography\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 2, | |
"id": "8e2ef28a", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"\n", | |
"import json\n", | |
"import base64\n", | |
"import time\n", | |
"import cbor2\n", | |
"\n", | |
"from cryptography.hazmat.primitives.asymmetric import ec\n", | |
"from cryptography.hazmat.primitives import hashes\n", | |
"from cryptography.hazmat.primitives.asymmetric.utils import decode_dss_signature\n", | |
"\n", | |
"from cose.messages import Sign1Message\n", | |
"from cose.keys.ec2 import EC2Key\n", | |
"from cose.algorithms import Es256\n", | |
"from cose.keys.curves import P256\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 3, | |
"id": "186ec0d5", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"\n", | |
"def b64url(data: bytes) -> str:\n", | |
" return base64.urlsafe_b64encode(data).rstrip(b\"=\").decode()\n", | |
"\n", | |
"# Generate EC key\n", | |
"private_key = ec.generate_private_key(ec.SECP256R1())\n", | |
"public_key = private_key.public_key()\n", | |
"numbers = private_key.private_numbers()\n", | |
"pub_numbers = numbers.public_numbers\n", | |
"x = pub_numbers.x.to_bytes(32, byteorder='big')\n", | |
"y = pub_numbers.y.to_bytes(32, byteorder='big')\n", | |
"d = numbers.private_value.to_bytes(32, byteorder='big')\n", | |
"\n", | |
"# Create EC2 COSE key\n", | |
"cose_key = EC2Key(\n", | |
" crv=P256,\n", | |
" x=x,\n", | |
" y=y,\n", | |
" d=d,\n", | |
" optional_params={\"alg\": Es256}\n", | |
")\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 4, | |
"id": "78f5e745", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"\n", | |
"payload = {\n", | |
" \"iss\": \"supply-chain-stuff\",\n", | |
" \"sub\": \"component-123\",\n", | |
" \"event\": \"build\",\n", | |
" \"ts\": \"2025-06-16T00:00:00Z\",\n", | |
" \"metadata\": {\n", | |
" \"version\": \"4.18.7\",\n", | |
" \"build_hash\": \"f3d4a1c2e6b90123aaef0987ddeeccbbf0e4d2e1f54ac9ba7c65db7fa2d3984b\",\n", | |
" \"compiler\": \"gcc 13.2.0\",\n", | |
" \"build_host\": \"ci-builder-12.internal.net\",\n", | |
" \"env\": {\n", | |
" \"GOOS\": \"linux\",\n", | |
" \"GOARCH\": \"amd64\",\n", | |
" \"CGO_ENABLED\": \"1\",\n", | |
" \"LD_LIBRARY_PATH\": \"/usr/local/lib\",\n", | |
" \"PATH\": \"/usr/local/bin:/usr/bin:/bin\"\n", | |
" }\n", | |
" },\n", | |
" \"build_logs\": \"\\n\".join([f\"[INFO] Step {i}: Completed\" for i in range(1, 51)]),\n", | |
" \"dependencies\": [\n", | |
" {\"name\": f\"lib-{i}\", \"version\": f\"{i}.{i+1}.{i+2}\", \"checksum\": f\"sha256:{i*12345:x}...\"}\n", | |
" for i in range(50)\n", | |
" ],\n", | |
" \"attestation\": {\n", | |
" \"provenance\": {\n", | |
" \"builder\": \"GitHub Actions\",\n", | |
" \"repo\": \"github.com/example/project\",\n", | |
" \"commit\": \"c0ffee1234badcafe123\",\n", | |
" \"workflow\": \"build-and-test.yml\",\n", | |
" \"trigger\": \"push\"\n", | |
" },\n", | |
" \"signing_policy\": \"strict\",\n", | |
" \"expires\": \"2026-06-16T00:00:00Z\"\n", | |
" }\n", | |
"}\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 5, | |
"id": "145d458c", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"\n", | |
"# COSE Signing\n", | |
"start_cose = time.time()\n", | |
"msg = Sign1Message(phdr={\"alg\": Es256}, payload=cbor2.dumps(payload))\n", | |
"msg.key = cose_key\n", | |
"signed_cose = msg.encode()\n", | |
"end_cose = time.time()\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 6, | |
"id": "052b4014", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"\n", | |
"# JWT Signing (Sigstore-style)\n", | |
"header = {\"alg\": \"ES256\", \"typ\": \"JWT\"}\n", | |
"b64_header = b64url(json.dumps(header, separators=(\",\", \":\")).encode())\n", | |
"b64_payload = b64url(json.dumps(payload, separators=(\",\", \":\")).encode())\n", | |
"signing_input = f\"{b64_header}.{b64_payload}\".encode()\n", | |
"\n", | |
"start_jwt = time.time()\n", | |
"signature = private_key.sign(signing_input, ec.ECDSA(hashes.SHA256()))\n", | |
"r, s = decode_dss_signature(signature)\n", | |
"raw_signature = r.to_bytes(32, \"big\") + s.to_bytes(32, \"big\")\n", | |
"b64_signature = b64url(raw_signature)\n", | |
"jwt_token = f\"{b64_header}.{b64_payload}.{b64_signature}\"\n", | |
"end_jwt = time.time()\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 7, | |
"id": "bdeba35d", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"Comparison Results\n", | |
"---------------------\n", | |
"Original Payload Size (JSON): 5709\n", | |
"Signed COSE Size (bytes): 4648\n", | |
"Signed JWT Size (bytes): 7275\n", | |
"Size Difference (%): 56.52\n", | |
"COSE Signing Time (s): 0.011529\n", | |
"JWT Signing Time (s): 0.001421\n" | |
] | |
} | |
], | |
"source": [ | |
"\n", | |
"print(\"Comparison Results\")\n", | |
"print(\"---------------------\")\n", | |
"print(\"Original Payload Size (JSON):\", len(json.dumps(payload)))\n", | |
"print(\"Signed COSE Size (bytes):\", len(signed_cose))\n", | |
"print(\"Signed JWT Size (bytes):\", len(jwt_token.encode()))\n", | |
"print(\"Size Difference (%):\", round((len(jwt_token.encode()) - len(signed_cose)) / len(signed_cose) * 100, 2))\n", | |
"print(\"COSE Signing Time (s):\", round(end_cose - start_cose, 6))\n", | |
"print(\"JWT Signing Time (s):\", round(end_jwt - start_jwt, 6))\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "edecc384", | |
"metadata": {}, | |
"outputs": [], | |
"source": [] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": ".venv", | |
"language": "python", | |
"name": "python3" | |
}, | |
"language_info": { | |
"codemirror_mode": { | |
"name": "ipython", | |
"version": 3 | |
}, | |
"file_extension": ".py", | |
"mimetype": "text/x-python", | |
"name": "python", | |
"nbconvert_exporter": "python", | |
"pygments_lexer": "ipython3", | |
"version": "3.11.11" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 5 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment