Index: third_party/tlslite/tlslite/utils/p256.py |
diff --git a/third_party/tlslite/tlslite/utils/p256.py b/third_party/tlslite/tlslite/utils/p256.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..6eb9a7799accc409fbeb88d9873c199ce8864d94 |
--- /dev/null |
+++ b/third_party/tlslite/tlslite/utils/p256.py |
@@ -0,0 +1,162 @@ |
+# Author: Google |
+# See the LICENSE file for legal information regarding use of this file. |
+ |
+import os |
+ |
+p = ( |
+ 115792089210356248762697446949407573530086143415290314195533631308867097853951) |
+order = ( |
+ 115792089210356248762697446949407573529996955224135760342422259061068512044369) |
+p256B = 0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b |
+ |
+baseX = 0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296 |
+baseY = 0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5 |
+basePoint = (baseX, baseY) |
+ |
+ |
+def _pointAdd(a, b): |
+ Z1Z1 = (a[2] * a[2]) % p |
+ Z2Z2 = (b[2] * b[2]) % p |
+ U1 = (a[0] * Z2Z2) % p |
+ U2 = (b[0] * Z1Z1) % p |
+ S1 = (a[1] * b[2] * Z2Z2) % p |
+ S2 = (b[1] * a[2] * Z1Z1) % p |
+ if U1 == U2 and S1 == S2: |
+ return pointDouble(a) |
+ H = (U2 - U1) % p |
+ I = (4 * H * H) % p |
+ J = (H * I) % p |
+ r = (2 * (S2 - S1)) % p |
+ V = (U1 * I) % p |
+ X3 = (r * r - J - 2 * V) % p |
+ Y3 = (r * (V - X3) - 2 * S1 * J) % p |
+ Z3 = (((a[2] + b[2]) * (a[2] + b[2]) - Z1Z1 - Z2Z2) * H) % p |
+ |
+ return (X3, Y3, Z3) |
+ |
+ |
+def _pointDouble(a): |
+ delta = (a[2] * a[2]) % p |
+ gamma = (a[1] * a[1]) % p |
+ beta = (a[0] * gamma) % p |
+ alpha = (3 * (a[0] - delta) * (a[0] + delta)) % p |
+ X3 = (alpha * alpha - 8 * beta) % p |
+ Z3 = ((a[1] + a[2]) * (a[1] + a[2]) - gamma - delta) % p |
+ Y3 = (alpha * (4 * beta - X3) - 8 * gamma * gamma) % p |
+ |
+ return (X3, Y3, Z3) |
+ |
+ |
+def _square(n): |
+ return (n * n) |
+ |
+ |
+def _modpow(a, n, p): |
+ if n == 0: |
+ return 1 |
+ if n == 1: |
+ return a |
+ r = _square(_modpow(a, n >> 1, p)) % p |
+ if n & 1 == 1: |
+ r = (r * a) % p |
+ return r |
+ |
+ |
+def _scalarMult(k, point): |
+ accum = (0, 0, 0) |
+ accumIsInfinity = True |
+ jacobianPoint = (point[0], point[1], 1) |
+ |
+ for bit in range(255, -1, -1): |
+ if not accumIsInfinity: |
+ accum = _pointDouble(accum) |
+ |
+ if (k >> bit) & 1 == 1: |
+ if accumIsInfinity: |
+ accum = jacobianPoint |
+ accumIsInfinity = False |
+ else: |
+ accum = _pointAdd(accum, jacobianPoint) |
+ |
+ if accumIsInfinity: |
+ return (0, 0) |
+ |
+ zInv = _modpow(accum[2], p - 2, p) |
+ return ((accum[0] * zInv * zInv) % p, (accum[1] * zInv * zInv * zInv) % p) |
+ |
+ |
+def _scalarBaseMult(k): |
+ return _scalarMult(k, basePoint) |
+ |
+ |
+def _decodeBigEndian(b): |
+ return sum([ord(b[len(b) - i - 1]) << 8 * i for i in range(len(b))]) |
+ |
+ |
+def _encodeBigEndian(n): |
+ b = [] |
+ while n != 0: |
+ b.append(chr(n & 0xff)) |
+ n >>= 8 |
+ |
+ if len(b) == 0: |
+ b.append(0) |
+ b.reverse() |
+ |
+ return "".join(b) |
+ |
+ |
+def _zeroPad(b, length): |
+ if len(b) < length: |
+ return ("\x00" * (length - len(b))) + b |
+ return b |
+ |
+ |
+def _encodePoint(point): |
+ x = point[0] |
+ y = point[1] |
+ if (y * y) % p != (x * x * x - 3 * x + p256B) % p: |
+ raise "point not on curve" |
+ return "\x04" + _zeroPad(_encodeBigEndian(point[0]), 32) + _zeroPad( |
+ _encodeBigEndian(point[1]), 32) |
+ |
+ |
+def _decodePoint(b): |
+ if len(b) != 1 + 32 + 32 or ord(b[0]) != 4: |
+ raise "invalid encoded ec point" |
+ x = _decodeBigEndian(b[1:33]) |
+ y = _decodeBigEndian(b[33:65]) |
+ if (y * y) % p != (x * x * x - 3 * x + p256B) % p: |
+ raise "point not on curve" |
+ return (x, y) |
+ |
+ |
+def generatePublicPrivate(): |
+ """generatePublicPrivate returns a tuple of (X9.62 encoded public point, |
+ private value), where the private value is generated from os.urandom.""" |
+ private = _decodeBigEndian(os.urandom(40)) % order |
+ return _encodePoint(_scalarBaseMult(private)), private |
+ |
+ |
+def generateSharedValue(theirPublic, private): |
+ """generateSharedValue returns the encoded x-coordinate of the |
+ multiplication of a peer's X9.62 encoded point and a private value.""" |
+ return _zeroPad( |
+ _encodeBigEndian(_scalarMult(private, _decodePoint(theirPublic))[0]), |
+ 32) |
+ |
+if __name__ == "__main__": |
+ alice, alicePrivate = generatePublicPrivate() |
+ bob, bobPrivate = generatePublicPrivate() |
+ |
+ if generateSharedValue(alice, bobPrivate) != generateSharedValue( |
+ bob, alicePrivate): |
+ raise "simple DH test failed" |
+ |
+ (x, _) = _scalarBaseMult(1) |
+ |
+ for i in range(1000): |
+ (x, _) = _scalarBaseMult(x) |
+ |
+ if x != 2428281965257598569040586318034812501729437946720808289049534492833635302706: |
+ raise "loop test failed" |