def test_scalarmult_ed25519(): SCALARBYTES = c.crypto_scalarmult_ed25519_SCALARBYTES # the minimum ed25519 scalar is represented by a 8 value in the # first octet, a 64 value in the last octet, and all zeros # in between: MINSC = bytes(bytearray([8] + (SCALARBYTES - 2) * [0] + [64])) # the scalar multiplication formula for ed25519 # "clamps" the scalar by setting the most significant bit # of the last octet to zero, therefore scalar multiplication # by CLMPD is equivalent to scalar multiplication by MINSC CLMPD = bytes(bytearray([8] + (SCALARBYTES - 2) * [0] + [192])) MIN_P1 = bytes(bytearray([9] + (SCALARBYTES - 2) * [0] + [64])) MIN_P7 = bytes(bytearray([15] + (SCALARBYTES - 2) * [0] + [64])) MIN_P8 = bytes(bytearray([16] + (SCALARBYTES - 2) * [0] + [64])) p, _s = c.crypto_sign_keypair() _p = p for i in range(254): # double _p _p = c.crypto_core_ed25519_add(_p, _p) for i in range(8): _p = c.crypto_core_ed25519_add(_p, p) # at this point _p is (2^254+8) times p assert c.crypto_scalarmult_ed25519(MINSC, p) == _p assert c.crypto_scalarmult_ed25519(CLMPD, p) == _p # ed25519 scalar multiplication sets the least three significant # bits of the first octet to zero; therefore: assert c.crypto_scalarmult_ed25519(MIN_P1, p) == _p assert c.crypto_scalarmult_ed25519(MIN_P7, p) == _p _p8 = _p for i in range(8): _p8 = c.crypto_core_ed25519_add(_p8, p) # at this point _p is (2^254 + 16) times p assert c.crypto_scalarmult_ed25519(MIN_P8, p) == _p8
def test_scalarmult_ed25519(): SCALARBYTES = c.crypto_scalarmult_ed25519_SCALARBYTES # the minimum ed25519 scalar is represented by a 8 value in the # first octet, a 64 value in the last octet, and all zeros # in between: MINSC = bytes(bytearray([8] + (SCALARBYTES - 2) * [0] + [64])) # the scalar multiplication formula for ed25519 # "clamps" the scalar by setting the most significant bit # of the last octet to zero, therefore scalar multiplication # by CLMPD is equivalent to scalar multiplication by MINSC CLMPD = bytes(bytearray([8] + (SCALARBYTES - 2) * [0] + [192])) MIN_P1 = bytes(bytearray([9] + (SCALARBYTES - 2) * [0] + [64])) MIN_P7 = bytes(bytearray([15] + (SCALARBYTES - 2) * [0] + [64])) MIN_P8 = bytes(bytearray([16] + (SCALARBYTES - 2) * [0] + [64])) p, _s = c.crypto_sign_keypair() _p = p for i in range(254): # double _p _p = c.crypto_core_ed25519_add(_p, _p) for i in range(8): _p = c.crypto_core_ed25519_add(_p, p) # at this point _p is (2^254+8) times p assert c.crypto_scalarmult_ed25519(MINSC, p) == _p assert c.crypto_scalarmult_ed25519(CLMPD, p) == _p # ed25519 scalar multiplication sets the least three significant # bits of the first octet to zero; therefore: assert c.crypto_scalarmult_ed25519(MIN_P1, p) == _p assert c.crypto_scalarmult_ed25519(MIN_P7, p) == _p _p8 = _p for i in range(8): _p8 = c.crypto_core_ed25519_add(_p8, p) # at this point _p is (2^254 + 16) times p assert c.crypto_scalarmult_ed25519(MIN_P8, p) == _p8
def test_ed25519_add_and_sub(): # the public component of a ed25519 keypair # is a point on the ed25519 curve p1, _s1 = c.crypto_sign_keypair() p2, _s2 = c.crypto_sign_keypair() p3 = c.crypto_core_ed25519_add(p1, p2) assert c.crypto_core_ed25519_is_valid_point(p3) is True assert c.crypto_core_ed25519_sub(p3, p1) == p2 assert c.crypto_core_ed25519_sub(p3, p2) == p1
def test_ed25519_add_and_sub(): # the public component of a ed25519 keypair # is a point on the ed25519 curve p1, _s1 = c.crypto_sign_keypair() p2, _s2 = c.crypto_sign_keypair() p3 = c.crypto_core_ed25519_add(p1, p2) assert c.crypto_core_ed25519_is_valid_point(p3) is True assert c.crypto_core_ed25519_sub(p3, p1) == p2 assert c.crypto_core_ed25519_sub(p3, p2) == p1
def test_ed25519_unavailable(): zero = 32 * b"\x00" with pytest.raises(UnavailableError): c.crypto_core_ed25519_is_valid_point(zero) with pytest.raises(UnavailableError): c.crypto_core_ed25519_add(zero, zero) with pytest.raises(UnavailableError): c.crypto_core_ed25519_sub(zero, zero) with pytest.raises(UnavailableError): c.crypto_core_ed25519_scalar_invert(zero) with pytest.raises(UnavailableError): c.crypto_core_ed25519_scalar_negate(zero) with pytest.raises(UnavailableError): c.crypto_core_ed25519_scalar_complement(zero) with pytest.raises(UnavailableError): c.crypto_core_ed25519_scalar_add(zero, zero) with pytest.raises(UnavailableError): c.crypto_core_ed25519_scalar_sub(zero, zero) with pytest.raises(UnavailableError): c.crypto_core_ed25519_scalar_mul(zero, zero) with pytest.raises(UnavailableError): c.crypto_core_ed25519_scalar_reduce(zero)
def point_add(point_1: bytes, point_2: bytes) -> bytes: """ Add two points on the ed25519 curve. Args: point_1 (bytes): Point 1 bytes point_2 (bytes): Point 2 bytes Returns: bytes: New point resulting from the addition """ return bindings.crypto_core_ed25519_add( point_1 if point_is_encoded(point_1) else point_encode(point_1), point_2 if point_is_encoded(point_2) else point_encode(point_2) )
def getRequestOTKey(self, entryIndex: str) -> bytes: """ Given the index of an entry of interest to the Receiver, returns the tailored public Oblivious Transfer key of the Receiver. Further, the Oblivious Transfer secret key is stored internally, which later is used to decrypt the entry of interest to the Receiver. :param entryIndex: The index of an entry of interest to the Receiver. It must be provided as a string. """ entryIndexBytes = entryIndex.encode('utf8') sk = nacl.utils.random(crypto_scalarmult_ed25519_SCALARBYTES) pk = crypto_scalarmult_ed25519_base(sk) self.__otSecrets[entryIndex] = crypto_scalarmult_ed25519( sk, self.__senderOTKey) return crypto_core_ed25519_add( crypto_scalarmult_ed25519( b'\0' * (32 - len(entryIndexBytes)) + entryIndexBytes, self.__senderOTKey), pk)