-
Notifications
You must be signed in to change notification settings - Fork 79
Open
Labels
enhancementEnhancement of the code, not introducing new features.Enhancement of the code, not introducing new features.
Description
Feature Request
Implement Rust equivalent of the encrypt_for_round
garaga/hydra/garaga/drand/tlock.py
Lines 30 to 91 in d71cc28
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) |
garaga/src/src/utils/drand.cairo
Line 693 in d71cc28
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 :
garaga/src/src/utils/drand.cairo
Lines 532 to 536 in d71cc28
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 thanrandom
)
Test by :
- adding a method serialize_to_calldata to the Python Ciphertext struct https://github.com/keep-starknet-strange/garaga/blob/d71cc28b8aa8066d27f02e84fc4577b156533be5/hydra/garaga/drand/tlock.py#L12C1-L27C20 or other relevant methods
- adding a python binding for the rust encrypt_for_round function
- test ciphertexts as calldata are equal for similar inputs (use debug mode or a variant to use same secrets on both sides)
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.Enhancement of the code, not introducing new features.