ristretto255 - [mainnet]
This module contains functions for Ristretto255 curve arithmetic, assuming addition as the group operation.
The order of the Ristretto255 elliptic curve group is , same as the order of the prime-order subgroup of Curve25519.
This module provides two structs for encoding Ristretto elliptic curves to the developer:
-
First, a 32-byte-sized CompressedRistretto struct, which is used to persist points in storage.
-
Second, a larger, in-memory, RistrettoPoint struct, which is decompressable from a CompressedRistretto struct. This larger struct can be used for fast arithmetic operations (additions, multiplications, etc.). The results can be saved back into storage by compressing RistrettoPoint structs back to CompressedRistretto structs.
This module also provides a Scalar struct for persisting scalars in storage and doing fast arithmetic on them.
One invariant maintained by this module is that all CompressedRistretto structs store a canonically-encoded point, which can always be decompressed into a valid point on the curve as a RistrettoPoint struct. Unfortunately, due to limitations in our underlying curve25519-dalek elliptic curve library, this decompression will unnecessarily verify the validity of the point and thus slightly decrease performance.
Similarly, all Scalar structs store a canonically-encoded scalar, which can always be safely operated on using arithmetic operations.
In the future, we might support additional features:
- For scalars:
- batch_invert()
- For points:
- double()
- The challenge is that curve25519-dalek does NOT export double for Ristretto points (nor for Edwards)
-
double_and_compress_batch()
-
fixed-base, variable-time via optional_mixed_multiscalar_mul() in VartimePrecomputedMultiscalarMul
- This would require a storage-friendly RistrettoBasepointTable and an in-memory variant of it too
- Similar to the CompressedRistretto and RistrettoPoint structs in this module
- The challenge is that curve25519-dalek’s RistrettoBasepointTable is not serializable
use 0x1::error;use 0x1::features;use 0x1::option;use 0x1::vector;
Constants
The native function has not been deployed yet.
const E_NATIVE_FUN_NOT_AVAILABLE: u64 = 5;
The basepoint (generator) of the Ristretto255 group
const BASE_POINT: vector<u8> = [226, 242, 174, 10, 106, 188, 78, 113, 168, 132, 169, 97, 197, 0, 81, 95, 88, 227, 11, 106, 165, 130, 221, 141, 182, 166, 89, 69, 224, 141, 45, 118];
The number of scalars does not match the number of points.
const E_DIFFERENT_NUM_POINTS_AND_SCALARS: u64 = 1;
Too many points have been created in the current transaction execution.
const E_TOO_MANY_POINTS_CREATED: u64 = 4;
Expected more than zero points as input.
const E_ZERO_POINTS: u64 = 2;
Expected more than zero scalars as input.
const E_ZERO_SCALARS: u64 = 3;
The hash of the basepoint of the Ristretto255 group using SHA3_512
const HASH_BASE_POINT: vector<u8> = [140, 146, 64, 180, 86, 169, 230, 220, 101, 195, 119, 161, 4, 141, 116, 95, 148, 160, 140, 219, 127, 68, 203, 205, 123, 70, 243, 64, 72, 135, 17, 52];
ORDER_ELL
- 1: i.e., the “largest”, reduced scalar in the field
const L_MINUS_ONE: vector<u8> = [236, 211, 245, 92, 26, 99, 18, 88, 214, 156, 247, 162, 222, 249, 222, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16];
The maximum size in bytes of a canonically-encoded Ristretto255 point is 32 bytes.
const MAX_POINT_NUM_BYTES: u64 = 32;
The maximum size in bits of a canonically-encoded Scalar is 256 bits.
const MAX_SCALAR_NUM_BITS: u64 = 256;
The maximum size in bytes of a canonically-encoded Scalar is 32 bytes.
const MAX_SCALAR_NUM_BYTES: u64 = 32;
The order of the Ristretto255 group and its scalar field, in little-endian.
const ORDER_ELL: vector<u8> = [237, 211, 245, 92, 26, 99, 18, 88, 214, 156, 247, 162, 222, 249, 222, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16];
Structs
Scalar
This struct represents a scalar as a little-endian byte encoding of an integer in , which is
stored in data
. Here, \ell denotes the order of the scalar field (and the underlying elliptic curve group).
struct Scalar has copy, drop, store
Fields
-
data: vector<u8>
CompressedRistretto
This struct represents a serialized point on the Ristretto255 curve, in 32 bytes. This struct can be decompressed from storage into an in-memory RistrettoPoint, on which fast curve arithmetic can be performed.
struct CompressedRistretto has copy, drop, store
Fields
-
data: vector<u8>
RistrettoPoint
This struct represents an in-memory Ristretto255 point and supports fast curve arithmetic.
An important invariant: There will never be two RistrettoPoint’s constructed with the same handle. One can have immutable references to the same RistrettoPoint, of course.
struct RistrettoPoint has drop
Fields
-
handle: u64
Functions
point_identity_compressed
Returns the identity point as a CompressedRistretto.
public fun point_identity_compressed(): ristretto255::CompressedRistretto
Implementation
public fun point_identity_compressed(): CompressedRistretto { CompressedRistretto { data: x"0000000000000000000000000000000000000000000000000000000000000000" }}
point_identity
Returns the identity point as a CompressedRistretto.
public fun point_identity(): ristretto255::RistrettoPoint
Implementation
public fun point_identity(): RistrettoPoint { RistrettoPoint { handle: point_identity_internal() }}
basepoint_compressed
Returns the basepoint (generator) of the Ristretto255 group as a compressed point
public fun basepoint_compressed(): ristretto255::CompressedRistretto
Implementation
public fun basepoint_compressed(): CompressedRistretto { CompressedRistretto { data: BASE_POINT }}
hash_to_point_base
Returns the hash-to-point result of serializing the basepoint of the Ristretto255 group. For use as the random value basepoint in Pedersen commitments
public fun hash_to_point_base(): ristretto255::RistrettoPoint
Implementation
public fun hash_to_point_base(): RistrettoPoint { let comp_res = CompressedRistretto { data: HASH_BASE_POINT }; point_decompress(&comp_res)}
basepoint
Returns the basepoint (generator) of the Ristretto255 group
public fun basepoint(): ristretto255::RistrettoPoint
Implementation
public fun basepoint(): RistrettoPoint { let (handle, _) = point_decompress_internal(BASE_POINT);
RistrettoPoint { handle }}
basepoint_mul
Multiplies the basepoint (generator) of the Ristretto255 group by a scalar and returns the result.
This call is much faster than point_mul(&basepoint(), &some_scalar)
because of precomputation tables.
public fun basepoint_mul(a: &ristretto255::Scalar): ristretto255::RistrettoPoint
Implementation
public fun basepoint_mul(a: &Scalar): RistrettoPoint { RistrettoPoint { handle: basepoint_mul_internal(a.data) }}
new_compressed_point_from_bytes
Creates a new CompressedRistretto point from a sequence of 32 bytes. If those bytes do not represent a valid point, returns None.
public fun new_compressed_point_from_bytes(bytes: vector<u8>): option::Option<ristretto255::CompressedRistretto>
Implementation
public fun new_compressed_point_from_bytes(bytes: vector<u8>): Option<CompressedRistretto> { if (point_is_canonical_internal(bytes)) { std::option::some(CompressedRistretto { data: bytes }) } else { std::option::none<CompressedRistretto>() }}
new_point_from_bytes
Creates a new RistrettoPoint from a sequence of 32 bytes. If those bytes do not represent a valid point, returns None.
public fun new_point_from_bytes(bytes: vector<u8>): option::Option<ristretto255::RistrettoPoint>
Implementation
public fun new_point_from_bytes(bytes: vector<u8>): Option<RistrettoPoint> { let (handle, is_canonical) = point_decompress_internal(bytes); if (is_canonical) { std::option::some(RistrettoPoint { handle }) } else { std::option::none<RistrettoPoint>() }}
compressed_point_to_bytes
Given a compressed ristretto point point
, returns the byte representation of that point
public fun compressed_point_to_bytes(point: ristretto255::CompressedRistretto): vector<u8>
Implementation
public fun compressed_point_to_bytes(point: CompressedRistretto): vector<u8> { point.data}
new_point_from_sha512
DEPRECATED: Use the more clearly-named new_point_from_sha2_512
Hashes the input to a uniformly-at-random RistrettoPoint via SHA512.
public fun new_point_from_sha512(sha2_512_input: vector<u8>): ristretto255::RistrettoPoint
Implementation
public fun new_point_from_sha512(sha2_512_input: vector<u8>): RistrettoPoint { new_point_from_sha2_512(sha2_512_input)}
new_point_from_sha2_512
Hashes the input to a uniformly-at-random RistrettoPoint via SHA2-512.
public fun new_point_from_sha2_512(sha2_512_input: vector<u8>): ristretto255::RistrettoPoint
Implementation
public fun new_point_from_sha2_512(sha2_512_input: vector<u8>): RistrettoPoint { RistrettoPoint { handle: new_point_from_sha512_internal(sha2_512_input) }}
new_point_from_64_uniform_bytes
Samples a uniformly-at-random RistrettoPoint given a sequence of 64 uniformly-at-random bytes. This function can be used to build a collision-resistant hash function that maps 64-byte messages to RistrettoPoint’s.
public fun new_point_from_64_uniform_bytes(bytes: vector<u8>): option::Option<ristretto255::RistrettoPoint>
Implementation
public fun new_point_from_64_uniform_bytes(bytes: vector<u8>): Option<RistrettoPoint> { if (bytes.length() == 64) { std::option::some(RistrettoPoint { handle: new_point_from_64_uniform_bytes_internal(bytes) }) } else { std::option::none<RistrettoPoint>() }}
point_decompress
Decompresses a CompressedRistretto from storage into a RistrettoPoint which can be used for fast arithmetic.
public fun point_decompress(point: &ristretto255::CompressedRistretto): ristretto255::RistrettoPoint
Implementation
public fun point_decompress(point: &CompressedRistretto): RistrettoPoint { // NOTE: Our CompressedRistretto invariant assures us that every CompressedRistretto in storage is a valid // RistrettoPoint let (handle, _) = point_decompress_internal(point.data); RistrettoPoint { handle }}
point_clone
Clones a RistrettoPoint.
public fun point_clone(point: &ristretto255::RistrettoPoint): ristretto255::RistrettoPoint
Implementation
public fun point_clone(point: &RistrettoPoint): RistrettoPoint { if(!features::bulletproofs_enabled()) { abort(std::error::invalid_state(E_NATIVE_FUN_NOT_AVAILABLE)) };
RistrettoPoint { handle: point_clone_internal(point.handle) }}
point_compress
Compresses a RistrettoPoint to a CompressedRistretto which can be put in storage.
public fun point_compress(point: &ristretto255::RistrettoPoint): ristretto255::CompressedRistretto
Implementation
public fun point_compress(point: &RistrettoPoint): CompressedRistretto { CompressedRistretto { data: point_compress_internal(point) }}
point_to_bytes
Returns the sequence of bytes representin this Ristretto point.
To convert a RistrettoPoint ‘p’ to bytes, first compress it via c = point_compress(&p)
, and then call this
function on c
.
public fun point_to_bytes(point: &ristretto255::CompressedRistretto): vector<u8>
Implementation
public fun point_to_bytes(point: &CompressedRistretto): vector<u8> { point.data}
point_mul
Returns a * point.
public fun point_mul(point: &ristretto255::RistrettoPoint, a: &ristretto255::Scalar): ristretto255::RistrettoPoint
Implementation
public fun point_mul(point: &RistrettoPoint, a: &Scalar): RistrettoPoint { RistrettoPoint { handle: point_mul_internal(point, a.data, false) }}
point_mul_assign
Sets a *= point and returns ‘a’.
public fun point_mul_assign(point: &mut ristretto255::RistrettoPoint, a: &ristretto255::Scalar): &mut ristretto255::RistrettoPoint
Implementation
public fun point_mul_assign(point: &mut RistrettoPoint, a: &Scalar): &mut RistrettoPoint { point_mul_internal(point, a.data, true); point}
basepoint_double_mul
Returns (a * a_base + b * base_point), where base_point is the Ristretto basepoint encoded in BASE_POINT
.
public fun basepoint_double_mul(a: &ristretto255::Scalar, a_base: &ristretto255::RistrettoPoint, b: &ristretto255::Scalar): ristretto255::RistrettoPoint
Implementation
public fun basepoint_double_mul(a: &Scalar, a_base: &RistrettoPoint, b: &Scalar): RistrettoPoint { RistrettoPoint { handle: basepoint_double_mul_internal(a.data, a_base, b.data) }}
point_add
Returns a + b
public fun point_add(a: &ristretto255::RistrettoPoint, b: &ristretto255::RistrettoPoint): ristretto255::RistrettoPoint
Implementation
public fun point_add(a: &RistrettoPoint, b: &RistrettoPoint): RistrettoPoint { RistrettoPoint { handle: point_add_internal(a, b, false) }}
point_add_assign
Sets a += b and returns ‘a’.
public fun point_add_assign(a: &mut ristretto255::RistrettoPoint, b: &ristretto255::RistrettoPoint): &mut ristretto255::RistrettoPoint
Implementation
public fun point_add_assign(a: &mut RistrettoPoint, b: &RistrettoPoint): &mut RistrettoPoint { point_add_internal(a, b, true); a}
point_sub
Returns a - b
public fun point_sub(a: &ristretto255::RistrettoPoint, b: &ristretto255::RistrettoPoint): ristretto255::RistrettoPoint
Implementation
public fun point_sub(a: &RistrettoPoint, b: &RistrettoPoint): RistrettoPoint { RistrettoPoint { handle: point_sub_internal(a, b, false) }}
point_sub_assign
Sets a -= b and returns ‘a’.
public fun point_sub_assign(a: &mut ristretto255::RistrettoPoint, b: &ristretto255::RistrettoPoint): &mut ristretto255::RistrettoPoint
Implementation
public fun point_sub_assign(a: &mut RistrettoPoint, b: &RistrettoPoint): &mut RistrettoPoint { point_sub_internal(a, b, true); a}
point_neg
Returns -a
public fun point_neg(a: &ristretto255::RistrettoPoint): ristretto255::RistrettoPoint
Implementation
public fun point_neg(a: &RistrettoPoint): RistrettoPoint { RistrettoPoint { handle: point_neg_internal(a, false) }}
point_neg_assign
Sets a = -a, and returns ‘a’.
public fun point_neg_assign(a: &mut ristretto255::RistrettoPoint): &mut ristretto255::RistrettoPoint
Implementation
public fun point_neg_assign(a: &mut RistrettoPoint): &mut RistrettoPoint { point_neg_internal(a, true); a}
point_equals
Returns true if the two RistrettoPoints are the same points on the elliptic curve.
public fun point_equals(g: &ristretto255::RistrettoPoint, h: &ristretto255::RistrettoPoint): bool
Implementation
native public fun point_equals(g: &RistrettoPoint, h: &RistrettoPoint): bool;
double_scalar_mul
Computes a double-scalar multiplication, returning a_1 p_1 + a_2 p_2
This function is much faster than computing each a_i p_i using point_mul
and adding up the results using point_add
.
public fun double_scalar_mul(scalar1: &ristretto255::Scalar, point1: &ristretto255::RistrettoPoint, scalar2: &ristretto255::Scalar, point2: &ristretto255::RistrettoPoint): ristretto255::RistrettoPoint
Implementation
public fun double_scalar_mul(scalar1: &Scalar, point1: &RistrettoPoint, scalar2: &Scalar, point2: &RistrettoPoint): RistrettoPoint { if(!features::bulletproofs_enabled()) { abort(std::error::invalid_state(E_NATIVE_FUN_NOT_AVAILABLE)) };
RistrettoPoint { handle: double_scalar_mul_internal(point1.handle, point2.handle, scalar1.data, scalar2.data) }}
multi_scalar_mul
Computes a multi-scalar multiplication, returning a_1 p_1 + a_2 p_2 + … + a_n p_n.
This function is much faster than computing each a_i p_i using point_mul
and adding up the results using point_add
.
public fun multi_scalar_mul(points: &vector<ristretto255::RistrettoPoint>, scalars: &vector<ristretto255::Scalar>): ristretto255::RistrettoPoint
Implementation
public fun multi_scalar_mul(points: &vector<RistrettoPoint>, scalars: &vector<Scalar>): RistrettoPoint { assert!(!points.is_empty(), std::error::invalid_argument(E_ZERO_POINTS)); assert!(!scalars.is_empty(), std::error::invalid_argument(E_ZERO_SCALARS)); assert!( points.length() == scalars.length(), std::error::invalid_argument(E_DIFFERENT_NUM_POINTS_AND_SCALARS));
RistrettoPoint { handle: multi_scalar_mul_internal<RistrettoPoint, Scalar>(points, scalars) }}
new_scalar_from_bytes
Given a sequence of 32 bytes, checks if they canonically-encode a Scalar and return it. Otherwise, returns None.
public fun new_scalar_from_bytes(bytes: vector<u8>): option::Option<ristretto255::Scalar>
Implementation
public fun new_scalar_from_bytes(bytes: vector<u8>): Option<Scalar> { if (scalar_is_canonical_internal(bytes)) { std::option::some(Scalar { data: bytes }) } else { std::option::none<Scalar>() }}
new_scalar_from_sha512
DEPRECATED: Use the more clearly-named new_scalar_from_sha2_512
Hashes the input to a uniformly-at-random Scalar via SHA2-512
public fun new_scalar_from_sha512(sha2_512_input: vector<u8>): ristretto255::Scalar
Implementation
public fun new_scalar_from_sha512(sha2_512_input: vector<u8>): Scalar { new_scalar_from_sha2_512(sha2_512_input)}
new_scalar_from_sha2_512
Hashes the input to a uniformly-at-random Scalar via SHA2-512
public fun new_scalar_from_sha2_512(sha2_512_input: vector<u8>): ristretto255::Scalar
Implementation
public fun new_scalar_from_sha2_512(sha2_512_input: vector<u8>): Scalar { Scalar { data: scalar_from_sha512_internal(sha2_512_input) }}
new_scalar_from_u8
Creates a Scalar from an u8.
public fun new_scalar_from_u8(byte: u8): ristretto255::Scalar
Implementation
public fun new_scalar_from_u8(byte: u8): Scalar { let s = scalar_zero(); s.data[0] = byte; s}
new_scalar_from_u32
Creates a Scalar from an u32.
public fun new_scalar_from_u32(four_bytes: u32): ristretto255::Scalar
Implementation
public fun new_scalar_from_u32(four_bytes: u32): Scalar { Scalar { data: scalar_from_u64_internal((four_bytes as u64)) }}
new_scalar_from_u64
Creates a Scalar from an u64.
public fun new_scalar_from_u64(eight_bytes: u64): ristretto255::Scalar
Implementation
public fun new_scalar_from_u64(eight_bytes: u64): Scalar { Scalar { data: scalar_from_u64_internal(eight_bytes) }}
new_scalar_from_u128
Creates a Scalar from an u128.
public fun new_scalar_from_u128(sixteen_bytes: u128): ristretto255::Scalar
Implementation
public fun new_scalar_from_u128(sixteen_bytes: u128): Scalar { Scalar { data: scalar_from_u128_internal(sixteen_bytes) }}
new_scalar_reduced_from_32_bytes
Creates a Scalar from 32 bytes by reducing the little-endian-encoded number in those bytes modulo .
public fun new_scalar_reduced_from_32_bytes(bytes: vector<u8>): option::Option<ristretto255::Scalar>
Implementation
public fun new_scalar_reduced_from_32_bytes(bytes: vector<u8>): Option<Scalar> { if (bytes.length() == 32) { std::option::some(Scalar { data: scalar_reduced_from_32_bytes_internal(bytes) }) } else { std::option::none() }}
new_scalar_uniform_from_64_bytes
Samples a scalar uniformly-at-random given 64 uniform-at-random bytes as input by reducing the little-endian-encoded number in those bytes modulo .
public fun new_scalar_uniform_from_64_bytes(bytes: vector<u8>): option::Option<ristretto255::Scalar>
Implementation
public fun new_scalar_uniform_from_64_bytes(bytes: vector<u8>): Option<Scalar> { if (bytes.length() == 64) { std::option::some(Scalar { data: scalar_uniform_from_64_bytes_internal(bytes) }) } else { std::option::none() }}
scalar_zero
Returns 0 as a Scalar.
public fun scalar_zero(): ristretto255::Scalar
Implementation
public fun scalar_zero(): Scalar { Scalar { data: x"0000000000000000000000000000000000000000000000000000000000000000" }}
scalar_is_zero
Returns true if the given Scalar equals 0.
public fun scalar_is_zero(s: &ristretto255::Scalar): bool
Implementation
public fun scalar_is_zero(s: &Scalar): bool { s.data == x"0000000000000000000000000000000000000000000000000000000000000000"}
scalar_one
Returns 1 as a Scalar.
public fun scalar_one(): ristretto255::Scalar
Implementation
public fun scalar_one(): Scalar { Scalar { data: x"0100000000000000000000000000000000000000000000000000000000000000" }}
scalar_is_one
Returns true if the given Scalar equals 1.
public fun scalar_is_one(s: &ristretto255::Scalar): bool
Implementation
public fun scalar_is_one(s: &Scalar): bool { s.data == x"0100000000000000000000000000000000000000000000000000000000000000"}
scalar_equals
Returns true if the two scalars are equal.
public fun scalar_equals(lhs: &ristretto255::Scalar, rhs: &ristretto255::Scalar): bool
Implementation
public fun scalar_equals(lhs: &Scalar, rhs: &Scalar): bool { lhs.data == rhs.data}
scalar_invert
Returns the inverse s^{-1} mod \ell of a scalar s. Returns None if s is zero.
public fun scalar_invert(s: &ristretto255::Scalar): option::Option<ristretto255::Scalar>
Implementation
public fun scalar_invert(s: &Scalar): Option<Scalar> { if (scalar_is_zero(s)) { std::option::none<Scalar>() } else { std::option::some(Scalar { data: scalar_invert_internal(s.data) }) }}
scalar_mul
Returns the product of the two scalars.
public fun scalar_mul(a: &ristretto255::Scalar, b: &ristretto255::Scalar): ristretto255::Scalar
Implementation
public fun scalar_mul(a: &Scalar, b: &Scalar): Scalar { Scalar { data: scalar_mul_internal(a.data, b.data) }}
scalar_mul_assign
Computes the product of ‘a’ and ‘b’ and assigns the result to ‘a’. Returns ‘a’.
public fun scalar_mul_assign(a: &mut ristretto255::Scalar, b: &ristretto255::Scalar): &mut ristretto255::Scalar
Implementation
public fun scalar_mul_assign(a: &mut Scalar, b: &Scalar): &mut Scalar { a.data = scalar_mul(a, b).data; a}
scalar_add
Returns the sum of the two scalars.
public fun scalar_add(a: &ristretto255::Scalar, b: &ristretto255::Scalar): ristretto255::Scalar
Implementation
public fun scalar_add(a: &Scalar, b: &Scalar): Scalar { Scalar { data: scalar_add_internal(a.data, b.data) }}
scalar_add_assign
Computes the sum of ‘a’ and ‘b’ and assigns the result to ‘a’ Returns ‘a’.
public fun scalar_add_assign(a: &mut ristretto255::Scalar, b: &ristretto255::Scalar): &mut ristretto255::Scalar
Implementation
public fun scalar_add_assign(a: &mut Scalar, b: &Scalar): &mut Scalar { a.data = scalar_add(a, b).data; a}
scalar_sub
Returns the difference of the two scalars.
public fun scalar_sub(a: &ristretto255::Scalar, b: &ristretto255::Scalar): ristretto255::Scalar
Implementation
public fun scalar_sub(a: &Scalar, b: &Scalar): Scalar { Scalar { data: scalar_sub_internal(a.data, b.data) }}
scalar_sub_assign
Subtracts ‘b’ from ‘a’ and assigns the result to ‘a’. Returns ‘a’.
public fun scalar_sub_assign(a: &mut ristretto255::Scalar, b: &ristretto255::Scalar): &mut ristretto255::Scalar
Implementation
public fun scalar_sub_assign(a: &mut Scalar, b: &Scalar): &mut Scalar { a.data = scalar_sub(a, b).data; a}
scalar_neg
Returns the negation of ‘a’: i.e., .
public fun scalar_neg(a: &ristretto255::Scalar): ristretto255::Scalar
Implementation
public fun scalar_neg(a: &Scalar): Scalar { Scalar { data: scalar_neg_internal(a.data) }}
scalar_neg_assign
Replaces ‘a’ by its negation. Returns ‘a’.
public fun scalar_neg_assign(a: &mut ristretto255::Scalar): &mut ristretto255::Scalar
Implementation
public fun scalar_neg_assign(a: &mut Scalar): &mut Scalar { a.data = scalar_neg(a).data; a}
scalar_to_bytes
Returns the byte-representation of the scalar.
public fun scalar_to_bytes(s: &ristretto255::Scalar): vector<u8>
Implementation
public fun scalar_to_bytes(s: &Scalar): vector<u8> { s.data}
new_point_from_sha512_internal
fun new_point_from_sha512_internal(sha2_512_input: vector<u8>): u64
Implementation
native fun new_point_from_sha512_internal(sha2_512_input: vector<u8>): u64;
new_point_from_64_uniform_bytes_internal
fun new_point_from_64_uniform_bytes_internal(bytes: vector<u8>): u64
Implementation
native fun new_point_from_64_uniform_bytes_internal(bytes: vector<u8>): u64;
point_is_canonical_internal
fun point_is_canonical_internal(bytes: vector<u8>): bool
Implementation
native fun point_is_canonical_internal(bytes: vector<u8>): bool;
point_identity_internal
fun point_identity_internal(): u64
Implementation
native fun point_identity_internal(): u64;
point_decompress_internal
fun point_decompress_internal(maybe_non_canonical_bytes: vector<u8>): (u64, bool)
Implementation
native fun point_decompress_internal(maybe_non_canonical_bytes: vector<u8>): (u64, bool);
point_clone_internal
fun point_clone_internal(point_handle: u64): u64
Implementation
native fun point_clone_internal(point_handle: u64): u64;
point_compress_internal
fun point_compress_internal(point: &ristretto255::RistrettoPoint): vector<u8>
Implementation
native fun point_compress_internal(point: &RistrettoPoint): vector<u8>;
point_mul_internal
fun point_mul_internal(point: &ristretto255::RistrettoPoint, a: vector<u8>, in_place: bool): u64
Implementation
native fun point_mul_internal(point: &RistrettoPoint, a: vector<u8>, in_place: bool): u64;
basepoint_mul_internal
fun basepoint_mul_internal(a: vector<u8>): u64
Implementation
native fun basepoint_mul_internal(a: vector<u8>): u64;
basepoint_double_mul_internal
fun basepoint_double_mul_internal(a: vector<u8>, some_point: &ristretto255::RistrettoPoint, b: vector<u8>): u64
Implementation
native fun basepoint_double_mul_internal(a: vector<u8>, some_point: &RistrettoPoint, b: vector<u8>): u64;
point_add_internal
fun point_add_internal(a: &ristretto255::RistrettoPoint, b: &ristretto255::RistrettoPoint, in_place: bool): u64
Implementation
native fun point_add_internal(a: &RistrettoPoint, b: &RistrettoPoint, in_place: bool): u64;
point_sub_internal
fun point_sub_internal(a: &ristretto255::RistrettoPoint, b: &ristretto255::RistrettoPoint, in_place: bool): u64
Implementation
native fun point_sub_internal(a: &RistrettoPoint, b: &RistrettoPoint, in_place: bool): u64;
point_neg_internal
fun point_neg_internal(a: &ristretto255::RistrettoPoint, in_place: bool): u64
Implementation
native fun point_neg_internal(a: &RistrettoPoint, in_place: bool): u64;
double_scalar_mul_internal
fun double_scalar_mul_internal(point1: u64, point2: u64, scalar1: vector<u8>, scalar2: vector<u8>): u64
Implementation
native fun double_scalar_mul_internal(point1: u64, point2: u64, scalar1: vector<u8>, scalar2: vector<u8>): u64;
multi_scalar_mul_internal
The generic arguments are needed to deal with some Move VM peculiarities which prevent us from borrowing the points (or scalars) inside a &vector in Rust.
WARNING: This function can only be called with P = RistrettoPoint and S = Scalar.
fun multi_scalar_mul_internal<P, S>(points: &vector<P>, scalars: &vector<S>): u64
Implementation
native fun multi_scalar_mul_internal<P, S>(points: &vector<P>, scalars: &vector<S>): u64;
scalar_is_canonical_internal
fun scalar_is_canonical_internal(s: vector<u8>): bool
Implementation
native fun scalar_is_canonical_internal(s: vector<u8>): bool;
scalar_from_u64_internal
fun scalar_from_u64_internal(num: u64): vector<u8>
Implementation
native fun scalar_from_u64_internal(num: u64): vector<u8>;
scalar_from_u128_internal
fun scalar_from_u128_internal(num: u128): vector<u8>
Implementation
native fun scalar_from_u128_internal(num: u128): vector<u8>;
scalar_reduced_from_32_bytes_internal
fun scalar_reduced_from_32_bytes_internal(bytes: vector<u8>): vector<u8>
Implementation
native fun scalar_reduced_from_32_bytes_internal(bytes: vector<u8>): vector<u8>;
scalar_uniform_from_64_bytes_internal
fun scalar_uniform_from_64_bytes_internal(bytes: vector<u8>): vector<u8>
Implementation
native fun scalar_uniform_from_64_bytes_internal(bytes: vector<u8>): vector<u8>;
scalar_invert_internal
fun scalar_invert_internal(bytes: vector<u8>): vector<u8>
Implementation
native fun scalar_invert_internal(bytes: vector<u8>): vector<u8>;
scalar_from_sha512_internal
fun scalar_from_sha512_internal(sha2_512_input: vector<u8>): vector<u8>
Implementation
native fun scalar_from_sha512_internal(sha2_512_input: vector<u8>): vector<u8>;
scalar_mul_internal
fun scalar_mul_internal(a_bytes: vector<u8>, b_bytes: vector<u8>): vector<u8>
Implementation
native fun scalar_mul_internal(a_bytes: vector<u8>, b_bytes: vector<u8>): vector<u8>;
scalar_add_internal
fun scalar_add_internal(a_bytes: vector<u8>, b_bytes: vector<u8>): vector<u8>
Implementation
native fun scalar_add_internal(a_bytes: vector<u8>, b_bytes: vector<u8>): vector<u8>;
scalar_sub_internal
fun scalar_sub_internal(a_bytes: vector<u8>, b_bytes: vector<u8>): vector<u8>
Implementation
native fun scalar_sub_internal(a_bytes: vector<u8>, b_bytes: vector<u8>): vector<u8>;
scalar_neg_internal
fun scalar_neg_internal(a_bytes: vector<u8>): vector<u8>
Implementation
native fun scalar_neg_internal(a_bytes: vector<u8>): vector<u8>;
Specification
point_equals
public fun point_equals(g: &ristretto255::RistrettoPoint, h: &ristretto255::RistrettoPoint): bool
pragma opaque;
double_scalar_mul
public fun double_scalar_mul(scalar1: &ristretto255::Scalar, point1: &ristretto255::RistrettoPoint, scalar2: &ristretto255::Scalar, point2: &ristretto255::RistrettoPoint): ristretto255::RistrettoPoint
pragma opaque;
multi_scalar_mul
public fun multi_scalar_mul(points: &vector<ristretto255::RistrettoPoint>, scalars: &vector<ristretto255::Scalar>): ristretto255::RistrettoPoint
aborts_if len(points) == 0;aborts_if len(scalars) == 0;aborts_if len(points) != len(scalars);ensures result.handle == spec_multi_scalar_mul_internal(points, scalars);
new_scalar_from_bytes
public fun new_scalar_from_bytes(bytes: vector<u8>): option::Option<ristretto255::Scalar>
aborts_if false;ensures spec_scalar_is_canonical_internal(bytes) ==> (std::option::spec_is_some(result) && std::option::spec_borrow(result).data == bytes);ensures !spec_scalar_is_canonical_internal(bytes) ==> std::option::spec_is_none(result);
new_scalar_from_sha2_512
public fun new_scalar_from_sha2_512(sha2_512_input: vector<u8>): ristretto255::Scalar
aborts_if false;ensures result.data == spec_scalar_from_sha512_internal(sha2_512_input);
new_scalar_from_u8
public fun new_scalar_from_u8(byte: u8): ristretto255::Scalar
aborts_if false;ensures result.data[0] == byte;ensures forall i in 1..len(result.data): result.data[i] == 0;
new_scalar_from_u32
public fun new_scalar_from_u32(four_bytes: u32): ristretto255::Scalar
aborts_if false;ensures result.data == spec_scalar_from_u64_internal(four_bytes);
new_scalar_from_u64
public fun new_scalar_from_u64(eight_bytes: u64): ristretto255::Scalar
aborts_if false;ensures result.data == spec_scalar_from_u64_internal(eight_bytes);
new_scalar_from_u128
public fun new_scalar_from_u128(sixteen_bytes: u128): ristretto255::Scalar
aborts_if false;ensures result.data == spec_scalar_from_u128_internal(sixteen_bytes);
new_scalar_reduced_from_32_bytes
public fun new_scalar_reduced_from_32_bytes(bytes: vector<u8>): option::Option<ristretto255::Scalar>
ensures len(bytes) != 32 ==> std::option::spec_is_none(result);ensures len(bytes) == 32 ==> std::option::spec_borrow(result).data == spec_scalar_reduced_from_32_bytes_internal(bytes);
new_scalar_uniform_from_64_bytes
public fun new_scalar_uniform_from_64_bytes(bytes: vector<u8>): option::Option<ristretto255::Scalar>
ensures len(bytes) != 64 ==> std::option::spec_is_none(result);ensures len(bytes) == 64 ==> std::option::spec_borrow(result).data == spec_scalar_uniform_from_64_bytes_internal(bytes);
scalar_zero
public fun scalar_zero(): ristretto255::Scalar
ensures spec_scalar_is_zero(result);
scalar_is_zero
public fun scalar_is_zero(s: &ristretto255::Scalar): bool
ensures result == spec_scalar_is_zero(s);
scalar_one
public fun scalar_one(): ristretto255::Scalar
ensures spec_scalar_is_one(result);
scalar_is_one
public fun scalar_is_one(s: &ristretto255::Scalar): bool
ensures result == spec_scalar_is_one(s);
scalar_equals
public fun scalar_equals(lhs: &ristretto255::Scalar, rhs: &ristretto255::Scalar): bool
aborts_if false;ensures result == (lhs.data == rhs.data);
scalar_invert
public fun scalar_invert(s: &ristretto255::Scalar): option::Option<ristretto255::Scalar>
aborts_if false;ensures spec_scalar_is_zero(s) ==> std::option::spec_is_none(result);ensures !spec_scalar_is_zero(s) ==> (std::option::spec_is_some(result) && std::option::spec_borrow(result).data == spec_scalar_invert_internal(s.data));
scalar_mul
public fun scalar_mul(a: &ristretto255::Scalar, b: &ristretto255::Scalar): ristretto255::Scalar
aborts_if false;ensures result.data == spec_scalar_mul_internal(a.data, b.data);
scalar_mul_assign
public fun scalar_mul_assign(a: &mut ristretto255::Scalar, b: &ristretto255::Scalar): &mut ristretto255::Scalar
aborts_if false;ensures a.data == spec_scalar_mul_internal(old(a).data, b.data);
scalar_add
public fun scalar_add(a: &ristretto255::Scalar, b: &ristretto255::Scalar): ristretto255::Scalar
aborts_if false;ensures result.data == spec_scalar_add_internal(a.data, b.data);
scalar_add_assign
public fun scalar_add_assign(a: &mut ristretto255::Scalar, b: &ristretto255::Scalar): &mut ristretto255::Scalar
aborts_if false;ensures a.data == spec_scalar_add_internal(old(a).data, b.data);
scalar_sub
public fun scalar_sub(a: &ristretto255::Scalar, b: &ristretto255::Scalar): ristretto255::Scalar
aborts_if false;ensures result.data == spec_scalar_sub_internal(a.data, b.data);
scalar_sub_assign
public fun scalar_sub_assign(a: &mut ristretto255::Scalar, b: &ristretto255::Scalar): &mut ristretto255::Scalar
aborts_if false;ensures a.data == spec_scalar_sub_internal(old(a).data, b.data);
scalar_neg
public fun scalar_neg(a: &ristretto255::Scalar): ristretto255::Scalar
pragma opaque;aborts_if false;ensures result.data == spec_scalar_neg_internal(a.data);
scalar_neg_assign
public fun scalar_neg_assign(a: &mut ristretto255::Scalar): &mut ristretto255::Scalar
aborts_if false;ensures a.data == spec_scalar_neg_internal(old(a).data);
scalar_to_bytes
public fun scalar_to_bytes(s: &ristretto255::Scalar): vector<u8>
aborts_if false;ensures result == s.data;
Helper functions
fun spec_scalar_is_zero(s: Scalar): bool { s.data == x"0000000000000000000000000000000000000000000000000000000000000000"}
fun spec_scalar_is_one(s: Scalar): bool { s.data == x"0100000000000000000000000000000000000000000000000000000000000000"}
fun spec_point_is_canonical_internal(bytes: vector<u8>): bool;
fun spec_double_scalar_mul_internal(point1: u64, point2: u64, scalar1: vector<u8>, scalar2: vector<u8>): u64;
fun spec_multi_scalar_mul_internal<P, S>(points: vector<P>, scalars: vector<S>): u64;
fun spec_scalar_is_canonical_internal(s: vector<u8>): bool;
fun spec_scalar_from_u64_internal(num: u64): vector<u8>;
fun spec_scalar_from_u128_internal(num: u128): vector<u8>;
fun spec_scalar_reduced_from_32_bytes_internal(bytes: vector<u8>): vector<u8>;
fun spec_scalar_uniform_from_64_bytes_internal(bytes: vector<u8>): vector<u8>;
fun spec_scalar_invert_internal(bytes: vector<u8>): vector<u8>;
fun spec_scalar_from_sha512_internal(sha2_512_input: vector<u8>): vector<u8>;
fun spec_scalar_mul_internal(a_bytes: vector<u8>, b_bytes: vector<u8>): vector<u8>;
fun spec_scalar_add_internal(a_bytes: vector<u8>, b_bytes: vector<u8>): vector<u8>;
fun spec_scalar_sub_internal(a_bytes: vector<u8>, b_bytes: vector<u8>): vector<u8>;
fun spec_scalar_neg_internal(a_bytes: vector<u8>): vector<u8>;
new_point_from_sha512_internal
fun new_point_from_sha512_internal(sha2_512_input: vector<u8>): u64
pragma opaque;
new_point_from_64_uniform_bytes_internal
fun new_point_from_64_uniform_bytes_internal(bytes: vector<u8>): u64
pragma opaque;
point_is_canonical_internal
fun point_is_canonical_internal(bytes: vector<u8>): bool
pragma opaque;aborts_if [abstract] false;ensures result == spec_point_is_canonical_internal(bytes);
point_identity_internal
fun point_identity_internal(): u64
pragma opaque;
point_decompress_internal
fun point_decompress_internal(maybe_non_canonical_bytes: vector<u8>): (u64, bool)
pragma opaque;
point_clone_internal
fun point_clone_internal(point_handle: u64): u64
pragma opaque;
point_compress_internal
fun point_compress_internal(point: &ristretto255::RistrettoPoint): vector<u8>
pragma opaque;
point_mul_internal
fun point_mul_internal(point: &ristretto255::RistrettoPoint, a: vector<u8>, in_place: bool): u64
pragma opaque;
basepoint_mul_internal
fun basepoint_mul_internal(a: vector<u8>): u64
pragma opaque;
basepoint_double_mul_internal
fun basepoint_double_mul_internal(a: vector<u8>, some_point: &ristretto255::RistrettoPoint, b: vector<u8>): u64
pragma opaque;
point_add_internal
fun point_add_internal(a: &ristretto255::RistrettoPoint, b: &ristretto255::RistrettoPoint, in_place: bool): u64
pragma opaque;
point_sub_internal
fun point_sub_internal(a: &ristretto255::RistrettoPoint, b: &ristretto255::RistrettoPoint, in_place: bool): u64
pragma opaque;
point_neg_internal
fun point_neg_internal(a: &ristretto255::RistrettoPoint, in_place: bool): u64
pragma opaque;
double_scalar_mul_internal
fun double_scalar_mul_internal(point1: u64, point2: u64, scalar1: vector<u8>, scalar2: vector<u8>): u64
pragma opaque;
multi_scalar_mul_internal
fun multi_scalar_mul_internal<P, S>(points: &vector<P>, scalars: &vector<S>): u64
pragma opaque;aborts_if [abstract] false;ensures result == spec_multi_scalar_mul_internal<P, S>(points, scalars);
scalar_is_canonical_internal
fun scalar_is_canonical_internal(s: vector<u8>): bool
pragma opaque;aborts_if [abstract] false;ensures result == spec_scalar_is_canonical_internal(s);
scalar_from_u64_internal
fun scalar_from_u64_internal(num: u64): vector<u8>
pragma opaque;aborts_if [abstract] false;ensures result == spec_scalar_from_u64_internal(num);
scalar_from_u128_internal
fun scalar_from_u128_internal(num: u128): vector<u8>
pragma opaque;aborts_if [abstract] false;ensures result == spec_scalar_from_u128_internal(num);
scalar_reduced_from_32_bytes_internal
fun scalar_reduced_from_32_bytes_internal(bytes: vector<u8>): vector<u8>
pragma opaque;ensures result == spec_scalar_reduced_from_32_bytes_internal(bytes);
scalar_uniform_from_64_bytes_internal
fun scalar_uniform_from_64_bytes_internal(bytes: vector<u8>): vector<u8>
pragma opaque;aborts_if [abstract] false;ensures result == spec_scalar_uniform_from_64_bytes_internal(bytes);
scalar_invert_internal
fun scalar_invert_internal(bytes: vector<u8>): vector<u8>
pragma opaque;aborts_if [abstract] false;ensures result == spec_scalar_invert_internal(bytes);
scalar_from_sha512_internal
fun scalar_from_sha512_internal(sha2_512_input: vector<u8>): vector<u8>
pragma opaque;aborts_if [abstract] false;ensures result == spec_scalar_from_sha512_internal(sha2_512_input);
scalar_mul_internal
fun scalar_mul_internal(a_bytes: vector<u8>, b_bytes: vector<u8>): vector<u8>
pragma opaque;aborts_if [abstract] false;ensures result == spec_scalar_mul_internal(a_bytes, b_bytes);
scalar_add_internal
fun scalar_add_internal(a_bytes: vector<u8>, b_bytes: vector<u8>): vector<u8>
pragma opaque;aborts_if [abstract] false;ensures result == spec_scalar_add_internal(a_bytes, b_bytes);
scalar_sub_internal
fun scalar_sub_internal(a_bytes: vector<u8>, b_bytes: vector<u8>): vector<u8>
pragma opaque;aborts_if [abstract] false;ensures result == spec_scalar_sub_internal(a_bytes, b_bytes);
scalar_neg_internal
fun scalar_neg_internal(a_bytes: vector<u8>): vector<u8>
pragma opaque;aborts_if [abstract] false;ensures result == spec_scalar_neg_internal(a_bytes);