Skip to content

Commit

Permalink
Merge pull request #417 from tuneinsight/dev_fix_benchmarks
Browse files Browse the repository at this point in the history
Dev fix benchmarks
  • Loading branch information
Pro7ech authored Nov 23, 2023
2 parents 5a4aca7 + 2dc03db commit d2c55ba
Show file tree
Hide file tree
Showing 10 changed files with 1,641 additions and 216 deletions.
72 changes: 72 additions & 0 deletions he/hebin/blindrotation_benchmark_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package hebin

import (
"testing"

"github.com/tuneinsight/lattigo/v5/core/rlwe"
"github.com/tuneinsight/lattigo/v5/utils"
"github.com/tuneinsight/lattigo/v5/utils/sampling"

"github.com/stretchr/testify/require"
)

func BenchmarkHEBin(b *testing.B) {

b.Run("BlindRotateCore/LogN=(9, 10)/LogQ=(13.6,26.99)/Gadget=2^7", func(b *testing.B) {

// RLWE parameters of the BlindRotation
// N=1024, Q=0x7fff801 -> 131 bit secure
paramsBR, err := rlwe.NewParametersFromLiteral(rlwe.ParametersLiteral{
LogN: 10,
Q: []uint64{0x7fff801},
NTTFlag: NTTFlag,
})

require.NoError(b, err)

// RLWE parameters of the samples
// N=512, Q=0x3001 -> 135 bit secure
paramsLWE, err := rlwe.NewParametersFromLiteral(rlwe.ParametersLiteral{
LogN: 9,
Q: []uint64{0x3001},
NTTFlag: NTTFlag,
})

require.NoError(b, err)

evkParams := rlwe.EvaluationKeyParameters{BaseTwoDecomposition: utils.Pointy(7)}

// RLWE secret for the samples
skLWE := rlwe.NewKeyGenerator(paramsLWE).GenSecretKeyNew()

// Secret of the RGSW ciphertexts encrypting the bits of skLWE
skBR := rlwe.NewKeyGenerator(paramsBR).GenSecretKeyNew()

// Collection of RGSW ciphertexts encrypting the bits of skLWE under skBR
BRK := GenEvaluationKeyNew(paramsBR, skBR, paramsLWE, skLWE, evkParams)

// Random LWE mask mod 2N with odd coefficients
a := make([]uint64, paramsLWE.N())
mask := uint64(2*paramsLWE.N() - 1)
for i := range a {
ai := sampling.RandUint64() & mask
if ai&1 == 0 && ai != 0 {
ai ^= 1
}
a[i] = ai
}

acc := rlwe.NewCiphertext(paramsBR, 1, paramsBR.MaxLevel())

// Evaluator for the Blind Rotation evaluation
eval := NewEvaluator(paramsBR, paramsLWE)

b.ResetTimer()

for i := 0; i < b.N; i++ {
if err := eval.BlindRotateCore(a, acc, BRK); err != nil {
panic(err)
}
}
})
}
2 changes: 2 additions & 0 deletions he/hebin/blindrotation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ func testBlindRotation(t *testing.T) {
NTTFlag: NTTFlag,
})

require.NoError(t, err)

evkParams := rlwe.EvaluationKeyParameters{BaseTwoDecomposition: utils.Pointy(7)}

require.NoError(t, err)
Expand Down
40 changes: 22 additions & 18 deletions he/hebin/evaluator.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,22 +67,14 @@ func (eval *Evaluator) EvaluateAndRepack(ct *rlwe.Ciphertext, testPolyWithSlotIn
// Evaluate extracts on the fly LWE samples and evaluates the provided blind rotation on the LWE.
// testPolyWithSlotIndex : a map with [slot_index] -> blind rotation
// Returns a map[slot_index] -> BlindRotate(ct[slot_index])
func (eval *Evaluator) Evaluate(ct *rlwe.Ciphertext, testPolyWithSlotIndex map[int]*ring.Poly, key BlindRotationEvaluationKeySet) (res map[int]*rlwe.Ciphertext, err error) {

evk, err := key.GetEvaluationKeySet()

if err != nil {
return nil, err
}

eval.Evaluator = eval.Evaluator.WithKey(evk)
func (eval *Evaluator) Evaluate(ct *rlwe.Ciphertext, testPolyWithSlotIndex map[int]*ring.Poly, BRK BlindRotationEvaluationKeySet) (res map[int]*rlwe.Ciphertext, err error) {

bRLWEMod2N := eval.poolMod2N[0]
aRLWEMod2N := eval.poolMod2N[1]

acc := eval.accumulator

brk, err := key.GetBlindRotationKey(0)
brk, err := BRK.GetBlindRotationKey(0)

if err != nil {
return nil, err
Expand Down Expand Up @@ -140,7 +132,7 @@ func (eval *Evaluator) Evaluate(ct *rlwe.Ciphertext, testPolyWithSlotIndex map[i
acc.Value[1].Zero()

// Line 3 of Algorithm 7 https://eprint.iacr.org/2022/198 (Algorithm 3 of https://eprint.iacr.org/2022/198)
if err = eval.BlindRotateCore(a, acc, key); err != nil {
if err = eval.BlindRotateCore(a, acc, BRK); err != nil {
return nil, fmt.Errorf("BlindRotateCore: %s", err)
}

Expand All @@ -159,7 +151,15 @@ func (eval *Evaluator) Evaluate(ct *rlwe.Ciphertext, testPolyWithSlotIndex map[i
}

// BlindRotateCore implements Algorithm 3 of https://eprint.iacr.org/2022/198
func (eval *Evaluator) BlindRotateCore(a []uint64, acc *rlwe.Ciphertext, evk BlindRotationEvaluationKeySet) (err error) {
func (eval *Evaluator) BlindRotateCore(a []uint64, acc *rlwe.Ciphertext, BRK BlindRotationEvaluationKeySet) (err error) {

evk, err := BRK.GetEvaluationKeySet()

if err != nil {
return err
}

eval.Evaluator = eval.Evaluator.WithKey(evk)

// GaloisElement(k) = GaloisGen^{k} mod 2N
GaloisElement := eval.paramsBR.GaloisElement
Expand All @@ -173,13 +173,13 @@ func (eval *Evaluator) BlindRotateCore(a []uint64, acc *rlwe.Ciphertext, evk Bli
var v int
// Lines 3 to 9 (negative set of a[i] = -g^{k} mod 2N)
for i := Nhalf - 1; i > 0; i-- {
if v, err = eval.evaluateFromDiscreteLogSets(GaloisElement, discreteLogSets, -i, v, acc, evk); err != nil {
if v, err = eval.evaluateFromDiscreteLogSets(GaloisElement, discreteLogSets, -i, v, acc, BRK); err != nil {
return
}
}

// Line 10 (0 in the negative set is 2N)
if _, err = eval.evaluateFromDiscreteLogSets(GaloisElement, discreteLogSets, eval.paramsBR.N()<<1, 0, acc, evk); err != nil {
if _, err = eval.evaluateFromDiscreteLogSets(GaloisElement, discreteLogSets, eval.paramsBR.N()<<1, 0, acc, BRK); err != nil {
return
}

Expand All @@ -191,21 +191,21 @@ func (eval *Evaluator) BlindRotateCore(a []uint64, acc *rlwe.Ciphertext, evk Bli

// Lines 13 - 19 (positive set of a[i] = g^{k} mod 2N)
for i := Nhalf - 1; i > 0; i-- {
if v, err = eval.evaluateFromDiscreteLogSets(GaloisElement, discreteLogSets, i, v, acc, evk); err != nil {
if v, err = eval.evaluateFromDiscreteLogSets(GaloisElement, discreteLogSets, i, v, acc, BRK); err != nil {
return
}
}

// Lines 20 - 21 (0 in the positive set is 0)
if _, err = eval.evaluateFromDiscreteLogSets(GaloisElement, discreteLogSets, 0, 0, acc, evk); err != nil {
if _, err = eval.evaluateFromDiscreteLogSets(GaloisElement, discreteLogSets, 0, 0, acc, BRK); err != nil {
return
}

return
}

// evaluateFromDiscreteLogSets loops of Algorithm 3 of https://eprint.iacr.org/2022/198
func (eval *Evaluator) evaluateFromDiscreteLogSets(GaloisElement func(k int) (galEl uint64), sets map[int][]int, k, v int, acc *rlwe.Ciphertext, evk BlindRotationEvaluationKeySet) (int, error) {
func (eval *Evaluator) evaluateFromDiscreteLogSets(GaloisElement func(k int) (galEl uint64), sets map[int][]int, k, v int, acc *rlwe.Ciphertext, BRK BlindRotationEvaluationKeySet) (int, error) {

// Checks if k is in the discrete log sets
if set, ok := sets[k]; ok {
Expand All @@ -222,7 +222,7 @@ func (eval *Evaluator) evaluateFromDiscreteLogSets(GaloisElement func(k int) (ga

for _, j := range set {

brk, err := evk.GetBlindRotationKey(j)
brk, err := BRK.GetBlindRotationKey(j)
if err != nil {
return v, err
}
Expand Down Expand Up @@ -276,6 +276,10 @@ func (eval *Evaluator) getDiscreteLogSets(a []uint64) (discreteLogSets map[int][
discreteLogSets = map[int][]int{}
for i, ai := range a {

if ai&1 != 1 && ai != 0 {
panic("getDiscreteLogSets: a[i] is not odd and thus not an element of Z_{2N}^{*} -> a[i] = (+/- 1) * g^{k} does not exist.")
}

dlog := GaloisGenDiscreteLog[ai]

if _, ok := discreteLogSets[dlog]; !ok {
Expand Down
Loading

0 comments on commit d2c55ba

Please sign in to comment.