Skip to content

Commit

Permalink
refactor: prepare terrain for linea integration
Browse files Browse the repository at this point in the history
  • Loading branch information
gbotrel committed Jan 8, 2025
1 parent 2484cda commit 455b89a
Show file tree
Hide file tree
Showing 10 changed files with 237 additions and 105 deletions.
66 changes: 46 additions & 20 deletions ecc/bls12-377/fr/sis/sis.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion ecc/bls12-377/fr/sis/sis_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

66 changes: 46 additions & 20 deletions field/babybear/sis/sis.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion field/babybear/sis/sis_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

68 changes: 48 additions & 20 deletions field/generator/internal/templates/sis/sis.go.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,6 @@ func NewRSis(seed int64, logTwoDegree, logTwoBound, maxNbElementsToHash int) (*R
return r, nil
}


// Hash interprets the input vector as a sequence of coefficients of size r.LogTwoBound bits long,
// and return the hash of the polynomial corresponding to the sum sum_i A[i]*m Mod X^{d}+1
func (r *RSis) Hash(v, res []{{ .FF }}.Element) error {
Expand All @@ -132,16 +131,27 @@ func (r *RSis) Hash(v, res []{{ .FF }}.Element) error {
res[i].SetZero()
}

// decompose v limb by limb
reader := NewVectorLimbReader(v, r.LogTwoBound/8)

kz := make([]{{ .FF }}.Element, r.Degree)
k := make([]{{ .FF }}.Element, r.Degree)
for i := 0; i < len(r.Ag); i++ {
copy(k, kz)

// inner hash
r.InnerHash(&vectorIterator{v: v}, res, k)


// reduces mod Xᵈ+1
r.Domain.FFTInverse(res, fft.DIT, fft.OnCoset(), fft.WithNbTasks(1))

return nil
}

func (r *RSis) InnerHash(it ElementIterator, res, k {{ .FF }}.Vector) {
reader := NewLimbIterator(it, r.LogTwoBound/8)

for i := 0; i < len(r.Ag); i++ {
zero := {{$tReturn}}(0)
for j := 0; j < r.Degree; j+=2 {
k[j].SetZero()
k[j+1].SetZero()

// read limbs 2 by 2 since degree is a power of 2 (> 1)
l := reader.NextLimb()
zero |= l
Expand All @@ -160,10 +170,7 @@ func (r *RSis) Hash(v, res []{{ .FF }}.Element) error {
r.Domain.FFT(k, fft.DIF, fft.OnCoset(), fft.WithNbTasks(1))
mulModAcc(res, r.Ag[i], k)
}
// reduces mod Xᵈ+1
r.Domain.FFTInverse(res, fft.DIT, fft.OnCoset(), fft.WithNbTasks(1))

return nil
}

// mulModAcc computes p * q in ℤ_{p}[X]/Xᵈ+1.
Expand Down Expand Up @@ -196,23 +203,44 @@ func deriveRandomElementFromSeed(seed, i, j int64) {{ .FF }}.Element {
}


// VectorLimbReader iterates over a vector of field element, limb by limb.
type VectorLimbReader struct {
// TODO @gbotrel explore generic perf impact + go 1.23 iterators

// ElementIterator is an iterator over a stream of field elements.
type ElementIterator interface {
Next() ({{ .FF }}.Element, bool)
}

type vectorIterator struct {
v {{ .FF }}.Vector
i int
}

func (vi *vectorIterator) Next() ({{ .FF }}.Element, bool) {
if vi.i == len(vi.v) {
return {{ .FF }}.Element{}, false
}
vi.i++
return vi.v[vi.i-1], true
}



// LimbIterator iterates over a vector of field element, limb by limb.
type LimbIterator struct {
it ElementIterator
buf [{{ .FF }}.Bytes]byte

i int // position in vector
j int // position in buf

next func(buf []byte, pos *int) {{$tReturn}}
}

// NewVectorLimbReader creates a new VectorLimbReader
// NewLimbIterator creates a new LimbIterator
// v: the vector to read
// limbSize: the size of the limb in bytes (1, 2, 4 or 8)
// The elements are interpreted in little endian.
// The limb is also in little endian.
func NewVectorLimbReader(v {{ .FF }}.Vector, limbSize int) *VectorLimbReader {
func NewLimbIterator(it ElementIterator, limbSize int) *LimbIterator {
var next func(buf []byte, pos *int) {{$tReturn}}
switch limbSize {
case 1:
Expand All @@ -228,8 +256,8 @@ func NewVectorLimbReader(v {{ .FF }}.Vector, limbSize int) *VectorLimbReader {
default:
panic("unsupported limb size")
}
return &VectorLimbReader{
v: v,
return &LimbIterator{
it: it,
j: {{ .FF }}.Bytes,
next: next,
}
Expand All @@ -238,11 +266,11 @@ func NewVectorLimbReader(v {{ .FF }}.Vector, limbSize int) *VectorLimbReader {
// NextLimb returns the next limb of the vector.
// This does not perform any bound check, may trigger an out of bound panic.
// If underlying vector is "out of limb"
func (vr *VectorLimbReader) NextLimb() {{$tReturn}} {
func (vr *LimbIterator) NextLimb() {{$tReturn}} {
if vr.j == {{ .FF }}.Bytes {
vr.j = 0
{{.FF}}.LittleEndian.PutElement(&vr.buf, vr.v[vr.i])
vr.i++
next, _ := vr.it.Next()
{{.FF}}.LittleEndian.PutElement(&vr.buf, next)
}
return vr.next(vr.buf[:], &vr.j)
}
Expand Down
2 changes: 1 addition & 1 deletion field/generator/internal/templates/sis/sis.test.go.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ func TestLimbDecomposeBytes(t *testing.T) {
logTwoBound := 8

for cc:=0;cc<{{- if $f31 }}1{{- else }}3{{- end}}; cc++ {
vr := NewVectorLimbReader(a, logTwoBound/8)
vr := NewLimbIterator(&vectorIterator{v:a}, logTwoBound/8)
m := make({{ .FF }}.Vector, nbElmts*{{ .FF }}.Bytes*8/logTwoBound)
for i := 0; i < len(m); i++ {
m[i][0] = vr.NextLimb()
Expand Down
Loading

0 comments on commit 455b89a

Please sign in to comment.