rbcl module
Python library that bundles libsodium and provides wrappers for its Ristretto group functions.
This library exports wrappers for all libsodium functions related to the Ristretto
group and random element generation, including all functions with names of the form
crypto_scalarmult_* and relevant functions with names of the form
randombytes*.
- rbcl.rbcl.crypto_core_ristretto255_HASHBYTES: int
Length of hash digest to use for creating a point.
- rbcl.rbcl.crypto_core_ristretto255_NONREDUCEDSCALARBYTES: int
Length of a byte sequence that represents a scalar (possibly using a non-reduced representation).
- rbcl.rbcl.crypto_core_ristretto255_SCALARBYTES: int
Length of a byte sequence that represents a scalar.
- rbcl.rbcl.crypto_scalarmult_ristretto255_BYTES: int
Length of a byte sequence that represents a point (provided to – or returned by – a scalar-point multiplication function).
- rbcl.rbcl.crypto_scalarmult_ristretto255_SCALARBYTES: int
Length of a byte sequence that represents a scalar (to be used as an input to a scalar-point multiplication function).
- rbcl.rbcl.randombytes(length: int) bytes[source]
Return a bytes-like object of length
lengthcontaining random bytes from a cryptographically suitable source of randomness.- Parameters
length – Length of bytes-like object to return.
>>> len(randombytes(14)) == 14 True >>> r1 = randombytes(14) >>> r2 = randombytes(14) >>> r1 == r2 # Chances of equality succeeding are 1/(2^42). False
An exception is raised if the input is not valid:
>>> randombytes('abc') Traceback (most recent call last): ... TypeError: length must be an integer >>> randombytes(-1) Traceback (most recent call last): ... ValueError: length must be a non-negative integer
- rbcl.rbcl.randombytes_buf_deterministic(length: int, seed: bytes) bytes[source]
Return a bytes-like object of length
lengthcontaining pseudorandom bytes that have been deterministically generated from the supplied seed (a byte vector of lengthrandombytes_SEEDBYTES).- Parameters
length – Length of bytes-like object to return.
seed – Seed to use for generating pseudorandom bytes.
The example below shows that the first
32bytes from the stream of pseudorandom bytes seeded byb'p' * 32are consistent across invocations:>>> r1 = randombytes_buf_deterministic(32, b'p' * 32) >>> r2 = randombytes_buf_deterministic(40, b'p' * 32) >>> len(r1) == 32 True >>> r1 == r2[:32] True
An exception is raised if an input is not valid:
>>> randombytes_buf_deterministic('abc', b'p' * 32) Traceback (most recent call last): ... TypeError: length must be an integer >>> randombytes_buf_deterministic(-1, b'p' * 32) Traceback (most recent call last): ... ValueError: length must be a non-negative integer >>> try: ... randombytes_buf_deterministic(32, 123) ... except TypeError as e: ... str(e) == 'seed must be a bytes object of length ' + str(randombytes_SEEDBYTES) True >>> try: ... randombytes_buf_deterministic(32, b'p'*16) ... except ValueError as e: ... str(e) == 'seed must be a bytes object of length ' + str(randombytes_SEEDBYTES) True
- rbcl.rbcl.crypto_core_ristretto255_is_valid_point(p: bytes) bool[source]
Return a boolean indiciating whether
pis a representation of a valid point on the main subgroup (in canonical form) and that the point does not have a small order.- Parameters
p – Byte vector of length
crypto_core_ristretto255_BYTES.
>>> p = crypto_core_ristretto255_random() >>> crypto_core_ristretto255_is_valid_point(p) True
For this and other functions that operate on points, a descriptive exception is raised if an input is not valid:
>>> try: ... crypto_core_ristretto255_is_valid_point(123) ... except TypeError as e: ... str(e) == ( ... 'point must be a bytes object of length ' + ... str(crypto_core_ristretto255_BYTES) ... ) True >>> try: ... crypto_core_ristretto255_is_valid_point(bytes([0, 0 ,0])) ... except ValueError as e: ... str(e) == ( ... 'point must be a bytes object of length ' + ... str(crypto_core_ristretto255_BYTES) ... ) True
- rbcl.rbcl.crypto_core_ristretto255_random() bytes[source]
Return a valid random point (represented as a byte vector of length
crypto_core_ristretto255_BYTES).>>> p = crypto_core_ristretto255_random() >>> crypto_core_ristretto255_is_valid_point(p) True
- rbcl.rbcl.crypto_core_ristretto255_from_hash(h: bytes) bytes[source]
Map a 64-byte vector
h(usually the output of a hash function) to a a point (represented as a byte vector of lengthcrypto_core_ristretto255_BYTES).- Parameters
h – Byte vector of length
crypto_core_ristretto255_HASHBYTES(usually representing a hash digest).
>>> p = crypto_core_ristretto255_from_hash(b'p'*64) >>> crypto_core_ristretto255_is_valid_point(p) True
- rbcl.rbcl.crypto_core_ristretto255_add(p: bytes, q: bytes) bytes[source]
Add two points
pandqand return their sum (represented as a byte vector of lengthcrypto_core_ristretto255_BYTES).- Parameters
p – Byte vector of length
crypto_core_ristretto255_BYTESrepresenting a point.q – Byte vector of length
crypto_core_ristretto255_BYTESrepresenting a point.
Addition of points is commutative:
>>> p = crypto_core_ristretto255_random() >>> q = crypto_core_ristretto255_from_hash(b'p'*64) >>> pq = crypto_core_ristretto255_add(p, q) >>> qp = crypto_core_ristretto255_add(q, p) >>> pq == qp True
- rbcl.rbcl.crypto_core_ristretto255_sub(p: bytes, q: bytes) bytes[source]
Subtract a point
qfrom a pointpand return their difference (represented as a byte vector of lengthcrypto_core_ristretto255_BYTES).- Parameters
p – Byte vector of length
crypto_core_ristretto255_BYTESrepresenting a point.q – Byte vector of length
crypto_core_ristretto255_BYTESrepresenting a point.
Subtraction between points is the inverse of point addition:
>>> p = crypto_core_ristretto255_from_hash(b'p'*64) >>> q = crypto_core_ristretto255_random() >>> masked = crypto_core_ristretto255_add(p, q) >>> unmasked = crypto_core_ristretto255_sub(masked, q) >>> p == unmasked True
- rbcl.rbcl.crypto_core_ristretto255_scalar_random() bytes[source]
Return a random scalar, represented as a byte vector of length
crypto_core_ristretto255_SCALARBYTES.>>> s = crypto_core_ristretto255_scalar_random() >>> len(s) == crypto_core_ristretto255_SCALARBYTES True
When interpreted as an integer, the scalar is guaranteed to be less than the order of the group (i.e.,
2^252 + 27742317777372353535851937790883648493).
- rbcl.rbcl.crypto_core_ristretto255_scalar_reduce(s: bytes) bytes[source]
Given a byte vector of length
crypto_core_ristretto255_NONREDUCEDSCALARBYTESrepresenting a scalar, return its reduced representationsmoduloL(whereLis the order of the main subgroup) as a byte vector of lengthcrypto_core_ristretto255_SCALARBYTES.- Parameters
s – Byte vector of length
crypto_core_ristretto255_NONREDUCEDSCALARBYTESrepresenting a scalar.
In the example below, a large integer representing a scalar is reduced to a valid scalar:
>>> x = bytes.fromhex('FF' * 32) >>> s = crypto_core_ristretto255_scalar_reduce(x) >>> p = crypto_core_ristretto255_random() >>> masked = crypto_scalarmult_ristretto255(s, p) >>> s_inv = crypto_core_ristretto255_scalar_invert(s) >>> unmasked = crypto_scalarmult_ristretto255(s_inv, masked) >>> unmasked == p True
For this and other functions that operate on points, a descriptive exception is raised if an input is not valid:
>>> try: ... crypto_core_ristretto255_scalar_reduce(123) ... except TypeError as e: ... str(e) == ( ... 'scalar must be a bytes object of length ' + ... str(crypto_core_ristretto255_SCALARBYTES) ... ) True >>> try: ... crypto_core_ristretto255_scalar_reduce(bytes([0, 0 ,0])) ... except ValueError as e: ... str(e) == ( ... 'scalar must be a bytes object of length ' + ... str(crypto_core_ristretto255_SCALARBYTES) ... ) True
- rbcl.rbcl.crypto_core_ristretto255_scalar_negate(s: bytes) bytes[source]
Return the additive inverse of the scalar
smoduloL(i.e., a scalartsuch thats + t == 0moduloL, whereLis the order of the main subgroup). The input and output are each represented as a byte vector of lengthcrypto_core_ristretto255_SCALARBYTES.- Parameters
s – Byte vector of length
crypto_core_ristretto255_SCALARBYTESrepresenting a scalar.
All scalars have an additive inverse:
>>> s = crypto_core_ristretto255_scalar_random() >>> t = crypto_core_ristretto255_scalar_negate(s) >>> zero = crypto_core_ristretto255_scalar_add(s, t) >>> s == crypto_core_ristretto255_scalar_add(s, zero) True
- rbcl.rbcl.crypto_core_ristretto255_scalar_complement(s: bytes) bytes[source]
Return the additive complement of the scalar
smoduloL(i.e., a scalartsuch thats + t == 1moduloL, whereLis the order of the main subgroup). The input and output are each represented as a byte vector of lengthcrypto_core_ristretto255_SCALARBYTES.- Parameters
s – Byte vector of length
crypto_core_ristretto255_SCALARBYTESrepresenting a scalar.
All scalars have an additive complement:
>>> s = crypto_core_ristretto255_scalar_random() >>> t = crypto_core_ristretto255_scalar_complement(s) >>> one = crypto_core_ristretto255_scalar_add(s, t) >>> p = crypto_core_ristretto255_random() >>> p == crypto_scalarmult_ristretto255(one, p) True
- rbcl.rbcl.crypto_core_ristretto255_scalar_invert(s: bytes) bytes[source]
Return the multiplicative inverse of the scalar
smoduloL(i.e., an integertsuch thats * t == 1moduloL, whereLis the order of the main subgroup). The input and output are each represented as a byte vector of lengthcrypto_core_ristretto255_SCALARBYTES.- Parameters
s – Byte vector of length
crypto_core_ristretto255_SCALARBYTESrepresenting a scalar.
All scalars have a multiplicative inverse:
>>> s = crypto_core_ristretto255_scalar_random() >>> p = crypto_core_ristretto255_random() >>> masked = crypto_scalarmult_ristretto255(s, p) >>> s_inv = crypto_core_ristretto255_scalar_invert(s) >>> unmasked = crypto_scalarmult_ristretto255(s_inv, masked) >>> unmasked == p True
If
sis the zero scalar, an exception is raised.>>> crypto_core_ristretto255_scalar_invert(bytes([0] * 32)) Traceback (most recent call last): ... ValueError: scalar must not be zero
- rbcl.rbcl.crypto_core_ristretto255_scalar_add(s: bytes, t: bytes) bytes[source]
Add two scalars
sandtmoduloL(whereLis the order of the main subgroup) and return their scalar product (represented as a byte vector of lengthcrypto_core_ristretto255_SCALARBYTES).- Parameters
s – Byte vector of length
crypto_core_ristretto255_SCALARBYTESrepresenting a scalar.t – Byte vector of length
crypto_core_ristretto255_SCALARBYTESrepresenting a scalar.
Addition of scalars is commutative:
>>> s1 = crypto_core_ristretto255_scalar_random() >>> s2 = crypto_core_ristretto255_scalar_random() >>> s12 = crypto_core_ristretto255_scalar_add(s1, s2) >>> s21 = crypto_core_ristretto255_scalar_add(s2, s1) >>> s12 == s21 True
- rbcl.rbcl.crypto_core_ristretto255_scalar_sub(s: bytes, t: bytes) bytes[source]
Subtract a scalar
tfrom a scalarsmoduloL(whereLis the order of the main subgroup) and return their difference (represented as a byte vector of lengthcrypto_core_ristretto255_SCALARBYTES).- Parameters
s – Byte vector of length
crypto_core_ristretto255_SCALARBYTESrepresenting a scalar.t – Byte vector of length
crypto_core_ristretto255_SCALARBYTESrepresenting a scalar.
Subtraction between scalars is the inverse of scalar addition:
>>> s1 = crypto_core_ristretto255_scalar_random() >>> s2 = crypto_core_ristretto255_scalar_random() >>> s1_plus_s2 = crypto_core_ristretto255_scalar_add(s1, s2) >>> s1 == crypto_core_ristretto255_scalar_sub(s1_plus_s2, s2) True
- rbcl.rbcl.crypto_core_ristretto255_scalar_mul(s: bytes, t: bytes) bytes[source]
Multiply two scalars
sandtmoduloL(whereLis the order of the main subgroup) and return their scalar product (represented as a byte vector of lengthcrypto_core_ristretto255_SCALARBYTES).- Parameters
s – Byte vector of length
crypto_core_ristretto255_SCALARBYTESrepresenting a scalar.t – Byte vector of length
crypto_core_ristretto255_SCALARBYTESrepresenting a scalar.
Multiplication of two scalars is commutative:
>>> s1 = crypto_core_ristretto255_scalar_random() >>> s2 = crypto_core_ristretto255_scalar_random() >>> s1s2 = crypto_core_ristretto255_scalar_mul(s1, s2) >>> s2s1 = crypto_core_ristretto255_scalar_mul(s2, s1) >>> s1s2 == s2s1 True
- rbcl.rbcl.crypto_scalarmult_ristretto255_base(s: bytes) bytes[source]
Compute and return the product (represented as a byte vector of length
crypto_scalarmult_ristretto255_BYTES) of a standard group element and a scalars.- Parameters
s – Byte vector of length
crypto_scalarmult_ristretto255_SCALARBYTESrepresenting a scalar.
>>> s = crypto_core_ristretto255_scalar_random() >>> gs = crypto_scalarmult_ristretto255_base(s) >>> crypto_core_ristretto255_is_valid_point(gs) True
- rbcl.rbcl.crypto_scalarmult_ristretto255_base_allow_scalar_zero(s: bytes) bytes[source]
Compute and return the product (represented as a byte vector of length
crypto_scalarmult_ristretto255_BYTES) of a standard group element and a scalars. Zero-valued scalars are permitted.- Parameters
s – Byte vector of length
crypto_scalarmult_ristretto255_SCALARBYTESrepresenting a scalar.
>>> s = crypto_core_ristretto255_scalar_random() >>> gs = crypto_scalarmult_ristretto255_base_allow_scalar_zero(s) >>> crypto_core_ristretto255_is_valid_point(gs) True >>> crypto_scalarmult_ristretto255_base_allow_scalar_zero( ... crypto_core_ristretto255_scalar_sub(s, s) ... ) == crypto_core_ristretto255_sub(gs, gs) True
- rbcl.rbcl.crypto_scalarmult_ristretto255(s: bytes, p: bytes) bytes[source]
Compute and return the product (represented as a byte vector of length
crypto_scalarmult_ristretto255_BYTES) of a clamped integersand the provided point (i.e., group element).- Parameters
s – Byte vector of length
crypto_scalarmult_ristretto255_SCALARBYTESrepresenting a scalar.p – Byte vector of length
crypto_scalarmult_ristretto255_BYTESrepresenting a valid point.
The scalar is clamped, as done in the public key generation case, by setting to zero the bits in position
[0, 1, 2, 255]and by setting to1the bit in position254.Scalar multiplication is an invertible operation:
>>> s = crypto_core_ristretto255_scalar_random() >>> p = crypto_core_ristretto255_random() >>> masked = crypto_scalarmult_ristretto255(s, p) >>> s_inv = crypto_core_ristretto255_scalar_invert(s) >>> unmasked = crypto_scalarmult_ristretto255(s_inv, masked) >>> unmasked == p True
Multiplication by the zero scalar is not defined in the subgroup consisting of products of valid points and scalars:
>>> p = crypto_core_ristretto255_random() >>> s = crypto_core_ristretto255_scalar_random() >>> t = crypto_core_ristretto255_scalar_negate(s) >>> zero = crypto_core_ristretto255_scalar_add(s, t) >>> try: ... crypto_scalarmult_ristretto255(zero, p) ... except RuntimeError as e: ... str(e) == ( ... 'input cannot be larger than the size of the group and ' + ... 'cannot yield the identity element when applied as an exponent' ... ) True
- rbcl.rbcl.crypto_scalarmult_ristretto255_allow_scalar_zero(s: bytes, p: bytes) bytes[source]
Compute and return the product (represented as a byte vector of length
crypto_scalarmult_ristretto255_BYTES) of a clamped integersand the provided point (i.e., group element).- Parameters
s – Byte vector of length
crypto_scalarmult_ristretto255_SCALARBYTESrepresenting a scalar.p – Byte vector of length
crypto_scalarmult_ristretto255_BYTESrepresenting a valid point.
The scalar is clamped, as done in the public key generation case, by setting to zero the bits in position
[0, 1, 2, 255]and by setting to1the bit in position254. Zero-valued scalars are permitted.Scalar multiplication is an invertible operation:
>>> s = crypto_core_ristretto255_scalar_random() >>> p = crypto_core_ristretto255_random() >>> masked = crypto_scalarmult_ristretto255_allow_scalar_zero(s, p) >>> s_inv = crypto_core_ristretto255_scalar_invert(s) >>> unmasked = crypto_scalarmult_ristretto255_allow_scalar_zero(s_inv, masked) >>> unmasked == p True
Multiplication by the zero scalar is permitted:
>>> zero_scalar, zero_point = bytes(32), bytes(32) >>> crypto_scalarmult_ristretto255_allow_scalar_zero(zero_scalar, p) == zero_point True
While the scalar input can be zero, the provided point must be valid:
>>> invalid_point = b'' * 32 >>> crypto_scalarmult_ristretto255_allow_scalar_zero(zero_scalar, invalid_point) Traceback (most recent call last): ... TypeError: second input must represent a valid point