Example #1
0
def test_scalarmult_ed25519_unavailable():
    zero = 32 * b"\x00"

    with pytest.raises(UnavailableError):
        c.crypto_scalarmult_ed25519_base(zero)
    with pytest.raises(UnavailableError):
        c.crypto_scalarmult_ed25519_base_noclamp(zero)
    with pytest.raises(UnavailableError):
        c.crypto_scalarmult_ed25519(zero, zero)
    with pytest.raises(UnavailableError):
        c.crypto_scalarmult_ed25519_noclamp(zero, zero)
Example #2
0
def test_scalarmult_ed25519_noclamp():
    # An arbitrary scalar which is known to differ once clamped
    scalar = 32 * b'\x01'
    BASEPOINT = bytes(bytearray([0x58, 0x66, 0x66, 0x66,
                                 0x66, 0x66, 0x66, 0x66,
                                 0x66, 0x66, 0x66, 0x66,
                                 0x66, 0x66, 0x66, 0x66,
                                 0x66, 0x66, 0x66, 0x66,
                                 0x66, 0x66, 0x66, 0x66,
                                 0x66, 0x66, 0x66, 0x66,
                                 0x66, 0x66, 0x66, 0x66]
                                )
                      )

    p = c.crypto_scalarmult_ed25519_noclamp(scalar, BASEPOINT)
    pb = c.crypto_scalarmult_ed25519_base_noclamp(scalar)
    pc = c.crypto_scalarmult_ed25519_base(scalar)
    assert p == pb
    assert pb != pc

    # clamp manually
    ba = bytearray(scalar)
    ba0 = bytes(bytearray([ba[0] & 248]))
    ba31 = bytes(bytearray([(ba[31] & 127) | 64]))
    scalar_clamped = ba0 + bytes(ba[1:31]) + ba31

    p1 = c.crypto_scalarmult_ed25519_noclamp(scalar_clamped, BASEPOINT)
    p2 = c.crypto_scalarmult_ed25519(scalar, BASEPOINT)
    assert p1 == p2
Example #3
0
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
Example #4
0
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
Example #5
0
    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)
Example #6
0
 def __init__(self) -> None:
     """
     Initialises the Sender.
     """
     self.__senderOTSecret = nacl.utils.random(
         #bytes(random.getrandbits(8) for _ in range(
         crypto_scalarmult_ed25519_SCALARBYTES)
     #)
     self.__senderOTKey = crypto_scalarmult_ed25519_base(
         self.__senderOTSecret)
     self.__senderOTU = crypto_scalarmult_ed25519(self.__senderOTSecret,
                                                  self.__senderOTKey)
Example #7
0
    def retrieve(self, params: dict) -> dict:
        """
        Returns all encrypted entries provided to the Sender (usually all
        entries of a database). It should contain the entry of interest to the
        Receiver, although the Sender is unaware of which entry is the one. Each
        entry must be a python dict containing the following keys:
            'index' as the index of the entry given by a string,
            'value' as the value of the entry given by a string.
        All entries will be extended with a new key, which must be calculated
        only once per Sender instance:
            'indexOTU' as a specific Oblivious Transfer index value calculated
                in dependence of the senderOTKey.

        :param params: A python dict containing the following:
            'requestOTKey' as the tailored public Oblivious Transfer key of the Receiver,
            'entries' with a list of all entries to be sent to the Receiver.
        """
        sharedOTSecret = crypto_scalarmult_ed25519(self.__senderOTSecret,
                                                   params['requestOTKey'])
        C = {}
        for entry in params['entries']:
            entryIndexBytes = entry['index'].encode('utf8')
            try:
                tmp = entry['indexOTU']
            except:
                entry['indexOTU'] = crypto_scalarmult_ed25519(
                    b'\0' * (32 - len(entryIndexBytes)) + entryIndexBytes,
                    self.__senderOTU)
            K = crypto_core_ed25519_sub(sharedOTSecret, entry['indexOTU'])
            c = nacl.secret.SecretBox(K).encrypt(entry['value'].encode('utf8'))
            if CONCEAL_RESPONSE_INDICES:
                i = _calcMac(
                    entryIndexBytes,
                    keyBytes=K,
                )
            else:
                i = entry['index']
            C[i] = c
        return C
Example #8
0
def test_scalarmult_ed25519_base():
    """
    Verify scalarmult_ed25519_base is congruent to
    scalarmult_ed25519 on the ed25519 base point
    """

    BASEPOINT = bytes(
        bytearray([
            0x58,
            0x66,
            0x66,
            0x66,
            0x66,
            0x66,
            0x66,
            0x66,
            0x66,
            0x66,
            0x66,
            0x66,
            0x66,
            0x66,
            0x66,
            0x66,
            0x66,
            0x66,
            0x66,
            0x66,
            0x66,
            0x66,
            0x66,
            0x66,
            0x66,
            0x66,
            0x66,
            0x66,
            0x66,
            0x66,
            0x66,
            0x66,
        ]))

    sclr = c.randombytes(c.crypto_scalarmult_ed25519_SCALARBYTES)

    p = c.crypto_scalarmult_ed25519_base(sclr)
    p2 = c.crypto_scalarmult_ed25519(sclr, BASEPOINT)

    assert p2 == p
Example #9
0
def test_scalarmult_ed25519_base():
    """
    Verify scalarmult_ed25519_base is congruent to
    scalarmult_ed25519 on the ed25519 base point
    """

    BASEPOINT = bytes(bytearray([0x58, 0x66, 0x66, 0x66,
                                 0x66, 0x66, 0x66, 0x66,
                                 0x66, 0x66, 0x66, 0x66,
                                 0x66, 0x66, 0x66, 0x66,
                                 0x66, 0x66, 0x66, 0x66,
                                 0x66, 0x66, 0x66, 0x66,
                                 0x66, 0x66, 0x66, 0x66,
                                 0x66, 0x66, 0x66, 0x66]
                                )
                      )

    sclr = c.randombytes(c.crypto_scalarmult_ed25519_SCALARBYTES)

    p = c.crypto_scalarmult_ed25519_base(sclr)
    p2 = c.crypto_scalarmult_ed25519(sclr, BASEPOINT)

    assert p2 == p