mirror of
https://github.com/tuneinsight/lattigo.git
synced 2025-09-13 03:27:14 +00:00
91 lines
2.3 KiB
Go
91 lines
2.3 KiB
Go
package integer
|
|
|
|
import (
|
|
"math/big"
|
|
"math/bits"
|
|
|
|
"github.com/tuneinsight/lattigo/v4/bgv"
|
|
"github.com/tuneinsight/lattigo/v4/circuits"
|
|
"github.com/tuneinsight/lattigo/v4/rlwe"
|
|
"github.com/tuneinsight/lattigo/v4/utils"
|
|
)
|
|
|
|
type simIntegerPolynomialEvaluator struct {
|
|
params bgv.Parameters
|
|
InvariantTensoring bool
|
|
}
|
|
|
|
func (d simIntegerPolynomialEvaluator) PolynomialDepth(degree int) int {
|
|
if d.InvariantTensoring {
|
|
return 0
|
|
}
|
|
return bits.Len64(uint64(degree)) - 1
|
|
}
|
|
|
|
// Rescale rescales the target circuits.SimOperand n times and returns it.
|
|
func (d simIntegerPolynomialEvaluator) Rescale(op0 *circuits.SimOperand) {
|
|
if !d.InvariantTensoring {
|
|
op0.Scale = op0.Scale.Div(rlwe.NewScale(d.params.Q()[op0.Level]))
|
|
op0.Level--
|
|
}
|
|
}
|
|
|
|
// Mul multiplies two circuits.SimOperand, stores the result the taret circuits.SimOperand and returns the result.
|
|
func (d simIntegerPolynomialEvaluator) MulNew(op0, op1 *circuits.SimOperand) (opOut *circuits.SimOperand) {
|
|
opOut = new(circuits.SimOperand)
|
|
opOut.Level = utils.Min(op0.Level, op1.Level)
|
|
|
|
if d.InvariantTensoring {
|
|
opOut.Scale = bgv.MulScaleInvariant(d.params, op0.Scale, op1.Scale, opOut.Level)
|
|
} else {
|
|
opOut.Scale = op0.Scale.Mul(op1.Scale)
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func (d simIntegerPolynomialEvaluator) UpdateLevelAndScaleBabyStep(lead bool, tLevelOld int, tScaleOld rlwe.Scale) (tLevelNew int, tScaleNew rlwe.Scale) {
|
|
tLevelNew = tLevelOld
|
|
tScaleNew = tScaleOld
|
|
if !d.InvariantTensoring && lead {
|
|
tScaleNew = tScaleOld.Mul(d.params.NewScale(d.params.Q()[tLevelOld]))
|
|
}
|
|
return
|
|
}
|
|
|
|
func (d simIntegerPolynomialEvaluator) UpdateLevelAndScaleGiantStep(lead bool, tLevelOld int, tScaleOld, xPowScale rlwe.Scale) (tLevelNew int, tScaleNew rlwe.Scale) {
|
|
|
|
Q := d.params.Q()
|
|
|
|
tLevelNew = tLevelOld
|
|
tScaleNew = tScaleOld.Div(xPowScale)
|
|
|
|
// tScaleNew = targetScale*currentQi/XPow.Scale
|
|
if !d.InvariantTensoring {
|
|
|
|
var currentQi uint64
|
|
if lead {
|
|
currentQi = Q[tLevelNew]
|
|
} else {
|
|
currentQi = Q[tLevelNew+1]
|
|
}
|
|
|
|
tScaleNew = tScaleNew.Mul(d.params.NewScale(currentQi))
|
|
|
|
} else {
|
|
|
|
T := d.params.PlaintextModulus()
|
|
|
|
// -Q mod T
|
|
qModTNeg := new(big.Int).Mod(d.params.RingQ().ModulusAtLevel[tLevelNew], new(big.Int).SetUint64(T)).Uint64()
|
|
qModTNeg = T - qModTNeg
|
|
tScaleNew = tScaleNew.Mul(d.params.NewScale(qModTNeg))
|
|
}
|
|
|
|
if !d.InvariantTensoring {
|
|
tLevelNew++
|
|
}
|
|
|
|
return
|
|
}
|