Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

'seal.Ciphertext' object attribute 'scale' is read-only #118

Open
qub1tt opened this issue Apr 11, 2024 · 5 comments
Open

'seal.Ciphertext' object attribute 'scale' is read-only #118

qub1tt opened this issue Apr 11, 2024 · 5 comments
Labels
bug Something isn't working

Comments

@qub1tt
Copy link

qub1tt commented Apr 11, 2024

Hello, i use this library for a project use Homomorphic Encryption in RF based on this repo https://github.com/dhuynh95/cryptotree/

I tried to convert all the function from tenSEAL to your library standards because in tenSEAL API, the create_public_key() function don't work and i don't know why so I found this library and decided to use it since it's working fine. Until i encountered a problem in https://github.com/dhuynh95/cryptotree/blob/master/nbs/03_polynomials.ipynb

from typing import List, Union

def multiply_and_add_coeffs(powers: List[seal.Ciphertext], plain_coeffs: List[seal.Plaintext],
                            coeffs: List[float],
                            evaluator: seal.Evaluator,
                            scale: float,
                            tol=1e-6) -> Union[seal.Ciphertext]:
    assert len(powers) == len(plain_coeffs), f"Mismatch between length between powers {len(powers)} and coeffs {len(coeffs)}"
    
    """Multiplies the coefficients with the corresponding powers andd adds everything.
    
    If the polynomial is non-constant, returns the ciphertext of the polynomial evaluation.
    Else if the polynomials is constant, the plaintext of the constant term is returned.
    """
    output = seal.Ciphertext()
    a0 = plain_coeffs[0]
    a0_added = False

    for i in range(1, len(plain_coeffs)):
        # We first check if the coefficient is not too small otherwise we skip it
        coef = coeffs[i]
        if np.abs(coef) < tol:
            continue
            
        plain_coeff = plain_coeffs[i]
        power = powers[i]
        
        evaluator.mod_switch_to_inplace(plain_coeff, power.parms_id())
        
        temp = evaluator.multiply_plain(power, plain_coeff)
        evaluator.rescale_to_next_inplace(temp)


        if not a0_added:
            evaluator.mod_switch_to_inplace(a0, temp.parms_id())
            temp.scale = scale
            output = evaluator.add_plain(temp, a0)
            a0_added = True
        else:
            evaluator.mod_switch_to_inplace(output, temp.parms_id())
            # We rescale both to the same scale
            output.scale = scale
            temp.scale = scale
            evaluator.add_inplace(output, temp)
    if a0_added:
        return output
    else:
        return a0

And when i call the function:

def polyeval_tree(ctx : seal.Ciphertext, coeffs: List[float], 
                  evaluator: seal.Evaluator, encoder : seal.Encryptor,
                  relin_keys: seal.RelinKeys,
                  scale: float):
    
    degree = len(coeffs) - 1
    plain_coeffs = coeffs_to_plaintext(coeffs, encoder, scale)
    powers = compute_all_powers(ctx, degree, evaluator, relin_keys)
    output = multiply_and_add_coeffs(powers, plain_coeffs, coeffs, evaluator, scale)
    
    return output

coeffs = [1.0,0.0,1.0]

ptx = encoder.encode(2.0, scale)

print("Initial vector input : ") 
print_ptx(ptx)


ctx = encryptor.encrypt(ptx)

output = polyeval_tree(ctx, coeffs, evaluator, encoder, relin_keys, scale)

print("Polynomial considered : X^2 + 1")
print(f"Associated coeffs : {coeffs}")
print("Output of polynomials : ")
print_ctx(output)

I have this error:

Cell In[113], line 37
35 if not a0_added:
36 evaluator.mod_switch_to_inplace(a0, temp.parms_id())
---> 37 temp.scale = scale
38 output = evaluator.add_plain(temp, a0)
39 a0_added = True
AttributeError: 'seal.Ciphertext' object attribute 'scale' is read-only

Does it mean that the scale attribute cannot be change in a Ciphertext object?
Appreciate if you can help me solve this problem because i intend to use this for my Cryptography project in uni. Thank you!

@qub1tt qub1tt added the bug Something isn't working label Apr 11, 2024
@Huelse
Copy link
Owner

Huelse commented Apr 12, 2024

There are some differences, you can read the scale by old_value = cipher.scale() and set the scale by cipher.scale(new_value).
Check the examples may also help you.

@qub1tt
Copy link
Author

qub1tt commented Apr 13, 2024

Thanks for the reply! I got the code run perfectly. Sorry i want to ask one more thing, i've found there is a function name encrypt_symmetric() and apparently it's from the tenseal API library.
image

This is from tenSEAL:
image
This is from your library:
image

In this library there is no encrypt_symmetric() just normal encrypt(), so I want to know what's the difference between these 2 functions? and if i want to use the symmetric one in this library what function i have to call?
Thanks again!

@qub1tt qub1tt closed this as completed Apr 13, 2024
@qub1tt qub1tt reopened this Apr 13, 2024
@qub1tt qub1tt closed this as completed Apr 13, 2024
@qub1tt qub1tt reopened this Apr 13, 2024
@Huelse
Copy link
Owner

Huelse commented Apr 14, 2024

The encrypt_symmetric methods were added at SEAL v3.4.0, it is used to generate the Ciphertext in secret-key mode, witch need an Encryptor init by the secret key, link.
You can use it is this library now.

@qub1tt
Copy link
Author

qub1tt commented Apr 14, 2024

It said public key is not set, i know the init for p is not right i just want to test the function. It seems like it only encrypt with public key
image

@Huelse
Copy link
Owner

Huelse commented Apr 17, 2024

I mean you could use encrypt_symmetric now, repull the code and build the lib.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants