From c73a705807a692c627d02bc94d9e73e8aca2511b Mon Sep 17 00:00:00 2001 From: Jussi Kukkonen Date: Mon, 2 Nov 2020 17:11:47 +0200 Subject: [PATCH 1/4] ed25519: Update to upstream master HEAD Update ed2519 from 18d0b5515 to c13748e1d2. This includes three commits that * fixes invalid escape sequence in docstring (our issue #290) * updates CI, lint & tox configuration (not included in our copy) * whitespace fixes to satisfy the new linter configuration So no functional changes but the first item should silence a DeprecationWarning in some cases. Fixes #298 --- securesystemslib/_vendor/ed25519/.gitignore | 2 + securesystemslib/_vendor/ed25519/README.rst | 4 +- securesystemslib/_vendor/ed25519/__init__.py | 0 securesystemslib/_vendor/ed25519/ed25519.py | 100 ++++++++++-------- securesystemslib/_vendor/ed25519/science.py | 2 +- .../_vendor/ed25519/test_ed25519.py | 10 +- 6 files changed, 67 insertions(+), 51 deletions(-) delete mode 100644 securesystemslib/_vendor/ed25519/__init__.py diff --git a/securesystemslib/_vendor/ed25519/.gitignore b/securesystemslib/_vendor/ed25519/.gitignore index 0d20b648..bfd157a0 100644 --- a/securesystemslib/_vendor/ed25519/.gitignore +++ b/securesystemslib/_vendor/ed25519/.gitignore @@ -1 +1,3 @@ *.pyc +.tox +*.egg-info diff --git a/securesystemslib/_vendor/ed25519/README.rst b/securesystemslib/_vendor/ed25519/README.rst index 39f4e8c0..3f3ead60 100644 --- a/securesystemslib/_vendor/ed25519/README.rst +++ b/securesystemslib/_vendor/ed25519/README.rst @@ -1,8 +1,8 @@ ed25519 ======= -.. image:: https://travis-ci.org/pyca/ed25519.png?branch=master - :target: https://travis-ci.org/pyca/ed25519 +.. image:: https://github.com/pyca/ed25519/workflows/CI/badge.svg + :target: https://github.com/pyca/ed25519/actions?query=workflow%3ACI `Ed25519 `_ is a high-speed public-key signature system. ``ed25519.py`` is based on the original Python diff --git a/securesystemslib/_vendor/ed25519/__init__.py b/securesystemslib/_vendor/ed25519/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/securesystemslib/_vendor/ed25519/ed25519.py b/securesystemslib/_vendor/ed25519/ed25519.py index be6d833b..06e3c4d6 100644 --- a/securesystemslib/_vendor/ed25519/ed25519.py +++ b/securesystemslib/_vendor/ed25519/ed25519.py @@ -47,7 +47,7 @@ int2byte = operator.methodcaller("to_bytes", 1, "big") else: int2byte = chr - range = xrange + range = xrange # noqa: F821 def indexbytes(buf, i): return ord(buf[i]) @@ -74,20 +74,20 @@ def pow2(x, p): def inv(z): - """$= z^{-1} \mod q$, for z != 0""" + r"""$= z^{-1} \mod q$, for z != 0""" # Adapted from curve25519_athlon.c in djb's Curve25519. - z2 = z * z % q # 2 - z9 = pow2(z2, 2) * z % q # 9 - z11 = z9 * z2 % q # 11 - z2_5_0 = (z11 * z11) % q * z9 % q # 31 == 2^5 - 2^0 - z2_10_0 = pow2(z2_5_0, 5) * z2_5_0 % q # 2^10 - 2^0 - z2_20_0 = pow2(z2_10_0, 10) * z2_10_0 % q # ... + z2 = z * z % q # 2 + z9 = pow2(z2, 2) * z % q # 9 + z11 = z9 * z2 % q # 11 + z2_5_0 = (z11 * z11) % q * z9 % q # 31 == 2^5 - 2^0 + z2_10_0 = pow2(z2_5_0, 5) * z2_5_0 % q # 2^10 - 2^0 + z2_20_0 = pow2(z2_10_0, 10) * z2_10_0 % q # ... z2_40_0 = pow2(z2_20_0, 20) * z2_20_0 % q z2_50_0 = pow2(z2_40_0, 10) * z2_10_0 % q z2_100_0 = pow2(z2_50_0, 50) * z2_50_0 % q z2_200_0 = pow2(z2_100_0, 100) * z2_100_0 % q - z2_250_0 = pow2(z2_200_0, 50) * z2_50_0 % q # 2^250 - 2^0 - return pow2(z2_250_0, 5) * z11 % q # 2^255 - 2^5 + 11 = q - 2 + z2_250_0 = pow2(z2_200_0, 50) * z2_50_0 % q # 2^250 - 2^0 + return pow2(z2_250_0, 5) * z11 % q # 2^255 - 2^5 + 11 = q - 2 d = -121665 * inv(121666) % q @@ -102,7 +102,7 @@ def xrecover(y): x = (x * I) % q if x % 2 != 0: - x = q-x + x = q - x return x @@ -119,18 +119,18 @@ def edwards_add(P, Q): (x1, y1, z1, t1) = P (x2, y2, z2, t2) = Q - a = (y1-x1)*(y2-x2) % q - b = (y1+x1)*(y2+x2) % q - c = t1*2*d*t2 % q - dd = z1*2*z2 % q + a = (y1 - x1) * (y2 - x2) % q + b = (y1 + x1) * (y2 + x2) % q + c = t1 * 2 * d * t2 % q + dd = z1 * 2 * z2 % q e = b - a f = dd - c g = dd + c h = b + a - x3 = e*f - y3 = g*h - t3 = e*h - z3 = f*g + x3 = e * f + y3 = g * h + t3 = e * h + z3 = f * g return (x3 % q, y3 % q, z3 % q, t3 % q) @@ -140,18 +140,18 @@ def edwards_double(P): # http://www.hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html (x1, y1, z1, t1) = P - a = x1*x1 % q - b = y1*y1 % q - c = 2*z1*z1 % q + a = x1 * x1 % q + b = y1 * y1 % q + c = 2 * z1 * z1 % q # dd = -a - e = ((x1+y1)*(x1+y1) - a - b) % q + e = ((x1 + y1) * (x1 + y1) - a - b) % q g = -a + b # dd + b f = g - c h = -a - b # dd - b - x3 = e*f - y3 = g*h - t3 = e*h - z3 = f*g + x3 = e * f + y3 = g * h + t3 = e * h + z3 = f * g return (x3 % q, y3 % q, z3 % q, t3 % q) @@ -175,6 +175,8 @@ def make_Bpow(): for i in range(253): Bpow.append(P) P = edwards_double(P) + + make_Bpow() @@ -195,10 +197,12 @@ def scalarmult_B(e): def encodeint(y): bits = [(y >> i) & 1 for i in range(b)] - return b''.join([ - int2byte(sum([bits[i * 8 + j] << j for j in range(8)])) - for i in range(b//8) - ]) + return b"".join( + [ + int2byte(sum([bits[i * 8 + j] << j for j in range(8)])) + for i in range(b // 8) + ] + ) def encodepoint(P): @@ -207,10 +211,12 @@ def encodepoint(P): x = (x * zi) % q y = (y * zi) % q bits = [(y >> i) & 1 for i in range(b - 1)] + [x & 1] - return b''.join([ - int2byte(sum([bits[i * 8 + j] << j for j in range(8)])) - for i in range(b // 8) - ]) + return b"".join( + [ + int2byte(sum([bits[i * 8 + j] << j for j in range(8)])) + for i in range(b // 8) + ] + ) def bit(h, i): @@ -252,9 +258,11 @@ def signature_unsafe(m, sk, pk): def isoncurve(P): (x, y, z, t) = P - return (z % q != 0 and - x*y % q == z*t % q and - (y*y - x*x - z*z - d*t*t) % q == 0) + return ( + z % q != 0 + and x * y % q == z * t % q + and (y * y - x * x - z * z - d * t * t) % q == 0 + ) def decodeint(s): @@ -264,9 +272,9 @@ def decodeint(s): def decodepoint(s): y = sum(2 ** i * bit(s, i) for i in range(0, b - 1)) x = xrecover(y) - if x & 1 != bit(s, b-1): + if x & 1 != bit(s, b - 1): x = q - x - P = (x, y, 1, (x*y) % q) + P = (x, y, 1, (x * y) % q) if not isoncurve(P): raise ValueError("decoding point that is not on curve") return P @@ -289,14 +297,18 @@ def checkvalid(s, m, pk): if len(pk) != b // 8: raise ValueError("public-key length is wrong") - R = decodepoint(s[:b // 8]) + R = decodepoint(s[: b // 8]) A = decodepoint(pk) - S = decodeint(s[b // 8:b // 4]) + S = decodeint(s[b // 8 : b // 4]) h = Hint(encodepoint(R) + pk + m) (x1, y1, z1, t1) = P = scalarmult_B(S) (x2, y2, z2, t2) = Q = edwards_add(R, scalarmult(A, h)) - if (not isoncurve(P) or not isoncurve(Q) or - (x1*z2 - x2*z1) % q != 0 or (y1*z2 - y2*z1) % q != 0): + if ( + not isoncurve(P) + or not isoncurve(Q) + or (x1 * z2 - x2 * z1) % q != 0 + or (y1 * z2 - y2 * z1) % q != 0 + ): raise SignatureMismatch("signature does not pass verification") diff --git a/securesystemslib/_vendor/ed25519/science.py b/securesystemslib/_vendor/ed25519/science.py index 1ed6a1a6..a72efe46 100644 --- a/securesystemslib/_vendor/ed25519/science.py +++ b/securesystemslib/_vendor/ed25519/science.py @@ -25,7 +25,7 @@ public_key = ed25519.publickey_unsafe(seed) signature = ed25519.signature_unsafe(data, private_key, public_key) -print('\nTime verify signature') +print("\nTime verify signature") print( timeit.timeit( "ed25519.checkvalid(signature, data, public_key)", diff --git a/securesystemslib/_vendor/ed25519/test_ed25519.py b/securesystemslib/_vendor/ed25519/test_ed25519.py index 20252744..3a012a48 100644 --- a/securesystemslib/_vendor/ed25519/test_ed25519.py +++ b/securesystemslib/_vendor/ed25519/test_ed25519.py @@ -75,10 +75,12 @@ def test_ed25519_kat(secret_key, public_key, message, signed, signature): if len(m) == 0: forgedm = b"x" else: - forgedm = ed25519.intlist2bytes([ - ed25519.indexbytes(m, i) + (i == len(m) - 1) - for i in range(len(m)) - ]) + forgedm = ed25519.intlist2bytes( + [ + ed25519.indexbytes(m, i) + (i == len(m) - 1) + for i in range(len(m)) + ] + ) except ValueError: # TODO: Yes this means that we "pass" a test if we can't generate a # forged message. This matches the original test suite, it's From f2267589017a80438cf8c70874dad94dea02b832 Mon Sep 17 00:00:00 2001 From: Jussi Kukkonen Date: Mon, 2 Nov 2020 18:35:04 +0200 Subject: [PATCH 2/4] test-ed25519-upstream.sh: Update expected hash --- securesystemslib/_vendor/test-ed25519-upstream.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/securesystemslib/_vendor/test-ed25519-upstream.sh b/securesystemslib/_vendor/test-ed25519-upstream.sh index 186cd0f8..c20d8f57 100755 --- a/securesystemslib/_vendor/test-ed25519-upstream.sh +++ b/securesystemslib/_vendor/test-ed25519-upstream.sh @@ -12,7 +12,7 @@ set -eu # This commit matches our securesystemslib/_vendor/ed25519/ content. # If upstream changes, we should review the changes, vendor them, # and update the hash here -pyca_ed25519_expected="18d0b5515c8bda6bab0148f1946845bf3027bc4f" +pyca_ed25519_expected="c13748e1d24c5c00f6ce2b9c38a319ae02355d97" pyca_ed25519_git_url="https://github.com/pyca/ed25519.git" pyca_ed25519_master_head=$(git ls-remote "$pyca_ed25519_git_url" master | cut -f1) From 95524ad8c526a9ba6ed1c333bf1a7664e7c8e86d Mon Sep 17 00:00:00 2001 From: Jussi Kukkonen Date: Tue, 3 Nov 2020 10:15:28 +0200 Subject: [PATCH 3/4] ed25519: Fix the "update process" and contents * Add advice on updating * Add __init__.py that was mistakenly removed in commit c73a705 (this file is not part of upstream, it is added in securesystemslib) * Delete Travis config as it was actually deleted upstream --- securesystemslib/_vendor/README.md | 17 ++++++++++++ securesystemslib/_vendor/ed25519/.travis.yml | 28 -------------------- securesystemslib/_vendor/ed25519/__init__.py | 0 3 files changed, 17 insertions(+), 28 deletions(-) create mode 100644 securesystemslib/_vendor/README.md delete mode 100644 securesystemslib/_vendor/ed25519/.travis.yml create mode 100644 securesystemslib/_vendor/ed25519/__init__.py diff --git a/securesystemslib/_vendor/README.md b/securesystemslib/_vendor/README.md new file mode 100644 index 00000000..e6c8ec53 --- /dev/null +++ b/securesystemslib/_vendor/README.md @@ -0,0 +1,17 @@ +## Updating ed25519 + +ed25519 is a vendored copy of https://github.com/pyca/ed25519. Here's +one way to update the vendored copy: +```bash +cd securesystemslib/_vendor +rm -rf ed25519/ +git clone git@github.com:pyca/ed25519.git +touch ed25519/__init__.py # needed by python<3.3 +git clean -f ed25519/ +git commit -a +``` + +Note that this does not commit any new files (our copy does not include +all of the upstream files). Remember to update the expected upstream +hash in `test-ed25519-upstream.sh`. + diff --git a/securesystemslib/_vendor/ed25519/.travis.yml b/securesystemslib/_vendor/ed25519/.travis.yml deleted file mode 100644 index 8518ca28..00000000 --- a/securesystemslib/_vendor/ed25519/.travis.yml +++ /dev/null @@ -1,28 +0,0 @@ -language: python -python: 2.7 -env: - - TOXENV=py26 - - TOXENV=py27 - #- TOXENV=py32 - #- TOXENV=py33 - - TOXENV=pypy - -install: - # Add the PyPy repository - - "if [[ $TOXENV == 'pypy' ]]; then sudo add-apt-repository -y ppa:pypy/ppa; fi" - # Upgrade PyPy - - "if [[ $TOXENV == 'pypy' ]]; then sudo apt-get -y install pypy; fi" - # This is required because we need to get rid of the Travis installed PyPy - # or it'll take precedence over the PPA installed one. - - "if [[ $TOXENV == 'pypy' ]]; then sudo rm -rf /usr/local/pypy/bin; fi" - - pip install tox - -script: - - tox - -notifications: - irc: - channels: - - "irc.freenode.org#cryptography-dev" - use_notice: true - skip_join: true diff --git a/securesystemslib/_vendor/ed25519/__init__.py b/securesystemslib/_vendor/ed25519/__init__.py new file mode 100644 index 00000000..e69de29b From aa6d87624ab1deaf7f2117b72cf28f1c3671cefa Mon Sep 17 00:00:00 2001 From: Jussi Kukkonen Date: Thu, 5 Nov 2020 15:29:30 +0200 Subject: [PATCH 4/4] Make _vendor/README.md more explicit about new files Co-authored-by: Joshua Lock --- securesystemslib/_vendor/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/securesystemslib/_vendor/README.md b/securesystemslib/_vendor/README.md index e6c8ec53..5e3d2d02 100644 --- a/securesystemslib/_vendor/README.md +++ b/securesystemslib/_vendor/README.md @@ -12,6 +12,6 @@ git commit -a ``` Note that this does not commit any new files (our copy does not include -all of the upstream files). Remember to update the expected upstream +all of the upstream files), any new implementation files will need to be +`git add`ed before commit. Remember to update the expected upstream hash in `test-ed25519-upstream.sh`. -