X448 (Curve 448)X448 is based on Curve 448, and is used for key exchange with ECDH (Elliptic Curve Diffie Hellman). It supports a 224-bit security level, and where we use a 448-bit (56-byte) prime number of \(P = 2^{448} - 2^{224} - 1\). It has improved security over Curve 25519, and which has a 255-bit prime number (\(P = 2^{255} - 19\)). As with X25519, in X448 we use a Montgomery curve (\(v^2 = u^3 + A \times u^2 + u\)) with scalar multiplication. In X448, we use 56-byte string values, rather than 32-byte values for X25519. Overall, X448 uses a little-endian method to store an array of bytes, and has a value of \(A = 39,081\) [X25519] [X448 Golang]. OutlineX448 is based on Curve 448, and is used for key exchange with ECDH (Elliptic Curve Diffie Hellman). It supports a 224-bit security level, and where we use a 448-bit (56-byte) prime number of \(P = 2^{448} - 2^{224} - 1\). It has improved security over Curve 25519, and which has a 255-bit prime number (\(P = 2^{255} - 19\)). As with X25519, in X448 we use a Montgomery curve (\(v^2 = u^3 + A \times u^2 + u\)) with scalar multiplication. In X448, we use 56-byte string values, rather than 32-byte values for X25519. Overall, X448 uses a little-endian method to store an array of bytes, and has a value of \(A = 39,081\). The paramaters based by on RFC 7748 [here]. CodeSome sample code is: # X448 import os import binascii P = 2 ** 448 - 2 ** 224 - 1 A24 = 39081 # Defined here https://tools.ietf.org/html/rfc7748 def cswap(swap, x_2, x_3): dummy = swap * ((x_2 - x_3) % P) x_2 = x_2 - dummy x_2 %= P x_3 = x_3 + dummy x_3 %= P return (x_2, x_3) # Defined here https://tools.ietf.org/html/rfc7748 def X448(k, u): x_1 = u x_2 = 1 z_2 = 0 x_3 = u z_3 = 1 swap = 0 for t in reversed(range(448)): k_t = (k >> t) & 1 swap ^= k_t x_2, x_3 = cswap(swap, x_2, x_3) z_2, z_3 = cswap(swap, z_2, z_3) swap = k_t A = x_2 + z_2 A %= P AA = A * A AA %= P B = x_2 - z_2 B %= P BB = B * B BB %= P E = AA - BB E %= P C = x_3 + z_3 C %= P D = x_3 - z_3 D %= P DA = D * A DA %= P CB = C * B CB %= P x_3 = ((DA + CB) % P)**2 x_3 %= P z_3 = x_1 * (((DA - CB) % P)**2) % P z_3 %= P x_2 = AA * BB x_2 %= P z_2 = E * ((AA + (A24 * E) % P) % P) z_2 %= P x_2, x_3 = cswap(swap, x_2, x_3) z_2, z_3 = cswap(swap, z_2, z_3) return (x_2 * pow(z_2, P - 2, P)) % P def decodeScalar448(k): k_list = [(b) for b in k] k_list[0] &= 252 k_list[55] |= 128 return decodeLittleEndian(k_list) def decodeLittleEndian(b): return sum([b[i] << 8*i for i in range( 56 )]) def unpack2(s): if len(s) != 56: raise ValueError('Invalid Curve448 scalar (len=%d)' % len(s)) return sum(ord(s[i]) << (8 * i) for i in range(56)) def pack(n): return ''.join([chr((n >> (8 * i)) & 255) for i in range(56)]) def clamp(n): n &= ~3 n |= 128 << 8 * 55 return n # Return nP def multscalar(n, p): n = clamp(decodeScalar448(n)) p = unpack2(p) return pack(X448(n, p)) # Start at x=9. Find point n times x-point def base_point_mult(n): n = clamp(decodeScalar448(n)) return pack(X448(n, 9)) a = os.urandom(56) b = os.urandom(56) a_pub = base_point_mult(a) b_pub = base_point_mult(b) k_ab = multscalar(a, b_pub) k_ba = multscalar(b, a_pub) print ("Bob private:\t",binascii.hexlify(a)) print ("Alice private:\t",binascii.hexlify(b)) print ("\n\nBob public:\t",binascii.hexlify(b_pub.encode())) print ("Alice public:\t",binascii.hexlify(a_pub.encode())) print ("\n\nBob shared:\t",binascii.hexlify(k_ba.encode())) print ("Alice shared:\t",binascii.hexlify(k_ab.encode())) and a sample run is: Bob private: b'3881e54909109f94d5781896384dd77af435b10ac92eb1aa9f76befbd8e17e958f6490ce4498374be26b495c63f9efaef0fdac32c45f20fb' Alice private: b'62808399ea71763681ea50921448475e96f106a3a4d4e9088a9cd0805252738644bdca79823f405be948739b3ba6d550267d2e9d88f973b6' Bob public: b'c3a928c3800b541a134c28417ac2926cc2aa1fc29fc39165c3812127311fc3b5c3ac79c38349497ec2973828c3ad72c3b5c3adc3a4c3bbc29178c3893fc39ec2a80cc280c288780472167ec3bdc3b054' Alice public: b'c292c281327e7fc2bac3bbc3b4c2a4c2bcc2a6c3b0c2bfc2b82dc3bac288c2b94c64c3bf1232c395c2937cc388291f3ec3a6c2904f2bc2aa14c384c3b4c3bb515d3d4b45c2942c15c3b0c292c386c3b4c3bb20c39dc293c2ad' Bob shared: b'c397c29ec284c28621c3913fc399c28d4003c3b06bc3ba1b24c3851cc394c3b402c2aa2ac2b62c75c2b1c2987826c3877fc298524f1c53c285c3a8c392c28bc3a7c2bdc29639c2b3c3824ec2b9c38bc386c286c398250920' Alice shared: b'c397c29ec284c28621c3913fc399c28d4003c3b06bc3ba1b24c3851cc394c3b402c2aa2ac2b62c75c2b1c2987826c3877fc298524f1c53c285c3a8c392c28bc3a7c2bdc29639c2b3c3824ec2b9c38bc386c286c398250920' |