GithubHelp home page GithubHelp logo

tuneinsight / lattigo Goto Github PK

View Code? Open in Web Editor NEW
1.2K 29.0 173.0 11.35 MB

A library for lattice-based multiparty homomorphic encryption in Go

License: Apache License 2.0

Makefile 0.09% Go 99.91%
lattice-based-crypto secure-multi-party-computation homomorphic-encryption

lattigo's Introduction

Lattigo: lattice-based multiparty homomorphic encryption library in Go

Go tests

Lattigo is a Go module that implements full-RNS Ring-Learning-With-Errors-based homomorphic-encryption primitives and Multiparty-Homomorphic-Encryption-based secure protocols. The library features:

  • Optimized arithmetic for power-of-two cyclotomic rings.
  • Advanced and scheme-agnostic implementation of RLWE-based primitives, key-generation, and their multiparty version.
  • Implementation of the BFV/BGV and CKKS schemes and their multiparty version.
  • Support for RGSW, external product and LMKCDEY blind rotations.
  • A pure Go implementation, enabling cross-platform builds, including WASM compilation for browser clients, with comparable performance to state-of-the-art C++ libraries.

Lattigo is meant to support HE in distributed systems and microservices architectures, for which Go is a common choice thanks to its natural concurrency model and portability.

Library overview

lattigo-hierarchy

Lattigo is a strictly hierarchical library whose packages form a linear dependency chain ranging from low-level arithmetic functionalities to high-level homomorphic circuits. A graphical depiction of the Lattigo package organization is given in the Figure above.

  • lattigo/ring: At the lowest level resides the ring package providing modular arithmetic operations for polynomials in the RNS basis, including: RNS basis extension; RNS rescaling; number theoretic transform (NTT); uniform, Gaussian and ternary sampling.

    • lattigo/core: This package implements the core cryptographic functionalities of the library and builds directly upon the arithmetic functionalities provided by the ring package:

      • rlwe: Common base for generic RLWE-based homomorphic encryption. It provides all homomorphic functionalities and defines all structs that are not scheme-specific. This includes plaintext, ciphertext, key-generation, encryption, decryption and key-switching, as well as other more advanced primitives such as RLWE-repacking.

      • rgsw: A Full-RNS variant of Ring-GSW ciphertexts and the external product.

  • lattigo/schemes: The implementation of RLWE-based homomorphic encryption schemes are found in the schemes package:

    • bfv: A Full-RNS variant of the Brakerski-Fan-Vercauteren scale-invariant homomorphic encryption scheme. This scheme is instantiated via a wrapper of the bgv scheme. It provides modular arithmetic over the integers.

    • bgv: A Full-RNS generalization of the Brakerski-Fan-Vercauteren scale-invariant (BFV) and Brakerski-Gentry-Vaikuntanathan (BGV) homomorphic encryption schemes. It provides modular arithmetic over the integers.

    • ckks: A Full-RNS Homomorphic Encryption for Arithmetic for Approximate Numbers (HEAAN, a.k.a. CKKS) scheme. It provides fixed-point approximate arithmetic over the complex numbers (in its classic variant) and over the real numbers (in its conjugate-invariant variant).

  • lattigo/circuits: The circuits package provides implementation of a select set of homomorphic circuits for the bgv and ckks cryptosystems:

    • bgv/lintrans, ckks/lintrans: Arbitrary linear transformations and slot permutations for both bgv and ckks. Scheme-generic objects and functions are part of common/lintrans.

    • bgv/polynomial, ckks/polynomial: Polynomial evaluation circuits for bgv and ckks. Scheme-generic objects and functions are part of common/polynomial.

    • ckks/minimax: Minimax composite polynomial evaluator for ckks.

    • ckks/comparison: Homomorphic comparison-based circuits such as sign, max and step for the ckks scheme.

    • ckks/inverse: Homomorphic inverse circuit for ckks.

    • ckks/mod1: Homomorphic circuit for the mod1 function using the ckks cryptosystem.

    • ckks/dft: Homomorphic Discrete Fourier Transform circuits for the ckks scheme.

    • ckks/bootstrapping: Bootstrapping for fixed-point approximate arithmetic over the real and complex numbers, i.e., the ckks scheme, with support for the Conjugate Invariant ring, batch bootstrapping with automatic packing/unpacking of sparsely packed/smaller ring degree ciphertexts, arbitrary precision bootstrapping, and advanced circuit customization/parameterization.

  • lattigo/multiparty: Package for multiparty (a.k.a. distributed or threshold) key-generation and interactive ciphertext bootstrapping with secret-shared secret keys.

    • mpckks: Homomorphic decryption and re-encryption from and to Linear-Secret-Sharing-Shares, as well as interactive ciphertext bootstrapping for the schemes/ckks package.

    • mpbgv: Homomorphic decryption and re-encryption from and to Linear-Secret-Sharing-Shares, as well as interactive ciphertext bootstrapping for the schemes/bgv package.

  • lattigo/examples: Executable Go programs that demonstrate the use of the Lattigo library. Each subpackage includes test files that further demonstrate the use of Lattigo primitives.

  • lattigo/utils: Generic utility methods. This package also contains the following sub-pacakges:

    • bignum: Arbitrary precision linear algebra and polynomial approximation.
    • buffer: Efficient methods to write/read on io.Writer and io.Reader.
    • factorization: Various factorization algorithms for medium-sized integers.
    • sampling: Secure bytes sampling.
    • structs: Generic structs for maps, vectors and matrices, including serialization.

Documentation

The full documentation of the individual packages can be browsed as a web page using official Golang documentation rendering tool pkgsite

$ go install golang.org/x/pkgsite/cmd/pkgsite@latest
$ cd lattigo
$ pkgsite -open .

Versions and Roadmap

The Lattigo library was originally exclusively developed by the EPFL Laboratory for Data Security until its version 2.4.0.

Starting with the release of version 3.0.0, Lattigo is maintained and supported by Tune Insight SA.

Also starting with from version 3.0.0, the module name has changed to github.com/tuneinsight/lattigo/v[X], and the official repository has been moved to https://github.com/tuneinsight/lattigo. This has the following implications for modules that depend on Lattigo:

  • Modules that require github.com/ldsec/lattigo/v2 will still build correctly.
  • To upgrade to a version X.y.z >= 3.0.0, depending modules must require github.com/tuneinsight/lattigo/v[X]/, for example by changing the imports to github.com/tuneinsight/lattigo/v[X]/[package] and by running go mod tidy.

The current version of Lattigo, (v5.x.x) is fast-evolving and in constant development. Consequently, there will still be backward-incompatible changes within this major version, in addition to many bug fixes and new features. Hence, we encourage all Lattigo users to update to the latest Lattigo version.

See CHANGELOG.md for the current and past versions.

Stability

To keep a comprehensive history, we prioritize rebases over merges for branches other than main. Branches with the prefix dev_ are branches in active development and will be frequently rebased. Hence, we don't recommend depending on them.

Pull Requests

External pull requests should only be used to propose new functionalities that are substantial and would require a fair amount of work if done on our side. If you plan to open such a pull request, please contact us before doing so to make sure that the proposed changes are aligned with our development roadmap.

External pull requests only proposing small or trivial changes will be converted to an issue and closed.

External contributions will require the signature of a Contributor License Agreement (CLA). You can contact us using the following email to request a copy of the CLA: [email protected].

Bug Reports

Lattigo welcomes bug/regression reports of any kind that conform to the preset template, which is automatically generated upon creation of a new empty issue. Nonconformity will result in the issue being closed without acknowledgement.

License

Lattigo is licensed under the Apache 2.0 License. See LICENSE.

Contact

Before contacting us directly, please make sure that your request cannot be handled through an issue.

If you want to contribute to Lattigo or report a security issue, you have a feature proposal or request, or you simply want to contact us directly, please do so using the following email: [email protected].

Citing

Please use the following BibTex entry for citing Lattigo:

@misc{lattigo,
    title = {Lattigo v5},
    howpublished = {Online: \url{https://github.com/tuneinsight/lattigo}},
    month = Nov,
    year = 2023,
    note = {EPFL-LDS, Tune Insight SA}
}

The Lattigo logo is a lattice-based version of the original Golang mascot by Renee French.

lattigo's People

Contributors

cgrigis avatar christianmct avatar dependabot[bot] avatar eliedz avatar ineiti avatar joaoandresa avatar jrtroncoso avatar mickmis avatar pro7ech avatar qantik avatar romainbou avatar tharvik avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

lattigo's Issues

[ckks] [MulByDiagMatrix] : correctness error if one of the innerloop has only a single rotation by 0

In the modified baby-step giant-step algorithm to evaluate a diagonalized matrix on a ciphertext, if one of the inner-loop of the algorithm doesn't have any rotation (a single rotation by k=0), then the accumulator isn't properly overwritten, and a correctness error follows. The fix is to check if that if there is only a single rotation by 0, then the accumulator is overwritten instead of accumulating.

Default Parameters

In version 1.1.0 of the library, can I use the parameters apart from default parameters that correspond to 128-bit security.
The default parameters start from 4096. can I use 1024 instead and how ?
{4096, 65537, logN12Q109, Pi60[len(Pi60)-len(logN12Q109)-1:], 3.19
what will I need to update apart from 4096 in the above parameter

Plans for Post-quantum crypto?

What are the plans for post-quantum crypto?

This is a topic I am interested in. Is the idea to use ring to implement lattigo's own lattice-based post-quantum crypto or to use an external library? If so, which external library?

Btw, where are signatures used in Lattigo? Is it to verify that the messages sent between distributed parties have not been modified?

I may be interested in native implementation using ring. However, there is overhead in maintaining your own crypto.

Fetch Public Key and Private Key

How can I fetch the public key and secret key to store them in a vault, the keys obtained are as follows ******&{0xc00000ccc0}&{[0xc00000cce0 0xc00000cd00]}.The Get() method returns a byte array, how can I get a base64 string of tje keys

TestRing/TernarySampler may fail

A test on the TernarySampler may fail randomly:

--- FAIL: TestRing/TernarySampler/N=4096/limbs=2 (0.00s)
        assertion_compare.go:211: 
            	Error Trace:	ring_test.go:318
            	Error:      	"1.86" is not greater than "1.8680000000000003"
            	Test:       	TestRing/TernarySampler/N=4096/limbs=2
            	Messages:   	[]

This test checks that the normalized hamming-weight doesn't go further from the expected one than a given fixed threshold.

We must document this threshold with the failure likelyhood, and updated it is it is too low. Otherwise, we need to fix something in ring.TernarySampler.

[Question] Trying to multiply Ciphertexts with output of degree>=6. bfv

HiHi,
I was trying to multiply Ciphertexts multiple times using bfv for a program using MulNew(), however after certain amount of times I face the error:
panic: runtime error: index out of range [6] with length 6
from inside the evaluator.go function tensorandrescale.

I also tried it with two random ciphers of degree three and it gives the same error (any other ciphers where the result is a poly is of degree>=6).

k := bfv.NewCiphertextRandom(params, 3) l := bfv.NewCiphertextRandom(params, 3) evaluator.MuNewl(k, l)

Same error when using Mul. I am using the default params inside the examples_bfv, and was wondering if this error is because I need to modify something to allow these larger polynomials.

Right Rotate may be wrong

Ckks scheme, I tried to use RotateColumns () function, but got the wrong answer.

I tried to find the cause of the error, and finally found that when commenting out part of the code of the RotateColumns () function, the result will be correct. But this may slow down the efficiency of rotation.

The commented code is:

// if utils.HammingWeight64(k) <= utils.HammingWeight64((eval.ckksContext.n>>1)-k) {
					eval.rotateColumnsLPow2(ct0, k, evakey, ctOut)
				// } else {
				// 	eval.rotateColumnsRPow2(ct0, (eval.ckksContext.n>>1)-k, evakey, ctOut)
				// }

So I guess the cause of the error may be related to right rotation.

Missing MarshalBinary and UnmarshalBinary functions in dckks

Hi,

While trying to send shares over the network, I noticed that some types in package dckks do not implement the functions MarshalBinary and UnmarshalBinary. This is the case for RTGShare, CKGShare, CKSShare and PCKSShare. Currently only RKGShare does implement it.

This enhancement would simplify the use of these protocols.

Notice that package dbfv implements them, so it may be possible to reuse this code with only little changes.

Homomorpic encrypted programm

hi, I am new here,
Could anyone pls give me an code example of an arithmetic programm which is encrypted and decrypted in ckks or any other methode.
Example:
A String: Hello World
A int: with plus and multiplication

code should be golint-clean

Hello,

Running golint ./... at the root directory lists a few issues (minor things such as underscore in names, += 1 --> ++, missing comments).
For code quality purposes, I would suggest to fix these, as well as adding a lint step in the CI chain to ensure it remains clean.

Thank you!

Generic Protocol(s) to transform an encryption to shares (and the opposite)

It would be nice to have a generic protocol to switch from a collectively encrypted ciphertext to (additive) secret shares, each held by one of the parties. I think that all the necessary components are already part of the refresh protocol and could be just decoupled from there.
It can make sense to have the "shares to ciphertext" protocol alongside, even though this protocol is probably very similar to a collective aggregation.
Thanks !

Can Lattigo support the Fully-Threshold MHE right now?

Hi, I read the paper Lattigo: a Multiparty Homomorphic Encryption Library in Go recently, I find this :

Full-threshold variants of BFV and CKKS are implemented in a development branch of Lattigo

but I can't find any branch which implemented the Fully-Threshold MHE. So I want to know is this still a on-goning work or I just missing it?
thanks

[ckks] Bug in bootstrapp for ciphertext at level zero

Hi,

According to the documentation of the Bootstrapp function in CKKS, it should be possible to pass ciphertexts at level zero. However, if we do it, the function will try to drop the ciphertext from level 0 to level 1:

// Bootstrapp re-encrypt a ciphertext at lvl Q0 to a ciphertext at MaxLevel-k where k is the depth of the bootstrapping circuit.
// If the input ciphertext level is zero, the input scale must be an exact power of two smaller or equal to round(Q0/2^{10}).
// If the input ciphertext is at level one or more, the input scale does not need to be an exact power of two as one level
// can be used to do a scale matching.
func (btp *Bootstrapper) Bootstrapp(ct *Ciphertext) *Ciphertext {
	//var t time.Time
	var ct0, ct1 *Ciphertext

	// Drops the level to 1
	for ct.Level() != 1 {
		btp.evaluator.DropLevel(ct, 1)
	}

	// ...
}

Then, since the function DropLevel does not check whether the requested level is higher than the current level, the slice ct0.value[i].Coeffs will become empty:

// DropLevel reduces the level of ct0 by levels and returns the result in ct0.
// No rescaling is applied during this procedure.
func (eval *evaluator) DropLevel(ct0 *Ciphertext, levels uint64) {
	level := ct0.Level()
	for i := range ct0.value {
		ct0.value[i].Coeffs = ct0.value[i].Coeffs[:level+1-levels]
	}
}

Why the need for "utils.Buffer"?

[Please label this as "question" :-)]

I was just curious, why was the Buffer type in package utils written? If I am not mistaken, it looks like the standard bytes.Buffer type, along with the binary.Read and binary.Write functions, would provide the same functionality? Or is it for reasons of performance?

Using dckks, getting wrong results with MulRelin

Hi, I am new here.
I am learning the use of DCKKS,but I got into trouble:

After Collective relinearization key generation to get rlk , use it in evaluator.MulRelin(ciphertext, ciphertext, rlk, result)

I got the wrong result much bigger than I wanted.

Because there is no example of dckks, can you write me a hint?

What is the plan for zero-knowledge proofs?

Is this to ensure that the computation has been performed correctly before decryption occurs? Since if it is not performed correctly, couldn't this leak secrets like a model's parameters?

I may be interested in implementing this if I know where to start.

CKKS Bootstrapping with level0 cipher

This ScaleUp step will consume one level before the modUp. As the result, the CKKS bootstrapping function only take care of cipher that with level >= 1, which is a stronger requirements.

Clarification about collective key switching

I don't understand why collective key switching must be performed rather than generating keyswitch keys.

Can't a similar procedure be used to generating relinearisation keys collectively?

This approach seems to introduce unnecessary communication costs.

Furthermore, there does not seem to be a description of how galois keys can be generated. However, can't one generate Galois keys by just permuting the coefficients of the secret key? This is not a problem even if we are dealing with shared secrets. So it is easy to publish galois keys, is it not? What other purpose is there for collective key switching?

Question about calling MulRelin multiple times

I want to test about the accuracy for the multiplication, so I implement a for loop to use MulRelin to calculate 1.1 ^ 20. I found that c2 would become 0 start from i = 10. Do I miss some function call to fix / minimize the errors?

values := make([]complex128, slots)
values[0] = complex(1.1, 0)
txt := ckks.NewPlaintext(params, params.MaxLevel(), params.Scale)
encoder.Encode(txt, values, slots)
c1 := encryptor.EncryptNew(txt)
c2 := encryptor.EncryptNew(txt)
for i := 0; i < 20; i++ {
	evaluator.MulRelin(c2, c1, nil, c2)
	evaluator.Relinearize(c2, rlk, c2)
	evaluator.Rescale(c2, params.Scale, c2)
}

bootstrapping more than once problem

Hi,
i transitioned to this library from SEAL because of CKKS bootstrapping.
For starters I just wrote one ciphertext - ciphertext multiplication, then rescale then bootstrapping and it worked fine, meaning the
result after bootstrapping was good enough.
Then I tested two bootstraps in the row: ciphertext - ciphertext multiplication, rescaling, bootstrapping and again on resulting ciphertext: ciphertext - ciphertext multiplication, rescaling, bootstrapping and result is very much off.

Pseudocode:
ciphertext1 = Enc([1.0, 1.0, ..., 1.0])
ciphertext2 = Enc([3.0, 3.0, ..., 3.0])
ciphertext1 = ciphertext1 * ciphertext2
evaluator.SetScale(ciphertext1, params.scale())
ciphertext1 = bootstrapper(ciphertext1)
ciphertext1 = ciphertext1 * ciphertext2
evaluator.SetScale(ciphertext1, params.scale())
ciphertext1 = bootstrapper(ciphertext1)

Code: https://pastebin.pl/view/b6cffc02

Output:
CKKS parameters: logN = 16, logSlots = 15, logQP = 1521, levels = 25, scale= 2^45.000000, sigma = 3.200000
ciphertext1 fresh (level/scale): 24 45
ciphertext1 after multiplication (level/scale): 24 90
plaintext after multiplication: (3.000000150894784-2.707561827248977e-08i)
ciphertext1 after setScale (level/scale): 23 45
plaintext after setScale: (3.000000151844232-2.71851598944193e-08i)
ciphertext1 after bootstrapping (level/scale): 10 45
plaintext after bootstrapp: (2.9998322935427497+1.2314033711896221e-06i)

ciphertext1 after multiplication (level/scale): 10 90
plaintext after multiplication: (8.999496993467984+3.6738101362829465e-06i)
ciphertext1 after setScale (level/scale): 8 45
plaintext after setScale: (4.64277915039133e-11+1.7291085069162014e-11i)
ciphertext1 after bootstrapping (level/scale): 10 45
plaintext after bootstrapp: (-2.5712217415452037e-08+3.0729998052670696e-06i)

So, it seems like everything is fine until second SetScale where ciphertext suddenly drops two level instead of one.

On another note, how to setup small parameters to fasten up bootstrapping, completely disregarding security. Its very counter-productive that i have to wait for so long everytime i run some tests of bootstrapping?

ring.PermuteNTTIndex : dissociate the xN-th root from the ring degree N

Automorphisms based on xN-th roots > 2N-th roots might be needed. Right now the length of the returned index is (xN-th root)/2, so it must be truncated to N if xN > 2N. Allow to dissociate the xN-th root from N so that the return length of the index is correct regardless of the xN-th root value.

Issue with older branch

Hello,
I have found an example of an older version. Now I want to create a code based on it to do some calculations.
https://medium.com/asecuritysite-when-bob-met-alice/heaan-homomorphic-encryption-for-arithmetic-of-approximate-numbers-ckks-40fa6a7a1fb6

Visual Studio says:
""""""""""""""""""""""""""""
undefined: ckks.CkksContext
undefined: ckks.NewCkksContext
encryptor.EncryptNew undefined (type *ckks.Encryptor is pointer to interface, not interface)
decryptor.DecryptNew undefined (type *ckks.Decryptor is pointer to interface, not interface)
""""""""""""""""""""""""""""
what has changed in the ckks file?
where can I find the older package or what do I have to change that it will work?

i hope you can help me
greetings

Documentation isn't completely idiomatic Go

Hey folks! This is really cool work and I'm looking forward to exploring. It could be much more legible to Go developers if you documented your functions and types using the canonical godoc formatting. I see that some of the code does this already, but some of it uses others styles of documentation (e.g. https://github.com/lca1/lattigo/blob/master/ring/float128.go)

This will allow both https://godoc.org and the local godoc tool to automatically parse your code as it updates. That way you won't have to make a new graphic for every release :)

Wrong paper cited at CHANGELOG?

I'm trying to learn about the algorithm used for bootstrapping the CKKS at Lattigo and found a reference to the original BFV paper on the most recent changelog for version 2.0.0. Is that write and Lattigo's CKKS uses BFV's bootstrap algorithm? Or maybe I miss understood the citation?

[ckks] Bug when encoding which non power-of-two slots

Hi,

When trying to use the CKKS encoder, I encountered a bug during encoding. If I try to encode a dummy value with the slots parameter being a non power-of-two, the operation hangs. This can be simply reproduced using the following code.

params := ckks.DefaultParams[0]
encoder := ckks.NewEncoder(params)
values := []complex128{complex(1, 0), complex(2, 0), complex(3, 0)}
plaintext := encoder.EncodeNew(values, 3)

The issue can be traced back to ckks/encoder.go:126, where the value check for slots seems to be incorrectly performed. If slots != 0 the condition fails, the power-of-two check is not executed and the execution is carried on, with an incorrect slotsvalue, which then cause the inverse FFT to hangs.
I believe this can be fixed by correcting the && into a || to ensure both checks are performed.

Problem of Synchronous Transfer?

How does Lattigo solve the problem of synchronous transfer? Isn't this required to symmetrically exchange decryption data? etc?

Is synchronous transfer required for secure key-exchange?

Updating the oblivious driver example (BFV) to use actual lat/long data (signed data)

Hi,
I think I am right in saying that BFV is not capable of doing math on encrypted floating point numbers. For my own education really (and perhaps others) I am trying to update the example to take a lat/long coordinate for the rider's location, convert this to signed integers and then continue the process to work out which driver is closest to the rider.

  • The first thing I have done is set the lat/long of the rider
  • Then I convert the lat/long to an integer, by multiplying by 1000 and rounding.
  • Next I have set each driver's location to something similar to the rider +/- a bit of randomness
  • Due to the fact that my values can be negative (lat/long can be negative) I have updated the example to use int64 instead of uint64.
  • Finally I need to calculate the expected and actual distances. This is where I am getting an error.

My code example is below. I believe the issue is on this line:

result := encoder.DecodeIntNew(decryptor.DecryptNew(evaluator.MulNew(RiderCiphertext, RiderCiphertext)))

The issue being its tricky for me to see exactly what that line is doing - but apparently its working out the distance between the rider and every driver...(?) - One question - is there another way to write that so that its more 'mathsy' - i.e a bit more like the distance() function - but for encrypted values, or is the reason its in this format precisely the point of lattice approaches to HE?

I haven't done it yet, but the last step will be to convert the distance back to a float and divide by 1000 to get the actual distance.

One step I am not sure about is whether I can use this encryption method to then send the closest driver the rider's actual location so that they can decrypt it and go there. Can the public key of the driver be used then by the rider to encrypt their location and send it to the driver who can then decrypt it, and is this comparable to RSA or AES encryption in efficiency and security?

This is a really nice example of how you could use HE btw - thanks for providing it, it would be cool if I could get it to use actual lat/long for my own peace of mind! Thank you all!

full code snippet:

package main

import (
	"fmt"
	"math"
	"math/rand"

	"github.com/ldsec/lattigo/v2/bfv"
)

func obliviousRiding() {

	// Number of drivers in the area
	nbDrivers := uint64(5) //max is N //2048 max

	// BFV parameters (128 bit security) with plaintext modulus 65929217
	params := bfv.DefaultParams[bfv.PN13QP218].WithT(0x3ee0001)

	encoder := bfv.NewEncoder(params)

	// Rider's keygen
	kgen := bfv.NewKeyGenerator(params)

	riderSk, riderPk := kgen.GenKeyPair()

	decryptor := bfv.NewDecryptor(params, riderSk)

	encryptorRiderPk := bfv.NewEncryptorFromPk(params, riderPk)

	encryptorRiderSk := bfv.NewEncryptorFromSk(params, riderSk)

	evaluator := bfv.NewEvaluator(params)

	fmt.Println("============================================")
	fmt.Println("Homomorphic computations on batched integers")
	fmt.Println("============================================")
	fmt.Println()
	fmt.Printf("Parameters : N=%d, T=%d, Q = %d bits, sigma = %f \n",
		1<<params.LogN(), params.T(), params.LogQP(), params.Sigma())
	fmt.Println()
	// Rider coordinates [x, y, x, y, ....., x, y]
	riderPosX := int64(math.Round(51.5014 * 1000)) //buckingham palace
	riderPosY := int64(math.Round(-0.1419 * 1000))

	fmt.Printf("riderPosX %d, riderPoxY %d\r\n", riderPosX, riderPosY)
	Rider := make([]int64, 1<<params.LogN())
	for i := uint64(0); i < nbDrivers; i++ {
		Rider[(i << 1)] = riderPosX
		Rider[(i<<1)+1] = riderPosY
	}

	riderPlaintext := bfv.NewPlaintext(params)
	encoder.EncodeInt(Rider, riderPlaintext)

	// driversData coordinates [0, 0, ..., x, y, ..., 0, 0]
	driversData := make([][]int64, nbDrivers)

	driversPlaintexts := make([]*bfv.Plaintext, nbDrivers)

	min := -500 //add some randomness to drivers positions
	max := 500  //add some randomness to drivers positions
	fmt.Println(rand.Intn(max - min) + min)

	for i := uint64(0); i < nbDrivers; i++ {
		driversData[i] = make([]int64, 1<<params.LogN())
		driversData[i][(i << 1)] = riderPosY + int64(rand.Intn(max - min) + min)
		driversData[i][(i<<1)+1] = riderPosY + int64(rand.Intn(max - min) + min)
		driversPlaintexts[i] = bfv.NewPlaintext(params)
		encoder.EncodeInt(driversData[i], driversPlaintexts[i])
	}
	k := 3
	driversData[k] = make([]int64, 1<<params.LogN())
	driversData[k][(k << 1)] = riderPosX
	driversData[k][(k<<1)+1] = riderPosY
	driversPlaintexts[k] = bfv.NewPlaintext(params)
	encoder.EncodeInt(driversData[k], driversPlaintexts[k])

	fmt.Printf("Encrypting %d driversData (x, y) and 1 Rider (%d, %d) \n",
		nbDrivers, riderPosX, riderPosY)
	fmt.Println()

	RiderCiphertext := encryptorRiderSk.EncryptNew(riderPlaintext)

	DriversCiphertexts := make([]*bfv.Ciphertext, nbDrivers)
	for i := uint64(0); i < nbDrivers; i++ {
		DriversCiphertexts[i] = encryptorRiderPk.EncryptNew(driversPlaintexts[i])
	}

	fmt.Println("Computing encrypted distance = ((CtD1 + CtD2 + CtD3 + CtD4...) - CtR)^2 ...")
	fmt.Println()

	evaluator.Neg(RiderCiphertext, RiderCiphertext)
	for i := uint64(0); i < nbDrivers; i++ {
		evaluator.Add(RiderCiphertext, DriversCiphertexts[i], RiderCiphertext)
	}

	result := encoder.DecodeIntNew(decryptor.DecryptNew(evaluator.MulNew(RiderCiphertext, RiderCiphertext)))

	minIndex, minPosX, minPosY, minDist := uint64(0), int64(0), int64(0), float64(0)
	errors := 0

	for i := uint64(0); i < nbDrivers; i++ {

		driverPosX, driverPosY := driversData[i][i<<1], driversData[i][(i<<1)+1]

		computedDist := math.Abs(float64(result[i<<1] + result[(i<<1)+1]))
		expectedDist := math.Abs(float64(distance(driverPosX, driverPosY, riderPosX, riderPosY)))
		fmt.Printf("x %d y %d calculated %.2f expected %.2f\r\n", driverPosX, driverPosY, computedDist, expectedDist)
		if computedDist == expectedDist {
			if computedDist < minDist {
				minIndex = i
				minPosX, minPosY = driverPosX, driverPosY
				minDist = computedDist
			}
		} else {
			errors++
		}

		if i < 4 || i > nbDrivers-5 {
			fmt.Printf("Distance with Driver %d : %8f = (%4d - %4d)^2 + (%4d - %4d)^2 --> correct: %t\n",
				i, computedDist, driverPosX, riderPosX, driverPosY, riderPosY, computedDist == expectedDist)
		}

		if i == nbDrivers>>1 {
			fmt.Println("...")
		}
	}

	fmt.Printf("\nFinished with %.2f%% errors\n\n", 100*float64(errors)/float64(nbDrivers))
	fmt.Printf("Closest Driver to Rider is n°%d (%d, %d) with a distance of %d units\n",
		minIndex, minPosX, minPosY, uint64(math.Sqrt(float64(minDist))))
}

func distance(a, b, c, d int64) int64 {
	if a > c {
		a, c = c, a
	}
	if b > d {
		b, d = d, b
	}
	x, y := a-c, b-d
	return x*x + y*y
}

func main() {
	obliviousRiding()
}

Fetch Public key and Private Key

How can I fetch the public key and secret key to store them in a file/vault, the keys obtained are as follows ******&{0xc00000ccc0}&{[0xc00000cce0 0xc00000cd00]}.The Get() method returns a byte array, how can I get a base64 string of the keys

Usage of Rescale

Hi, when I use Rescale() after Mul, the result is wrong. And it doesn't just happen occasionally.
Here is my code:

evaluator.MulRelin(result,encIn[i],rlk,result)
fmt.Println(math.Log2(result.Scale()))
evaluator.Rescale(result,params.Scale,result)
fmt.Println(math.Log2(result.Scale()))

if we decrypt after MulRelin, we will get the corrext answer. And we decrypt after Rescale(), we will get a huge answer . The answer is different every time.

Here is one of answer:
QMUTB_R)A%2DVJES0@AP B8

I wonder if my usage of Rescale () is wrong. How to use it correctly.

Less levels needed when bootstrapping

Hi.
So I tried implementing max function, which returns approximate maximum among ciphertext.slots() real numbers from interval [0,1 ] encoded and encrypted in single ciphertext. To do this I first implement approximate max(a,b) = (a + b + abs(a-b))/2, where i approximate abs(x) = sqrt_cheby(x^2), where sqrt_cheby is cheby approximation of sqrt on [0, 1] of degree 33. With max(a, b) implemented I rotate log2(ciphertext.slots) times. In each iteration i calculate ciphertext = max(ciphertext, rotate(ciphertext, 2^i)). All of this costs 10 levels, so i bootstrapp in each iteration.
This works fine and among ciphertext.slots real numbers from interval [0, 1] i get approximate max which is three decimals accurate
which is good enough for me, as this was just an experiment and not a serious attempt.
By choosing default bootstrapp parameters I get 24 levels on fresh ciphertext, but that is too much since i only need 11. Those 13 excessive levels increase the size of ciphertext but more importantly probably slow down the whole bootstrapp operation. So my question is how to choose parameters for encryption and bootstrapping with only 11 levels on fresh ciphertext?
(the code is here https://pastebin.com/gug4N4Tg, but due to all the Printlns looks like shit. Consider yourself warned :) )

Documentation for Refresh protocol

I don't understand what is being done in:
https://github.com/ldsec/lattigo/blob/bb095f1d82cd5c532171b138cd0ad83ecd785103/dckks/public_refresh.go

There is no documentation on this, including here: https://eprint.iacr.org/2019/961.pdf.

Also, I don't understand how it is possible to perform CKKS refreshing in a multiparty manner. Does it do so in a way that none of the parties learn any of the intermediate outputs?

Reading the implementation, it seems that additive secret sharing is used. One decrypts their own portion of the CKKS/BFV secret ct[1].s_i, wrt to modulus 0, and adds their share of a shared secret mod q_0 to it. Then, as long as q_0 is larger than q_i for all i larger than 0, one can reduce this number mod q_i for each i, and for each i, each party removes their portion of the shared secret, and encrypts with their portion of the CKKS secret wrt to the modulus q_i. I believe this is correct.

I don't think this library has solved the problem of premature decryption, before the required computation on the server has been performed, which is a problem faced by any MPC approach, besides client-server, since in the client-server case the client is the sole stakeholder of the component secrets, hence if I am not wrong, it is thinking of implementing ZK proofs, although I don't know how this can be done.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.