mirror of
https://github.com/luxfhe/example-playground.git
synced 2026-10-30 18:13:21 +00:00
97 lines
4.5 KiB
Solidity
97 lines
4.5 KiB
Solidity
// SPDX-License-Identifier: BSD-3-Clause-Clear
|
|
|
|
pragma solidity >=0.8.13 <0.9.0;
|
|
|
|
import { euint32, ebool, FHE } from "@luxfi/contracts/fhe/FHE.sol";
|
|
import "./BytesLib.sol";
|
|
|
|
/// @title Encrypted Address Library
|
|
/// @notice Provides methods for creating and managing addresses encrypted with FHE (Fully Homomorphic Encryption)
|
|
/// @dev Assumes the existence of an FHE library that implements fully homomorphic encryption functions
|
|
|
|
/// @dev A representation of an encrypted address using Fully Homomorphic Encryption.
|
|
/// It consists of 5 encrypted 32-bit unsigned integers (`euint32`).
|
|
struct Eaddress {
|
|
euint32[5] values;
|
|
}
|
|
|
|
library ConfAddress {
|
|
/// @notice Encrypts a plaintext Ethereum address into its encrypted representation (`eaddress`).
|
|
/// @dev Iterates over 5 chunks of the address, applying a bitmask to each, then encrypting with `FHE`.
|
|
/// @param addr The plain Ethereum address to encrypt
|
|
/// @return eaddr The encrypted representation of the address
|
|
function toEaddress(address payable addr) internal returns (Eaddress memory) {
|
|
uint160 addrValue = uint160(address(addr));
|
|
/// @dev A bitmask constant for selecting specific 32-bit chunks from a 160-bit Ethereum address.
|
|
/// It has the first 32 bits set to 1, and the remaining bits set to 0.
|
|
uint160 MASK =
|
|
uint160(uint256(0x000000000000000000000000FFFFFFFF00000000000000000000000000000000));
|
|
|
|
Eaddress memory eaddr;
|
|
|
|
for (uint i = 0; i < 5; i++) {
|
|
uint160 currentChunkOffset = uint160(i * 32);
|
|
uint160 mask = MASK >> currentChunkOffset; // Mask the correct chunk based on i
|
|
uint32 chunk = uint32((addrValue & mask) >> (128 - currentChunkOffset));
|
|
eaddr.values[i] = FHE.asEuint32(chunk);
|
|
}
|
|
|
|
return eaddr;
|
|
}
|
|
|
|
/// @notice Placeholder for async decryption of an encrypted address.
|
|
/// @dev In production, implement IAsyncFHEReceiver for Gateway callback pattern.
|
|
/// This simplified version returns address(0) as decryption requires async flow.
|
|
/// @param eaddr The encrypted address (unused in simplified version)
|
|
/// @return address(0) - implement Gateway callback for actual decryption
|
|
function unsafeToAddress(Eaddress memory eaddr) internal pure returns (address) {
|
|
// Suppress unused parameter warning
|
|
eaddr;
|
|
// Note: Actual decryption requires Gateway async callback pattern
|
|
// In production, request decryption and handle result in callback
|
|
return address(0);
|
|
}
|
|
|
|
/// @notice Re-encrypts the encrypted values within an `eaddress`.
|
|
/// @dev The re-encryption is done to change the encrypted representation without
|
|
/// altering the underlying plaintext address, which can be useful for obfuscation purposes in storage.
|
|
/// @param eaddr The encrypted address to re-encrypt
|
|
/// @param ezero An encrypted zero value that triggers the re-encryption
|
|
function resestEaddress(Eaddress memory eaddr, euint32 ezero) internal returns (Eaddress memory) {
|
|
for (uint i = 0; i < 5; i++) {
|
|
// Adding zero will practically reencrypt the value without it being changed
|
|
eaddr.values[i] = FHE.add(eaddr.values[i], ezero);
|
|
}
|
|
return eaddr;
|
|
}
|
|
|
|
/// @notice Determines if an encrypted address is equal to a given plaintext Ethereum address.
|
|
/// @dev This operation encrypts the plaintext address and compares the encrypted representations.
|
|
/// @param lhs The encrypted address to compare
|
|
/// @param addr The plaintext Ethereum address to compare against
|
|
/// @return res A boolean indicating if the encrypted and plaintext addresses are equal
|
|
function equals(Eaddress storage lhs, address payable addr) internal returns (ebool) {
|
|
Eaddress memory rhs = toEaddress(addr);
|
|
ebool res = FHE.eq(lhs.values[0], rhs.values[0]);
|
|
for (uint i = 1; i < 5; i++) {
|
|
res = FHE.and(res, FHE.eq(lhs.values[i], rhs.values[i]));
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
function conditionalUpdate(
|
|
ebool condition,
|
|
Eaddress memory eaddr,
|
|
Eaddress memory newEaddr
|
|
) internal returns (Eaddress memory) {
|
|
for (uint i = 0; i < 5; i++) {
|
|
// Even if condition is false the ENCRYPTED value of eaddr.values[i] will be changed
|
|
// because the encryption is not deterministic
|
|
// so no one will know whether the highest bidder was changed or not
|
|
eaddr.values[i] = FHE.select(condition, newEaddr.values[i], eaddr.values[i]);
|
|
}
|
|
|
|
return eaddr;
|
|
}
|
|
} |