Skip to content

feat: Support encrypt_for_round in rust+javascript #397

Open
@feltroidprime

Description

@feltroidprime

Feature Request

Implement Rust equivalent of the encrypt_for_round

def encrypt_for_round(
drand_public_key: G2Point, round: int, message: bytes, debug: bool = False
) -> CipherText:
assert len(message) == 16, f"Message should be 16 bytes: {len(message)}"
msg_at_round = digest_func(round)
# print(f"msg_at_round list of ints: {list(msg_at_round)}")
pt_at_round = hash_to_curve(msg_at_round, CurveID.BLS12_381)
gid: E12 = G1G2Pair.pair([G1G2Pair(p=pt_at_round, q=drand_public_key)])
if debug:
# Use a fixed sigma for debugging:
sigma = b"0000000000000000"
else:
sigma: bytes = secrets.token_bytes(16)
assert len(sigma) == 16
hasher = hashlib.sha256()
hasher.update(b"IBE-H3")
hasher.update(sigma)
hasher.update(message)
r = int.from_bytes(expand_message_drand(hasher.digest(), 32), "little")
# print(f"r list of ints: {r}")
r = r % CURVES[CurveID.BLS12_381.value].n
# U = r * G2
U = G2Point.get_nG(CurveID.BLS12_381, r)
# print(f"U: {U}")
# V = sigma XOR H (rGid)
rGid: E12 = gid**r
# print(f"rGid: {rGid.value_coeffs}")
rgid_serialized = rGid.serialize()
# Print bytes as hex strings:
# print(f"rGid hex : {rgid_serialized.hex()}")
# print(f"rGid serialized: {list(rgid_serialized)} len: {len(rgid_serialized)}")
rgid_hash = hashlib.sha256()
rgid_hash.update(b"IBE-H2")
rgid_hash.update(rgid_serialized)
rgid_hash = rgid_hash.digest()
# Take first 16 bytes only :
rgid_hash = rgid_hash[:16]
# print(f"rgid_hash hex: {rgid_hash.hex()}")
V = bytes([a ^ b for a, b in zip(sigma, rgid_hash)])
# print(f"V hex: {V.hex()}")
# 6. Compute W = M XOR H(sigma)
W = bytes([a ^ b for a, b in zip(message, rgid_hash)])
sigma_hash = hashlib.sha256()
sigma_hash.update(b"IBE-H4")
sigma_hash.update(sigma)
sigma_hash = sigma_hash.digest()[:16] # First 16 bytes only
# print(f"sigma_hash hex: {sigma_hash.hex()}")
W = bytes([a ^ b for a, b in zip(message, sigma_hash)])
# print(f"W hex: {W.hex()}")
return CipherText(U, V, W)
function, which is the counterpart of the decrypt_at_round in Cairo.
pub fn decrypt_at_round(signature_at_round: G1Point, ciphertext: CipherText) -> [u8; 16] {

  • Users should be able to encrypt a msg for a specific round OR a specific time from Rust and javascript with the wasm binding. Add a time_to_round_number function and provide both alternatives.
  • the output (as list of Felt/BigUint) should be serialized for the Corresponding Cairo struct ciphertext :
    pub struct CipherText {
    U: G2Point,
    V: [u8; 16],
    W: [u8; 16],
    }
  • Carefully handle errors with Result<>, especially for input larger than 16 bytes.
  • Use cryptographically secure random number generation (similar to the secrets lib in python which is more secure than random)

Test by :

Final note :
For rust and typescript, we can drop the drand_public_key: G2Point parameter and assume a default public key which will be the drand quicknet public key.

Metadata

Metadata

Assignees

Labels

enhancementEnhancement of the code, not introducing new features.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions