ristretto255_elgamal - [mainnet]
This module implements an ElGamal encryption API, over the Ristretto255 curve, that can be used with the Bulletproofs module.
An ElGamal ciphertext is an encryption of a value v
under a basepoint G
and public key Y = sk * G
, where sk
is the corresponding secret key, is (v * G + r * Y, r * G)
, for a random scalar r
.
Note that we place the value v
“in the exponent” of G
so that ciphertexts are additively homomorphic: i.e., so
that Enc_Y(v, r) + Enc_Y(v’, r’) = Enc_Y(v + v’, r + r’)
where v, v’
are plaintext messages, Y
is a public key and r, r’
are the randomness of the ciphertexts.
use 0x1::option;use 0x1::ristretto255;use 0x1::vector;
Structs
Ciphertext
An ElGamal ciphertext.
struct Ciphertext has drop
Fields
-
left: ristretto255::RistrettoPoint
-
right: ristretto255::RistrettoPoint
CompressedCiphertext
A compressed ElGamal ciphertext.
struct CompressedCiphertext has copy, drop, store
Fields
CompressedPubkey
An ElGamal public key.
struct CompressedPubkey has copy, drop, store
Fields
Functions
new_pubkey_from_bytes
Creates a new public key from a serialized Ristretto255 point.
public fun new_pubkey_from_bytes(bytes: vector<u8>): option::Option<ristretto255_elgamal::CompressedPubkey>
Implementation
public fun new_pubkey_from_bytes(bytes: vector<u8>): Option<CompressedPubkey> { let point = ristretto255::new_compressed_point_from_bytes(bytes); if (point.is_some()) { let pk = CompressedPubkey { point: point.extract() }; std::option::some(pk) } else { std::option::none<CompressedPubkey>() }}
pubkey_to_bytes
Given an ElGamal public key pubkey
, returns the byte representation of that public key.
public fun pubkey_to_bytes(pubkey: &ristretto255_elgamal::CompressedPubkey): vector<u8>
Implementation
public fun pubkey_to_bytes(pubkey: &CompressedPubkey): vector<u8> { ristretto255::compressed_point_to_bytes(pubkey.point)}
pubkey_to_point
Given a public key pubkey
, returns the underlying RistrettoPoint
representing that key.
public fun pubkey_to_point(pubkey: &ristretto255_elgamal::CompressedPubkey): ristretto255::RistrettoPoint
Implementation
public fun pubkey_to_point(pubkey: &CompressedPubkey): RistrettoPoint { ristretto255::point_decompress(&pubkey.point)}
pubkey_to_compressed_point
Given a public key, returns the underlying CompressedRistretto
point representing that key.
public fun pubkey_to_compressed_point(pubkey: &ristretto255_elgamal::CompressedPubkey): ristretto255::CompressedRistretto
Implementation
public fun pubkey_to_compressed_point(pubkey: &CompressedPubkey): CompressedRistretto { pubkey.point}
new_ciphertext_from_bytes
Creates a new ciphertext from two serialized Ristretto255 points: the first 32 bytes store r * G
while the
next 32 bytes store v * G + r * Y
, where Y
is the public key.
public fun new_ciphertext_from_bytes(bytes: vector<u8>): option::Option<ristretto255_elgamal::Ciphertext>
Implementation
public fun new_ciphertext_from_bytes(bytes: vector<u8>): Option<Ciphertext> { if(bytes.length() != 64) { return std::option::none<Ciphertext>() };
let bytes_right = bytes.trim(32);
let left_point = ristretto255::new_point_from_bytes(bytes); let right_point = ristretto255::new_point_from_bytes(bytes_right);
if (left_point.is_some::<RistrettoPoint>() && right_point.is_some::<RistrettoPoint>()) { std::option::some<Ciphertext>(Ciphertext { left: left_point.extract::<RistrettoPoint>(), right: right_point.extract::<RistrettoPoint>() }) } else { std::option::none<Ciphertext>() }}
new_ciphertext_no_randomness
Creates a new ciphertext (val * G + 0 * Y, 0 * G) = (val * G, 0 * G)
where G
is the Ristretto255 basepoint
and the randomness is set to zero.
public fun new_ciphertext_no_randomness(val: &ristretto255::Scalar): ristretto255_elgamal::Ciphertext
Implementation
public fun new_ciphertext_no_randomness(val: &Scalar): Ciphertext { Ciphertext { left: ristretto255::basepoint_mul(val), right: ristretto255::point_identity(), }}
ciphertext_from_points
Moves a pair of Ristretto points into an ElGamal ciphertext.
public fun ciphertext_from_points(left: ristretto255::RistrettoPoint, right: ristretto255::RistrettoPoint): ristretto255_elgamal::Ciphertext
Implementation
public fun ciphertext_from_points(left: RistrettoPoint, right: RistrettoPoint): Ciphertext { Ciphertext { left, right, }}
ciphertext_from_compressed_points
Moves a pair of CompressedRistretto
points into an ElGamal ciphertext.
public fun ciphertext_from_compressed_points(left: ristretto255::CompressedRistretto, right: ristretto255::CompressedRistretto): ristretto255_elgamal::CompressedCiphertext
Implementation
public fun ciphertext_from_compressed_points(left: CompressedRistretto, right: CompressedRistretto): CompressedCiphertext { CompressedCiphertext { left, right, }}
ciphertext_to_bytes
Given a ciphertext ct
, serializes that ciphertext into bytes.
public fun ciphertext_to_bytes(ct: &ristretto255_elgamal::Ciphertext): vector<u8>
Implementation
public fun ciphertext_to_bytes(ct: &Ciphertext): vector<u8> { let bytes_left = ristretto255::point_to_bytes(&ristretto255::point_compress(&ct.left)); let bytes_right = ristretto255::point_to_bytes(&ristretto255::point_compress(&ct.right)); let bytes = vector::empty<u8>(); bytes.append::<u8>(bytes_left); bytes.append::<u8>(bytes_right); bytes}
ciphertext_into_points
Moves the ciphertext into a pair of RistrettoPoint
’s.
public fun ciphertext_into_points(c: ristretto255_elgamal::Ciphertext): (ristretto255::RistrettoPoint, ristretto255::RistrettoPoint)
Implementation
public fun ciphertext_into_points(c: Ciphertext): (RistrettoPoint, RistrettoPoint) { let Ciphertext { left, right } = c; (left, right)}
ciphertext_as_points
Returns the pair of RistrettoPoint
’s representing the ciphertext.
public fun ciphertext_as_points(c: &ristretto255_elgamal::Ciphertext): (&ristretto255::RistrettoPoint, &ristretto255::RistrettoPoint)
Implementation
public fun ciphertext_as_points(c: &Ciphertext): (&RistrettoPoint, &RistrettoPoint) { (&c.left, &c.right)}
compress_ciphertext
Creates a new compressed ciphertext from a decompressed ciphertext.
public fun compress_ciphertext(ct: &ristretto255_elgamal::Ciphertext): ristretto255_elgamal::CompressedCiphertext
Implementation
public fun compress_ciphertext(ct: &Ciphertext): CompressedCiphertext { CompressedCiphertext { left: point_compress(&ct.left), right: point_compress(&ct.right), }}
decompress_ciphertext
Creates a new decompressed ciphertext from a compressed ciphertext.
public fun decompress_ciphertext(ct: &ristretto255_elgamal::CompressedCiphertext): ristretto255_elgamal::Ciphertext
Implementation
public fun decompress_ciphertext(ct: &CompressedCiphertext): Ciphertext { Ciphertext { left: ristretto255::point_decompress(&ct.left), right: ristretto255::point_decompress(&ct.right), }}
ciphertext_add
Homomorphically combines two ciphertexts lhs
and rhs
as lhs + rhs
.
Useful for re-randomizing the ciphertext or updating the committed value.
public fun ciphertext_add(lhs: &ristretto255_elgamal::Ciphertext, rhs: &ristretto255_elgamal::Ciphertext): ristretto255_elgamal::Ciphertext
Implementation
public fun ciphertext_add(lhs: &Ciphertext, rhs: &Ciphertext): Ciphertext { Ciphertext { left: ristretto255::point_add(&lhs.left, &rhs.left), right: ristretto255::point_add(&lhs.right, &rhs.right), }}
ciphertext_add_assign
Like ciphertext_add
but assigns lhs = lhs + rhs
.
public fun ciphertext_add_assign(lhs: &mut ristretto255_elgamal::Ciphertext, rhs: &ristretto255_elgamal::Ciphertext)
Implementation
public fun ciphertext_add_assign(lhs: &mut Ciphertext, rhs: &Ciphertext) { ristretto255::point_add_assign(&mut lhs.left, &rhs.left); ristretto255::point_add_assign(&mut lhs.right, &rhs.right);}
ciphertext_sub
Homomorphically combines two ciphertexts lhs
and rhs
as lhs - rhs
.
Useful for re-randomizing the ciphertext or updating the committed value.
public fun ciphertext_sub(lhs: &ristretto255_elgamal::Ciphertext, rhs: &ristretto255_elgamal::Ciphertext): ristretto255_elgamal::Ciphertext
Implementation
public fun ciphertext_sub(lhs: &Ciphertext, rhs: &Ciphertext): Ciphertext { Ciphertext { left: ristretto255::point_sub(&lhs.left, &rhs.left), right: ristretto255::point_sub(&lhs.right, &rhs.right), }}
ciphertext_sub_assign
Like ciphertext_add
but assigns lhs = lhs - rhs
.
public fun ciphertext_sub_assign(lhs: &mut ristretto255_elgamal::Ciphertext, rhs: &ristretto255_elgamal::Ciphertext)
Implementation
public fun ciphertext_sub_assign(lhs: &mut Ciphertext, rhs: &Ciphertext) { ristretto255::point_sub_assign(&mut lhs.left, &rhs.left); ristretto255::point_sub_assign(&mut lhs.right, &rhs.right);}
ciphertext_clone
Creates a copy of this ciphertext.
public fun ciphertext_clone(c: &ristretto255_elgamal::Ciphertext): ristretto255_elgamal::Ciphertext
Implementation
public fun ciphertext_clone(c: &Ciphertext): Ciphertext { Ciphertext { left: ristretto255::point_clone(&c.left), right: ristretto255::point_clone(&c.right), }}
ciphertext_equals
Returns true if the two ciphertexts are identical: i.e., same value and same randomness.
public fun ciphertext_equals(lhs: &ristretto255_elgamal::Ciphertext, rhs: &ristretto255_elgamal::Ciphertext): bool
Implementation
public fun ciphertext_equals(lhs: &Ciphertext, rhs: &Ciphertext): bool { ristretto255::point_equals(&lhs.left, &rhs.left) && ristretto255::point_equals(&lhs.right, &rhs.right)}
get_value_component
Returns the RistrettoPoint
in the ciphertext which contains the encrypted value in the exponent.
public fun get_value_component(ct: &ristretto255_elgamal::Ciphertext): &ristretto255::RistrettoPoint
Implementation
public fun get_value_component(ct: &Ciphertext): &RistrettoPoint { &ct.left}