[all]: updated API for encoding/decoding in place

This commit is contained in:
Jean-Philippe Bossuat
2023-04-24 18:44:02 +02:00
parent e7a162a309
commit d5f0f04b68
27 changed files with 826 additions and 921 deletions

View File

@@ -10,8 +10,8 @@ All notable changes to this library are documented in this file.
- `BinarySize() int`: size in bytes when written to an `io.Writer` or to a slice of bytes using `Read`.
- `WriteTo(io.Writer) (int64, error)`: efficient writing on any `io.Writer`.
- `ReadFrom(io.Reader) (int64, error)`: efficient reading from any `io.Reader`.
- `Read([]byte) (int, error)`: highly efficient encoding on preallocated slice of bytes.
- `Write([]byte) (int, error)`: highly efficient decoding from a slice of bytes.
- `Encode([]byte) (int, error)`: highly efficient encoding on preallocated slice of bytes.
- `Decode([]byte) (int, error)`: highly efficient decoding from a slice of bytes.
Streamlined and simplified all test related this interface. They can now be implemented with a single line of code.
- All: all tests and benchmarks in package other than the `RLWE` and `DRLWE` package that were merely wrapper of methods of the `RLWE` or `DRLWE` have been removed and/or moved to the `RLWE` and `DRLWE` packages.
- All: polynomials, ciphertext and keys now all implement the method V Equal(V) bool.

View File

@@ -28,9 +28,9 @@ func (p *PowerBasis) ReadFrom(r io.Reader) (n int64, err error) {
return p.PowerBasis.ReadFrom(r)
}
func (p *PowerBasis) Write(data []byte) (n int, err error) {
func (p *PowerBasis) Decode(data []byte) (n int, err error) {
p.PowerBasis = &rlwe.PowerBasis{}
return p.PowerBasis.Write(data)
return p.PowerBasis.Decode(data)
}
// GenPower generates the n-th power of the power basis,

View File

@@ -28,9 +28,9 @@ func (p *PowerBasis) ReadFrom(r io.Reader) (n int64, err error) {
return p.PowerBasis.ReadFrom(r)
}
func (p *PowerBasis) Write(data []byte) (n int, err error) {
func (p *PowerBasis) Decode(data []byte) (n int, err error) {
p.PowerBasis = &rlwe.PowerBasis{}
return p.PowerBasis.Write(data)
return p.PowerBasis.Decode(data)
}
// GenPower generates the n-th power of the power basis,

View File

@@ -27,9 +27,9 @@ func (p *PowerBasis) ReadFrom(r io.Reader) (n int64, err error) {
return p.PowerBasis.ReadFrom(r)
}
func (p *PowerBasis) Write(data []byte) (n int, err error) {
func (p *PowerBasis) Decode(data []byte) (n int, err error) {
p.PowerBasis = &rlwe.PowerBasis{}
return p.PowerBasis.Write(data)
return p.PowerBasis.Decode(data)
}
// GenPower recursively computes X^{n}.

View File

@@ -37,7 +37,8 @@ type CKGCRP struct {
Value ringqp.Poly
}
// BinarySize returns the size in bytes that the object once marshalled into a binary form.
// BinarySize returns the size in bytes of the object
// when encoded using Encode.
func (share *CKGShare) BinarySize() int {
return share.Value.BinarySize()
}
@@ -47,10 +48,10 @@ func (share *CKGShare) MarshalBinary() (p []byte, err error) {
return share.Value.MarshalBinary()
}
// Read encodes the object into a binary form on a preallocated slice of bytes
// Encode encodes the object into a binary form on a preallocated slice of bytes
// and returns the number of bytes written.
func (share *CKGShare) Read(p []byte) (ptr int, err error) {
return share.Value.Read(p)
func (share *CKGShare) Encode(p []byte) (ptr int, err error) {
return share.Value.Encode(p)
}
// WriteTo writes the object on an io.Writer.
@@ -64,17 +65,16 @@ func (share *CKGShare) WriteTo(w io.Writer) (n int64, err error) {
return share.Value.WriteTo(w)
}
// UnmarshalBinary decodes a slice of bytes generated by MarshalBinary,
// WriteTo or Read on the object.
// UnmarshalBinary decodes a slice of bytes generated by
// MarshalBinary or WriteTo on the object.
func (share *CKGShare) UnmarshalBinary(p []byte) (err error) {
_, err = share.Write(p)
return
return share.Value.UnmarshalBinary(p)
}
// Write decodes a slice of bytes generated by MarshalBinary or
// Read on the object and returns the number of bytes read.
func (share *CKGShare) Write(p []byte) (n int, err error) {
return share.Value.Write(p)
// Decode decodes a slice of bytes generated by Encode
// on the object and returns the number of bytes read.
func (share *CKGShare) Decode(p []byte) (n int, err error) {
return share.Value.Decode(p)
}
// ReadFrom reads on the object from an io.Writer.

View File

@@ -2,6 +2,7 @@ package drlwe
import (
"bufio"
"bytes"
"encoding/binary"
"fmt"
"io"
@@ -239,23 +240,24 @@ type GKGShare struct {
Value structs.Matrix[ringqp.Poly]
}
// BinarySize returns the size in bytes that the object once marshalled into a binary form.
// BinarySize returns the size in bytes of the object
// when encoded using Encode.
func (share *GKGShare) BinarySize() int {
return 8 + share.Value.BinarySize()
}
// MarshalBinary encodes the object into a binary form on a newly allocated slice of bytes.
func (share *GKGShare) MarshalBinary() (data []byte, err error) {
data = make([]byte, share.BinarySize())
_, err = share.Read(data)
return
func (share *GKGShare) MarshalBinary() (p []byte, err error) {
buf := bytes.NewBuffer([]byte{})
_, err = share.WriteTo(buf)
return buf.Bytes(), nil
}
// Read encodes the object into a binary form on a preallocated slice of bytes
// Encode encodes the object into a binary form on a preallocated slice of bytes
// and returns the number of bytes written.
func (share *GKGShare) Read(data []byte) (n int, err error) {
binary.LittleEndian.PutUint64(data, share.GaloisElement)
n, err = share.Value.Read(data[8:])
func (share *GKGShare) Encode(p []byte) (n int, err error) {
binary.LittleEndian.PutUint64(p, share.GaloisElement)
n, err = share.Value.Encode(p[8:])
return n + 8, err
}
@@ -291,18 +293,18 @@ func (share *GKGShare) WriteTo(w io.Writer) (n int64, err error) {
}
}
// UnmarshalBinary decodes a slice of bytes generated by MarshalBinary,
// WriteTo or Read on the object.
func (share *GKGShare) UnmarshalBinary(data []byte) (err error) {
_, err = share.Write(data)
// UnmarshalBinary decodes a slice of bytes generated by
// MarshalBinary or WriteTo on the object.
func (share *GKGShare) UnmarshalBinary(p []byte) (err error) {
_, err = share.ReadFrom(bytes.NewBuffer(p))
return
}
// Write decodes a slice of bytes generated by MarshalBinary or
// Read on the object and returns the number of bytes read.
func (share *GKGShare) Write(data []byte) (n int, err error) {
share.GaloisElement = binary.LittleEndian.Uint64(data)
n, err = share.Value.Write(data[8:])
// Decode decodes a slice of bytes generated by Encode
// on the object and returns the number of bytes read.
func (share *GKGShare) Decode(p []byte) (n int, err error) {
share.GaloisElement = binary.LittleEndian.Uint64(p)
n, err = share.Value.Decode(p[8:])
return n + 8, err
}

View File

@@ -308,7 +308,8 @@ func (ekg *RKGProtocol) AllocateShare() (ephSk *rlwe.SecretKey, r1 *RKGShare, r2
return
}
// BinarySize returns the size in bytes that the object once marshalled into a binary form.
// BinarySize returns the size in bytes of the object
// when encoded using Encode.
func (share *RKGShare) BinarySize() int {
return share.GadgetCiphertext.BinarySize()
}
@@ -318,10 +319,10 @@ func (share *RKGShare) MarshalBinary() (data []byte, err error) {
return share.GadgetCiphertext.MarshalBinary()
}
// Read encodes the object into a binary form on a preallocated slice of bytes
// Encode encodes the object into a binary form on a preallocated slice of bytes
// and returns the number of bytes written.
func (share *RKGShare) Read(data []byte) (n int, err error) {
return share.GadgetCiphertext.Read(data)
func (share *RKGShare) Encode(data []byte) (n int, err error) {
return share.GadgetCiphertext.Encode(data)
}
// WriteTo writes the object on an io.Writer.
@@ -335,16 +336,16 @@ func (share *RKGShare) WriteTo(w io.Writer) (n int64, err error) {
return share.GadgetCiphertext.WriteTo(w)
}
// UnmarshalBinary decodes a slice of bytes generated by MarshalBinary,
// WriteTo or Read on the object.
// UnmarshalBinary decodes a slice of bytes generated by
// MarshalBinary or WriteTo on the object.
func (share *RKGShare) UnmarshalBinary(data []byte) (err error) {
return share.GadgetCiphertext.UnmarshalBinary(data)
}
// Write decodes a slice of bytes generated by MarshalBinary or
// Read on the object and returns the number of bytes read.
func (share *RKGShare) Write(data []byte) (n int, err error) {
return share.GadgetCiphertext.Write(data)
// Decode decodes a slice of bytes generated by Encode
// on the object and returns the number of bytes read.
func (share *RKGShare) Decode(data []byte) (n int, err error) {
return share.GadgetCiphertext.Decode(data)
}
// ReadFrom reads on the object from an io.Writer.

View File

@@ -136,7 +136,8 @@ type PCKSShare struct {
rlwe.OperandQ
}
// BinarySize returns the size in bytes that the object once marshalled into a binary form.
// BinarySize returns the size in bytes of the object
// when encoded using Encode.
func (share *PCKSShare) BinarySize() int {
return share.OperandQ.BinarySize()
}
@@ -146,10 +147,10 @@ func (share *PCKSShare) MarshalBinary() (p []byte, err error) {
return share.OperandQ.MarshalBinary()
}
// Read encodes the object into a binary form on a preallocated slice of bytes
// Encode encodes the object into a binary form on a preallocated slice of bytes
// and returns the number of bytes written.
func (share *PCKSShare) Read(p []byte) (n int, err error) {
return share.OperandQ.Read(p)
func (share *PCKSShare) Encode(p []byte) (n int, err error) {
return share.OperandQ.Encode(p)
}
// WriteTo writes the object on an io.Writer.
@@ -163,16 +164,16 @@ func (share *PCKSShare) WriteTo(w io.Writer) (n int64, err error) {
return share.OperandQ.WriteTo(w)
}
// UnmarshalBinary decodes a slice of bytes generated by MarshalBinary,
// WriteTo or Read on the object.
// UnmarshalBinary decodes a slice of bytes generated by
// MarshalBinary or WriteTo on the object.
func (share *PCKSShare) UnmarshalBinary(p []byte) (err error) {
return share.OperandQ.UnmarshalBinary(p)
}
// Write decodes a slice of bytes generated by MarshalBinary or
// Read on the object and returns the number of bytes read.
func (share *PCKSShare) Write(p []byte) (n int, err error) {
return share.OperandQ.Write(p)
// Decode decodes a slice of bytes generated by Encode
// on the object and returns the number of bytes read.
func (share *PCKSShare) Decode(p []byte) (n int, err error) {
return share.OperandQ.Decode(p)
}
// ReadFrom reads on the object from an io.Writer.

View File

@@ -1,6 +1,7 @@
package drlwe
import (
"bytes"
"io"
"math"
@@ -158,22 +159,23 @@ func (ckss *CKSShare) Level() int {
return ckss.Value.Level()
}
// BinarySize returns the size in bytes that the object once marshalled into a binary form.
// BinarySize returns the size in bytes of the object
// when encoded using Encode.
func (ckss *CKSShare) BinarySize() int {
return ckss.Value.BinarySize()
}
// MarshalBinary encodes a CKS share on a slice of bytes.
func (ckss *CKSShare) MarshalBinary() (p []byte, err error) {
p = make([]byte, ckss.BinarySize())
_, err = ckss.Read(p)
return
buf := bytes.NewBuffer([]byte{})
_, err = ckss.WriteTo(buf)
return buf.Bytes(), nil
}
// Read encodes the object into a binary form on a preallocated slice of bytes
// Encode encodes the object into a binary form on a preallocated slice of bytes
// and returns the number of bytes written.
func (ckss *CKSShare) Read(p []byte) (ptr int, err error) {
return ckss.Value.Read(p)
func (ckss *CKSShare) Encode(p []byte) (ptr int, err error) {
return ckss.Value.Encode(p)
}
// WriteTo writes the object on an io.Writer.
@@ -187,21 +189,21 @@ func (ckss *CKSShare) WriteTo(w io.Writer) (n int64, err error) {
return ckss.Value.WriteTo(w)
}
// UnmarshalBinary decodes a slice of bytes generated by MarshalBinary,
// WriteTo or Read on the object.
// UnmarshalBinary decodes a slice of bytes generated by
// MarshalBinary or WriteTo on the object.
func (ckss *CKSShare) UnmarshalBinary(p []byte) (err error) {
_, err = ckss.Write(p)
_, err = ckss.ReadFrom(bytes.NewBuffer(p))
return
}
// Write decodes a slice of bytes generated by MarshalBinary or
// Read on the object and returns the number of bytes read.
func (ckss *CKSShare) Write(p []byte) (ptr int, err error) {
// Decode decodes a slice of bytes generated by Encode
// on the object and returns the number of bytes read.
func (ckss *CKSShare) Decode(p []byte) (ptr int, err error) {
if ckss.Value == nil {
ckss.Value = new(ring.Poly)
}
return ckss.Value.Write(p)
return ckss.Value.Decode(p)
}
// ReadFrom reads on the object from an io.Writer.

View File

@@ -2,6 +2,7 @@ package drlwe
import (
"bufio"
"bytes"
"io"
"github.com/tuneinsight/lattigo/v4/utils/buffer"
@@ -13,26 +14,27 @@ type RefreshShare struct {
S2EShare CKSShare
}
// BinarySize returns the size in bytes that the object once marshalled into a binary form.
// BinarySize returns the size in bytes of the object
// when encoded using Encode.
func (share *RefreshShare) BinarySize() int {
return share.E2SShare.BinarySize() + share.S2EShare.BinarySize()
}
// MarshalBinary encodes the object into a binary form on a newly allocated slice of bytes.
func (share *RefreshShare) MarshalBinary() (p []byte, err error) {
p = make([]byte, share.BinarySize())
_, err = share.Read(p)
return
buf := bytes.NewBuffer([]byte{})
_, err = share.WriteTo(buf)
return buf.Bytes(), nil
}
// Read encodes the object into a binary form on a preallocated slice of bytes
// Encode encodes the object into a binary form on a preallocated slice of bytes
// and returns the number of bytes written.
func (share *RefreshShare) Read(p []byte) (n int, err error) {
if n, err = share.E2SShare.Read(p[n:]); err != nil {
func (share *RefreshShare) Encode(p []byte) (n int, err error) {
if n, err = share.E2SShare.Encode(p[n:]); err != nil {
return
}
var inc int
inc, err = share.S2EShare.Read(p[n:])
inc, err = share.S2EShare.Encode(p[n:])
return n + inc, err
}
@@ -57,21 +59,21 @@ func (share *RefreshShare) WriteTo(w io.Writer) (n int64, err error) {
}
}
// UnmarshalBinary decodes a slice of bytes generated by MarshalBinary,
// WriteTo or Read on the object.
// UnmarshalBinary decodes a slice of bytes generated by
// MarshalBinary or WriteTo on the object.
func (share *RefreshShare) UnmarshalBinary(p []byte) (err error) {
_, err = share.Write(p)
_, err = share.ReadFrom(bytes.NewBuffer(p))
return
}
// Write decodes a slice of bytes generated by MarshalBinary or
// Read on the object and returns the number of bytes read.
func (share *RefreshShare) Write(p []byte) (n int, err error) {
if n, err = share.E2SShare.Write(p[n:]); err != nil {
// Decode decodes a slice of bytes generated by Encode
// on the object and returns the number of bytes read.
func (share *RefreshShare) Decode(p []byte) (n int, err error) {
if n, err = share.E2SShare.Decode(p[n:]); err != nil {
return
}
var inc int
inc, err = share.S2EShare.Write(p[n:])
inc, err = share.S2EShare.Decode(p[n:])
return n + inc, err
}

View File

@@ -174,7 +174,8 @@ func (cmb *Combiner) lagrangeCoeff(thisKey ShamirPublicPoint, thatKey ShamirPubl
cmb.ringQP.MulRNSScalar(lagCoeff, that, lagCoeff)
}
// BinarySize returns the size in bytes that the object once marshalled into a binary form.
// BinarySize returns the size in bytes of the object
// when encoded using Encode.
func (s *ShamirSecretShare) BinarySize() int {
return s.Poly.BinarySize()
}
@@ -184,10 +185,10 @@ func (s *ShamirSecretShare) MarshalBinary() (p []byte, err error) {
return s.Poly.MarshalBinary()
}
// Read encodes the object into a binary form on a preallocated slice of bytes
// Encode encodes the object into a binary form on a preallocated slice of bytes
// and returns the number of bytes written.
func (s *ShamirSecretShare) Read(p []byte) (n int, err error) {
return s.Poly.Read(p)
func (s *ShamirSecretShare) Encode(p []byte) (n int, err error) {
return s.Poly.Encode(p)
}
// WriteTo writes the object on an io.Writer.
@@ -201,16 +202,16 @@ func (s *ShamirSecretShare) WriteTo(w io.Writer) (n int64, err error) {
return s.Poly.WriteTo(w)
}
// UnmarshalBinary decodes a slice of bytes generated by MarshalBinary,
// WriteTo or Read on the object.
// UnmarshalBinary decodes a slice of bytes generated by
// MarshalBinary or WriteTo on the object.
func (s *ShamirSecretShare) UnmarshalBinary(p []byte) (err error) {
return s.Poly.UnmarshalBinary(p)
}
// Write decodes a slice of bytes generated by MarshalBinary or
// Read on the object and returns the number of bytes read.
func (s *ShamirSecretShare) Write(p []byte) (n int, err error) {
return s.Poly.Write(p)
// Decode decodes a slice of bytes generated by Encode
// on the object and returns the number of bytes read.
func (s *ShamirSecretShare) Decode(p []byte) (n int, err error) {
return s.Poly.Decode(p)
}
// ReadFrom reads on the object from an io.Writer.

View File

@@ -1,151 +0,0 @@
package main_test
import (
"bufio"
"fmt"
"testing"
"github.com/tuneinsight/lattigo/v4/ring"
"github.com/tuneinsight/lattigo/v4/utils/sampling"
)
func Benchmark(b *testing.B) {
LogN := 15
Qi := []uint64{0x1fffffffffe00001, 0x1fffffffffc80001, 0x1fffffffffb40001, 0x1fffffffff500001,
0x1fffffffff380001, 0x1fffffffff000001, 0x1ffffffffef00001, 0x1ffffffffee80001,
0x1ffffffffeb40001, 0x1ffffffffe780001, 0x1ffffffffe600001, 0x1ffffffffe4c0001}
r, err := ring.NewRing(1<<LogN, Qi)
if err != nil {
b.Fatal(err)
}
prng, err := sampling.NewPRNG()
if err != nil {
b.Fatal(err)
}
sampler := ring.NewUniformSampler(prng, r)
pol := sampler.ReadNew()
b.Run("Read([]byte)", func(b *testing.B) {
data := make([]byte, pol.BinarySize())
b.ResetTimer()
for i := 0; i < b.N; i++ {
if _, err = pol.Read(data); err != nil {
b.Fatal(err)
}
}
})
b.Run("WriteTo(buffer.Writer)", func(b *testing.B) {
writer := NewWriter(pol.BinarySize())
w := bufio.NewWriter(writer)
b.ResetTimer()
for i := 0; i < b.N; i++ {
if _, err = pol.WriteTo(w); err != nil {
b.Fatal(err)
}
writer.n = 0
}
})
b.Run("Write([]byte)", func(b *testing.B) {
data := make([]byte, pol.BinarySize())
if _, err = pol.Read(data); err != nil {
b.Fatal(err)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
if _, err = pol.Write(data); err != nil {
b.Fatal(err)
}
}
})
b.Run("ReadFrom(utils.Reader)", func(b *testing.B) {
writer := NewWriter(pol.BinarySize())
w := bufio.NewWriter(writer)
if _, err = pol.WriteTo(w); err != nil {
b.Fatal(err)
}
if err = w.Flush(); err != nil {
b.Fatal(err)
}
reader := NewReader(writer.buff)
r := bufio.NewReader(reader)
b.ResetTimer()
for i := 0; i < b.N; i++ {
if _, err = pol.ReadFrom(r); err != nil {
b.Fatal(err)
}
reader.n = 0
}
})
}
type Reader struct {
buff []byte
n int
}
func NewReader(b []byte) *Reader {
return &Reader{
buff: b,
n: 0,
}
}
func (r *Reader) Read(b []byte) (n int, err error) {
if len(b) > len(r.buff[r.n:]) {
return 0, fmt.Errorf("cannot read: len(b)=%d > %d", len(b), len(r.buff[r.n:]))
}
copy(b, r.buff[r.n:])
r.n += len(b)
return len(b), nil
}
type Writer struct {
buff []byte
n int
}
func NewWriter(size int) *Writer {
return &Writer{
buff: make([]byte, size),
n: 0,
}
}
func (w *Writer) Write(b []byte) (n int, err error) {
if len(b) > len(w.buff[w.n:]) {
return 0, fmt.Errorf("cannot write len(b)=%d > %d", len(b), len(w.buff[w.n:]))
}
copy(w.buff[w.n:], b)
w.n += len(b)
return len(b), nil
}

View File

@@ -2,6 +2,7 @@ package ring
import (
"bufio"
"bytes"
"encoding/binary"
"fmt"
"io"
@@ -117,26 +118,26 @@ func (pol *Poly) Equal(other *Poly) bool {
}
// BinarySize returns the size in bytes of the object
// when encoded using MarshalBinary, Read or WriteTo.
// when encoded using Encode.
func BinarySize(N, Level int) (size int) {
return 16 + N*(Level+1)<<3
}
// BinarySize returns the size in bytes of the object
// when encoded using MarshalBinary, Read or WriteTo.
// when encoded using Encode.
func (pol *Poly) BinarySize() (size int) {
return BinarySize(pol.N(), pol.Level())
}
// MarshalBinary encodes the object into a binary form on a newly allocated slice of bytes.
func (pol *Poly) MarshalBinary() (p []byte, err error) {
p = make([]byte, pol.BinarySize())
_, err = pol.Read(p)
return
buf := bytes.NewBuffer([]byte{})
_, err = pol.WriteTo(buf)
return buf.Bytes(), nil
}
// UnmarshalBinary decodes a slice of bytes generated by MarshalBinary,
// WriteTo or Read on the object.
// UnmarshalBinary decodes a slice of bytes generated by
// MarshalBinary or WriteTo on the object.
func (pol *Poly) UnmarshalBinary(p []byte) (err error) {
N := int(binary.LittleEndian.Uint64(p))
@@ -146,7 +147,7 @@ func (pol *Poly) UnmarshalBinary(p []byte) (err error) {
return fmt.Errorf("cannot UnmarshalBinary: len(p)=%d != %d", len(p), size)
}
if _, err = pol.Write(p); err != nil {
if _, err = pol.ReadFrom(bytes.NewBuffer(p)); err != nil {
return
}
@@ -163,7 +164,7 @@ func (pol *Poly) UnmarshalBinary(p []byte) (err error) {
func (pol *Poly) WriteTo(w io.Writer) (int64, error) {
switch w := w.(type) {
case buffer.Writer:
case *bufio.Writer:
var err error
@@ -200,7 +201,7 @@ func (pol *Poly) WriteTo(w io.Writer) (int64, error) {
func (pol *Poly) ReadFrom(r io.Reader) (int64, error) {
switch r := r.(type) {
case buffer.Reader:
case *bufio.Reader:
var err error
var n, inc int
@@ -253,15 +254,15 @@ func (pol *Poly) ReadFrom(r io.Reader) (int64, error) {
}
}
// Read encodes the object into a binary form on a preallocated slice of bytes
// Encode encodes the object into a binary form on a preallocated slice of bytes
// and returns the number of bytes written.
func (pol *Poly) Read(p []byte) (n int, err error) {
func (pol *Poly) Encode(p []byte) (n int, err error) {
N := pol.N()
Level := pol.Level()
if len(p) < pol.BinarySize() {
return n, fmt.Errorf("cannot Read: len(p)=%d < %d", len(p), pol.BinarySize())
return n, fmt.Errorf("cannot Encode: len(p)=%d < %d", len(p), pol.BinarySize())
}
binary.LittleEndian.PutUint64(p[n:], uint64(N))
@@ -282,9 +283,9 @@ func (pol *Poly) Read(p []byte) (n int, err error) {
return
}
// Write decodes a slice of bytes generated by MarshalBinary, WriteTo or
// Read on the object and returns the number of bytes read.
func (pol *Poly) Write(p []byte) (n int, err error) {
// Decode decodes a slice of bytes generated by Encode
// on the object and returns the number of bytes read.
func (pol *Poly) Decode(p []byte) (n int, err error) {
N := int(binary.LittleEndian.Uint64(p[n:]))
n += 8
@@ -292,7 +293,7 @@ func (pol *Poly) Write(p []byte) (n int, err error) {
n += 8
if size := BinarySize(N, Level); len(p) < size {
return n, fmt.Errorf("cannot Read: len(p)=%d < ", size)
return n, fmt.Errorf("cannot Decode: len(p)=%d < ", size)
}
if pol.Buff == nil || len(pol.Buff) != N*(Level+1) {

View File

@@ -2,6 +2,7 @@ package rlwe
import (
"bufio"
"bytes"
"fmt"
"io"
@@ -79,61 +80,27 @@ func (evk *EvaluationKeySet) GetRelinearizationKey() (rk *RelinearizationKey, er
return nil, fmt.Errorf("RelinearizationKey is nil")
}
func (evk *EvaluationKeySet) BinarySize() (size int) {
size++
if evk.RelinearizationKey != nil {
size += evk.RelinearizationKey.BinarySize()
}
size++
if evk.GaloisKeys != nil {
size += evk.GaloisKeys.BinarySize()
}
return
}
// MarshalBinary encodes the object into a binary form on a newly allocated slice of bytes.
func (evk *EvaluationKeySet) MarshalBinary() (p []byte, err error) {
p = make([]byte, evk.BinarySize())
_, err = evk.Read(p)
return
}
func (evk *EvaluationKeySet) Read(p []byte) (n int, err error) {
var inc int
if evk.RelinearizationKey != nil {
p[n] = 1
n++
if inc, err = evk.RelinearizationKey.Read(p[n:]); err != nil {
return n + inc, err
}
n += inc
} else {
n++
}
if evk.GaloisKeys != nil {
p[n] = 1
n++
if inc, err = evk.GaloisKeys.Read(p[n:]); err != nil {
return n + inc, err
}
n += inc
} else {
n++
}
buf := bytes.NewBuffer([]byte{})
_, err = evk.WriteTo(buf)
return buf.Bytes(), nil
}
// UnmarshalBinary decodes a slice of bytes generated by
// MarshalBinary or WriteTo on the object.
func (evk *EvaluationKeySet) UnmarshalBinary(p []byte) (err error) {
_, err = evk.ReadFrom(bytes.NewBuffer(p))
return
}
// WriteTo writes the object on an io.Writer.
// To ensure optimal efficiency and minimal allocations, the user is encouraged
// to provide a struct implementing the interface buffer.Writer, which defines
// a subset of the method of the bufio.Writer.
// If w is not compliant to the buffer.Writer interface, it will be wrapped in
// a new bufio.Writer.
// For additional information, see lattigo/utils/buffer/writer.go.
func (evk *EvaluationKeySet) WriteTo(w io.Writer) (int64, error) {
switch w := w.(type) {
case buffer.Writer:
@@ -189,50 +156,13 @@ func (evk *EvaluationKeySet) WriteTo(w io.Writer) (int64, error) {
}
}
func (evk *EvaluationKeySet) UnmarshalBinary(p []byte) (err error) {
_, err = evk.Write(p)
return
}
func (evk *EvaluationKeySet) Write(p []byte) (n int, err error) {
var inc int
if p[n] == 1 {
n++
if evk.RelinearizationKey == nil {
evk.RelinearizationKey = new(RelinearizationKey)
}
if inc, err = evk.RelinearizationKey.Write(p[n:]); err != nil {
return n + inc, err
}
n += inc
} else {
n++
}
if p[n] == 1 {
n++
if evk.GaloisKeys == nil {
evk.GaloisKeys = structs.Map[uint64, GaloisKey]{}
}
if inc, err = evk.GaloisKeys.Write(p[n:]); err != nil {
return n + inc, err
}
n += inc
} else {
n++
}
return
}
// ReadFrom reads on the object from an io.Writer.
// To ensure optimal efficiency and minimal allocations, the user is encouraged
// to provide a struct implementing the interface buffer.Reader, which defines
// a subset of the method of the bufio.Reader.
// If r is not compliant to the buffer.Reader interface, it will be wrapped in
// a new bufio.Reader.
// For additional information, see lattigo/utils/buffer/reader.go.
func (evk *EvaluationKeySet) ReadFrom(r io.Reader) (n int64, err error) {
switch r := r.(type) {
case buffer.Reader:
@@ -286,3 +216,95 @@ func (evk *EvaluationKeySet) ReadFrom(r io.Reader) (n int64, err error) {
return evk.ReadFrom(bufio.NewReader(r))
}
}
func (evk *EvaluationKeySet) BinarySize() (size int) {
size++
if evk.RelinearizationKey != nil {
size += evk.RelinearizationKey.BinarySize()
}
size++
if evk.GaloisKeys != nil {
size += evk.GaloisKeys.BinarySize()
}
return
}
// Encode encodes the object into a binary form on a preallocated slice of bytes
// and returns the number of bytes written.
func (evk *EvaluationKeySet) Encode(p []byte) (n int, err error) {
var inc int
if evk.RelinearizationKey != nil {
p[n] = 1
n++
if inc, err = evk.RelinearizationKey.Encode(p[n:]); err != nil {
return n + inc, err
}
n += inc
} else {
n++
}
if evk.GaloisKeys != nil {
p[n] = 1
n++
if inc, err = evk.GaloisKeys.Encode(p[n:]); err != nil {
return n + inc, err
}
n += inc
} else {
n++
}
return
}
// Decode decodes a slice of bytes generated by Encode
// on the object and returns the number of bytes read.
func (evk *EvaluationKeySet) Decode(p []byte) (n int, err error) {
var inc int
if p[n] == 1 {
n++
if evk.RelinearizationKey == nil {
evk.RelinearizationKey = new(RelinearizationKey)
}
if inc, err = evk.RelinearizationKey.Decode(p[n:]); err != nil {
return n + inc, err
}
n += inc
} else {
n++
}
if p[n] == 1 {
n++
if evk.GaloisKeys == nil {
evk.GaloisKeys = structs.Map[uint64, GaloisKey]{}
}
if inc, err = evk.GaloisKeys.Decode(p[n:]); err != nil {
return n + inc, err
}
n += inc
} else {
n++
}
return
}

View File

@@ -1,6 +1,7 @@
package rlwe
import (
"bytes"
"io"
"github.com/google/go-cmp/cmp"
@@ -65,15 +66,17 @@ func (ct *GadgetCiphertext) CopyNew() (ctCopy *GadgetCiphertext) {
return &GadgetCiphertext{Value: v}
}
// BinarySize returns the size in bytes that the object once marshalled into a binary form.
func (ct *GadgetCiphertext) BinarySize() (dataLen int) {
return ct.Value.BinarySize()
}
// MarshalBinary encodes the object into a binary form on a newly allocated slice of bytes.
func (ct *GadgetCiphertext) MarshalBinary() (data []byte, err error) {
data = make([]byte, ct.BinarySize())
_, err = ct.Value.Read(data)
buf := bytes.NewBuffer([]byte{})
_, err = ct.WriteTo(buf)
return buf.Bytes(), nil
}
// UnmarshalBinary decodes a slice of bytes generated by
// MarshalBinary or WriteTo on the object.
func (ct *GadgetCiphertext) UnmarshalBinary(p []byte) (err error) {
_, err = ct.ReadFrom(bytes.NewBuffer(p))
return
}
@@ -88,12 +91,6 @@ func (ct *GadgetCiphertext) WriteTo(w io.Writer) (n int64, err error) {
return ct.Value.WriteTo(w)
}
// Read encodes the object into a binary form on a preallocated slice of bytes
// and returns the number of bytes written.
func (ct *GadgetCiphertext) Read(p []byte) (n int, err error) {
return ct.Value.Read(p)
}
// ReadFrom reads on the object from an io.Writer.
// To ensure optimal efficiency and minimal allocations, the user is encouraged
// to provide a struct implementing the interface buffer.Reader, which defines
@@ -105,17 +102,22 @@ func (ct *GadgetCiphertext) ReadFrom(r io.Reader) (n int64, err error) {
return ct.Value.ReadFrom(r)
}
// UnmarshalBinary decodes a slice of bytes generated by MarshalBinary,
// WriteTo or Read on the object.
func (ct *GadgetCiphertext) UnmarshalBinary(p []byte) (err error) {
_, err = ct.Value.Write(p)
return
// BinarySize returns the size in bytes of the object
// when encoded using Encode.
func (ct *GadgetCiphertext) BinarySize() (dataLen int) {
return ct.Value.BinarySize()
}
// Write decodes a slice of bytes generated by MarshalBinary or
// Read on the object and returns the number of bytes read.
func (ct *GadgetCiphertext) Write(p []byte) (n int, err error) {
return ct.Value.Write(p)
// Encode encodes the object into a binary form on a preallocated slice of bytes
// and returns the number of bytes written.
func (ct *GadgetCiphertext) Encode(p []byte) (n int, err error) {
return ct.Value.Encode(p)
}
// Decode decodes a slice of bytes generated by Encode
// on the object and returns the number of bytes read.
func (ct *GadgetCiphertext) Decode(p []byte) (n int, err error) {
return ct.Value.Decode(p)
}
// AddPolyTimesGadgetVectorToGadgetCiphertext takes a plaintext polynomial and a list of Ciphertexts and adds the

View File

@@ -2,6 +2,7 @@ package rlwe
import (
"bufio"
"bytes"
"encoding/binary"
"fmt"
"io"
@@ -46,40 +47,11 @@ func (gk *GaloisKey) CopyNew() *GaloisKey {
}
}
// BinarySize returns the size in bytes that the object once marshalled into a binary form.
func (gk *GaloisKey) BinarySize() (size int) {
return gk.EvaluationKey.BinarySize() + 16
}
// MarshalBinary encodes the object into a binary form on a newly allocated slice of bytes.
func (gk *GaloisKey) MarshalBinary() (p []byte, err error) {
p = make([]byte, gk.BinarySize())
_, err = gk.Read(p)
return
}
// Read encodes the object into a binary form on a preallocated slice of bytes
// and returns the number of bytes written.
func (gk *GaloisKey) Read(p []byte) (n int, err error) {
if len(p) < 16 {
return n, fmt.Errorf("cannot read: len(p) < 16")
}
binary.LittleEndian.PutUint64(p[n:], gk.GaloisElement)
n += 8
binary.LittleEndian.PutUint64(p[n:], gk.NthRoot)
n += 8
var inc int
if inc, err = gk.EvaluationKey.Read(p[n:]); err != nil {
return
}
n += inc
return
buf := bytes.NewBuffer([]byte{})
_, err = gk.WriteTo(buf)
return buf.Bytes(), nil
}
// WriteTo writes the object on an io.Writer.
@@ -121,10 +93,10 @@ func (gk *GaloisKey) WriteTo(w io.Writer) (n int64, err error) {
}
}
// UnmarshalBinary decodes a slice of bytes generated by MarshalBinary,
// WriteTo or Read on the object.
// UnmarshalBinary decodes a slice of bytes generated by
// MarshalBinary or WriteTo on the object.
func (gk *GaloisKey) UnmarshalBinary(p []byte) (err error) {
_, err = gk.Write(p)
_, err = gk.ReadFrom(bytes.NewBuffer(p))
return
}
@@ -166,12 +138,42 @@ func (gk *GaloisKey) ReadFrom(r io.Reader) (n int64, err error) {
}
}
// Write decodes a slice of bytes generated by MarshalBinary or
// Read on the object and returns the number of bytes read.
func (gk *GaloisKey) Write(p []byte) (n int, err error) {
// BinarySize returns the size in bytes of the object
// when encoded using Encode.
func (gk *GaloisKey) BinarySize() (size int) {
return gk.EvaluationKey.BinarySize() + 16
}
// Encode encodes the object into a binary form on a preallocated slice of bytes
// and returns the number of bytes written.
func (gk *GaloisKey) Encode(p []byte) (n int, err error) {
if len(p) < 16 {
return n, fmt.Errorf("cannot read: len(p) < 16")
return n, fmt.Errorf("cannot Encode: len(p) < 16")
}
binary.LittleEndian.PutUint64(p[n:], gk.GaloisElement)
n += 8
binary.LittleEndian.PutUint64(p[n:], gk.NthRoot)
n += 8
var inc int
if inc, err = gk.EvaluationKey.Encode(p[n:]); err != nil {
return
}
n += inc
return
}
// Decode decodes a slice of bytes generated by Encode
// on the object and returns the number of bytes read.
func (gk *GaloisKey) Decode(p []byte) (n int, err error) {
if len(p) < 16 {
return n, fmt.Errorf("cannot Decode: len(p) < 16")
}
gk.GaloisElement = binary.LittleEndian.Uint64(p[n:])
@@ -181,7 +183,7 @@ func (gk *GaloisKey) Write(p []byte) (n int, err error) {
n += 8
var inc int
if inc, err = gk.EvaluationKey.Write(p[n:]); err != nil {
if inc, err = gk.EvaluationKey.Decode(p[n:]); err != nil {
return
}

View File

@@ -25,25 +25,25 @@ func (m *MetaData) BinarySize() int {
}
// MarshalBinary encodes the object into a binary form on a newly allocated slice of bytes.
func (m *MetaData) MarshalBinary() (data []byte, err error) {
data = make([]byte, m.BinarySize())
_, err = m.Read(data)
func (m *MetaData) MarshalBinary() (p []byte, err error) {
p = make([]byte, m.BinarySize())
_, err = m.Encode(p)
return
}
// UnmarshalBinary decodes a slice of bytes generated by MarshalBinary,
// WriteTo or Read on the object.
func (m *MetaData) UnmarshalBinary(data []byte) (err error) {
_, err = m.Write(data)
// UnmarshalBinary decodes a slice of bytes generated by
// MarshalBinary or WriteTo on the object.
func (m *MetaData) UnmarshalBinary(p []byte) (err error) {
_, err = m.Decode(p)
return
}
// WriteTo writes the object on an io.Writer.
func (m *MetaData) WriteTo(w io.Writer) (int64, error) {
if data, err := m.MarshalBinary(); err != nil {
if p, err := m.MarshalBinary(); err != nil {
return 0, err
} else {
if n, err := w.Write(data); err != nil {
if n, err := w.Write(p); err != nil {
return int64(n), err
} else {
return int64(n), nil
@@ -52,58 +52,58 @@ func (m *MetaData) WriteTo(w io.Writer) (int64, error) {
}
func (m *MetaData) ReadFrom(r io.Reader) (int64, error) {
data := make([]byte, m.BinarySize())
if n, err := r.Read(data); err != nil {
return int64(n), err
p := make([]byte, m.BinarySize())
if n, err := r.Read(p); err != nil {
return int64(n), nil
} else {
return int64(n), m.UnmarshalBinary(data)
return int64(n), m.UnmarshalBinary(p)
}
}
// Read encodes the object into a binary form on a preallocated slice of bytes
// Encode encodes the object into a binary form on a preallocated slice of bytes
// and returns the number of bytes written.
func (m *MetaData) Read(data []byte) (ptr int, err error) {
func (m *MetaData) Encode(p []byte) (n int, err error) {
if len(data) < m.BinarySize() {
return 0, fmt.Errorf("cannot write: len(data) is too small")
if len(p) < m.BinarySize() {
return 0, fmt.Errorf("cannot Encode: len(p) is too small")
}
if ptr, err = m.Scale.Read(data[ptr:]); err != nil {
if n, err = m.Scale.Encode(p[n:]); err != nil {
return 0, err
}
if m.IsNTT {
data[ptr] = 1
p[n] = 1
}
ptr++
n++
if m.IsMontgomery {
data[ptr] = 1
p[n] = 1
}
ptr++
n++
return
}
// Write decodes a slice of bytes generated by MarshalBinary or
// Read on the object and returns the number of bytes read.
func (m *MetaData) Write(data []byte) (ptr int, err error) {
// Decode decodes a slice of bytes generated by Encode
// on the object and returns the number of bytes read.
func (m *MetaData) Decode(p []byte) (n int, err error) {
if len(data) < m.BinarySize() {
return 0, fmt.Errorf("canoot read: len(data) is too small")
if len(p) < m.BinarySize() {
return 0, fmt.Errorf("canoot Decode: len(p) is too small")
}
if ptr, err = m.Scale.Write(data[ptr:]); err != nil {
if n, err = m.Scale.Decode(p[n:]); err != nil {
return
}
m.IsNTT = data[ptr] == 1
ptr++
m.IsNTT = p[n] == 1
n++
m.IsMontgomery = data[ptr] == 1
ptr++
m.IsMontgomery = p[n] == 1
n++
return
}

View File

@@ -1,6 +1,7 @@
package rlwe
import (
"bytes"
"fmt"
"io"
@@ -224,15 +225,17 @@ func SwitchCiphertextRingDegree(ctIn, ctOut *OperandQ) {
ctOut.MetaData = ctIn.MetaData
}
// BinarySize returns the size in bytes that the object once marshalled into a binary form.
func (op *OperandQ) BinarySize() int {
return op.MetaData.BinarySize() + op.Value.BinarySize()
}
// MarshalBinary encodes the object into a binary form on a newly allocated slice of bytes.
func (op *OperandQ) MarshalBinary() (data []byte, err error) {
data = make([]byte, op.BinarySize())
_, err = op.Read(data)
buf := bytes.NewBuffer([]byte{})
_, err = op.WriteTo(buf)
return buf.Bytes(), nil
}
// UnmarshalBinary decodes a slice of bytes generated by MarshalBinary
// or Read on the objeop.
func (op *OperandQ) UnmarshalBinary(p []byte) (err error) {
_, err = op.ReadFrom(bytes.NewBuffer(p))
return
}
@@ -276,39 +279,38 @@ func (op *OperandQ) ReadFrom(r io.Reader) (n int64, err error) {
return n + inc, err
}
// Read encodes the object into a binary form on a preallocated slice of bytes
// BinarySize returns the size in bytes of the object
// when encoded using Encode.
func (op *OperandQ) BinarySize() int {
return op.MetaData.BinarySize() + op.Value.BinarySize()
}
// Encode encodes the object into a binary form on a preallocated slice of bytes
// and returns the number of bytes written.
func (op *OperandQ) Read(p []byte) (n int, err error) {
func (op *OperandQ) Encode(p []byte) (n int, err error) {
if len(p) < op.BinarySize() {
return 0, fmt.Errorf("cannote write: len(p) is too small")
return 0, fmt.Errorf("cannot Encode: len(p) is too small")
}
if n, err = op.MetaData.Read(p); err != nil {
if n, err = op.MetaData.Encode(p); err != nil {
return
}
inc, err := op.Value.Read(p[n:])
inc, err := op.Value.Encode(p[n:])
return n + inc, err
}
// UnmarshalBinary decodes a slice of bytes generated by MarshalBinary
// or Read on the objeop.
func (op *OperandQ) UnmarshalBinary(p []byte) (err error) {
_, err = op.Write(p)
return
}
// Decode decodes a slice of bytes generated by Encode
// on the object and returns the number of bytes read.
func (op *OperandQ) Decode(p []byte) (n int, err error) {
// Write decodes a slice of bytes generated by MarshalBinary or
// Read on the object and returns the number of bytes read.
func (op *OperandQ) Write(p []byte) (n int, err error) {
if n, err = op.MetaData.Write(p); err != nil {
if n, err = op.MetaData.Decode(p); err != nil {
return
}
inc, err := op.Value.Write(p[n:])
inc, err := op.Value.Decode(p[n:])
return n + inc, err
}
@@ -371,15 +373,17 @@ func (op *OperandQP) CopyNew() *OperandQP {
return &OperandQP{Value: Value, MetaData: op.MetaData}
}
// BinarySize returns the size in bytes that the object once marshalled into a binary form.
func (op *OperandQP) BinarySize() int {
return op.MetaData.BinarySize() + op.Value.BinarySize()
}
// MarshalBinary encodes the object into a binary form on a newly allocated slice of bytes.
func (op *OperandQP) MarshalBinary() (data []byte, err error) {
data = make([]byte, op.BinarySize())
_, err = op.Read(data)
buf := bytes.NewBuffer([]byte{})
_, err = op.WriteTo(buf)
return buf.Bytes(), nil
}
// UnmarshalBinary decodes a slice of bytes generated by MarshalBinary
// or Read on the objeop.
func (op *OperandQP) UnmarshalBinary(p []byte) (err error) {
_, err = op.ReadFrom(bytes.NewBuffer(p))
return
}
@@ -423,39 +427,38 @@ func (op *OperandQP) ReadFrom(r io.Reader) (n int64, err error) {
return n + inc, err
}
// Read encodes the object into a binary form on a preallocated slice of bytes
// BinarySize returns the size in bytes of the object
// when encoded using Encode.
func (op *OperandQP) BinarySize() int {
return op.MetaData.BinarySize() + op.Value.BinarySize()
}
// Encode encodes the object into a binary form on a preallocated slice of bytes
// and returns the number of bytes written.
func (op *OperandQP) Read(p []byte) (n int, err error) {
func (op *OperandQP) Encode(p []byte) (n int, err error) {
if len(p) < op.BinarySize() {
return 0, fmt.Errorf("cannote write: len(p) is too small")
return 0, fmt.Errorf("cannote Encode: len(p) is too small")
}
if n, err = op.MetaData.Read(p); err != nil {
if n, err = op.MetaData.Encode(p); err != nil {
return
}
inc, err := op.Value.Read(p[n:])
inc, err := op.Value.Encode(p[n:])
return n + inc, err
}
// UnmarshalBinary decodes a slice of bytes generated by MarshalBinary
// or Read on the objeop.
func (op *OperandQP) UnmarshalBinary(p []byte) (err error) {
_, err = op.Write(p)
return
}
// Decode decodes a slice of bytes generated by Encode
// on the object and returns the number of bytes read.
func (op *OperandQP) Decode(p []byte) (n int, err error) {
// Write decodes a slice of bytes generated by MarshalBinary or
// Read on the object and returns the number of bytes read.
func (op *OperandQP) Write(p []byte) (n int, err error) {
if n, err = op.MetaData.Write(p); err != nil {
if n, err = op.MetaData.Decode(p); err != nil {
return
}
inc, err := op.Value.Write(p[n:])
inc, err := op.Value.Decode(p[n:])
return n + inc, err
}

View File

@@ -57,10 +57,10 @@ func (pt *Plaintext) UnmarshalBinary(p []byte) (err error) {
return
}
// Write decodes a slice of bytes generated by MarshalBinary or
// Read on the object and returns the number of bytes read.
func (pt *Plaintext) Write(p []byte) (n int, err error) {
if n, err = pt.OperandQ.Write(p); err != nil {
// Decode decodes a slice of bytes generated by Encode
// on the object and returns the number of bytes read.
func (pt *Plaintext) Decode(p []byte) (n int, err error) {
if n, err = pt.OperandQ.Decode(p); err != nil {
return
}
pt.Value = pt.OperandQ.Value[0]

View File

@@ -2,6 +2,7 @@ package rlwe
import (
"bufio"
"bytes"
"fmt"
"io"
@@ -27,16 +28,17 @@ func NewPowerBasis(ct *Ciphertext, basis polynomial.Basis) (p *PowerBasis) {
return
}
// BinarySize returns the size in bytes of the object
// when encoded using MarshalBinary, Read or WriteTo.
func (p *PowerBasis) BinarySize() (size int) {
return 1 + p.Value.BinarySize()
}
// MarshalBinary encodes the object into a binary form on a newly allocated slice of bytes.
func (p *PowerBasis) MarshalBinary() (data []byte, err error) {
data = make([]byte, p.BinarySize())
_, err = p.Read(data)
buf := bytes.NewBuffer([]byte{})
_, err = p.WriteTo(buf)
return buf.Bytes(), nil
}
// UnmarshalBinary decodes a slice of bytes generated by
// MarshalBinary or WriteTo on the object.
func (p *PowerBasis) UnmarshalBinary(data []byte) (err error) {
_, err = p.ReadFrom(bytes.NewBuffer(data))
return
}
@@ -69,29 +71,6 @@ func (p *PowerBasis) WriteTo(w io.Writer) (n int64, err error) {
}
}
// Read encodes the object into a binary form on a preallocated slice of bytes
// and returns the number of bytes written.
func (p *PowerBasis) Read(data []byte) (n int, err error) {
if len(data) < p.BinarySize() {
return n, fmt.Errorf("cannot Read: len(data)=%d < %d", len(data), p.BinarySize())
}
data[n] = uint8(p.Basis)
n++
inc, err := p.Value.Read(data[n:])
return n + inc, err
}
// UnmarshalBinary decodes a slice of bytes generated by MarshalBinary,
// WriteTo or Read on the object.
func (p *PowerBasis) UnmarshalBinary(data []byte) (err error) {
_, err = p.Write(data)
return
}
// ReadFrom reads on the object from an io.Writer.
// To ensure optimal efficiency and minimal allocations, the user is encouraged
// to provide a struct implementing the interface buffer.Reader, which defines
@@ -127,9 +106,31 @@ func (p *PowerBasis) ReadFrom(r io.Reader) (n int64, err error) {
}
}
// Write decodes a slice of bytes generated by MarshalBinary, WriteTo or
// Read on the object and returns the number of bytes read.
func (p *PowerBasis) Write(data []byte) (n int, err error) {
// BinarySize returns the size in bytes of the object
// when encoded using Encode.
func (p *PowerBasis) BinarySize() (size int) {
return 1 + p.Value.BinarySize()
}
// Encode encodes the object into a binary form on a preallocated slice of bytes
// and returns the number of bytes written.
func (p *PowerBasis) Encode(data []byte) (n int, err error) {
if len(data) < p.BinarySize() {
return n, fmt.Errorf("cannot Encode: len(data)=%d < %d", len(data), p.BinarySize())
}
data[n] = uint8(p.Basis)
n++
inc, err := p.Value.Encode(data[n:])
return n + inc, err
}
// Decode decodes a slice of bytes generated by Encode
// on the object and returns the number of bytes read.
func (p *PowerBasis) Decode(data []byte) (n int, err error) {
p.Basis = polynomial.Basis(data[n])
n++
@@ -138,7 +139,7 @@ func (p *PowerBasis) Write(data []byte) (n int, err error) {
p.Value = map[int]*Ciphertext{}
}
inc, err := p.Value.Write(data[n:])
inc, err := p.Value.Decode(data[n:])
return n + inc, err
}

View File

@@ -2,6 +2,7 @@ package ringqp
import (
"bufio"
"bytes"
"io"
"github.com/google/go-cmp/cmp"
@@ -115,7 +116,8 @@ func (p *Poly) Resize(levelQ, levelP int) {
}
}
// BinarySize returns the size in bytes that the object once marshalled into a binary form.
// BinarySize returns the size in bytes of the object
// when encoded using Encode.
// Assumes that each coefficient takes 8 bytes.
func (p *Poly) BinarySize() (dataLen int) {
@@ -263,9 +265,9 @@ func (p *Poly) ReadFrom(r io.Reader) (n int64, err error) {
}
}
// Read encodes the object into a binary form on a preallocated slice of bytes
// Encode encodes the object into a binary form on a preallocated slice of bytes
// and returns the number of bytes written.
func (p *Poly) Read(data []byte) (n int, err error) {
func (p *Poly) Encode(data []byte) (n int, err error) {
var inc int
if p.Q != nil {
@@ -279,14 +281,14 @@ func (p *Poly) Read(data []byte) (n int, err error) {
n = 2
if data[0] == 1 {
if inc, err = p.Q.Read(data[n:]); err != nil {
if inc, err = p.Q.Encode(data[n:]); err != nil {
return
}
n += inc
}
if data[1] == 1 {
if inc, err = p.P.Read(data[n:]); err != nil {
if inc, err = p.P.Encode(data[n:]); err != nil {
return
}
n += inc
@@ -295,9 +297,9 @@ func (p *Poly) Read(data []byte) (n int, err error) {
return
}
// Write decodes a slice of bytes generated by MarshalBinary or
// Read on the object and returns the number of bytes read.
func (p *Poly) Write(data []byte) (n int, err error) {
// Decode decodes a slice of bytes generated by Encode
// on the object and returns the number of bytes read.
func (p *Poly) Decode(data []byte) (n int, err error) {
var inc int
n = 2
@@ -308,7 +310,7 @@ func (p *Poly) Write(data []byte) (n int, err error) {
p.Q = new(ring.Poly)
}
if inc, err = p.Q.Write(data[n:]); err != nil {
if inc, err = p.Q.Decode(data[n:]); err != nil {
return
}
n += inc
@@ -320,7 +322,7 @@ func (p *Poly) Write(data []byte) (n int, err error) {
p.P = new(ring.Poly)
}
if inc, err = p.P.Write(data[n:]); err != nil {
if inc, err = p.P.Decode(data[n:]); err != nil {
return
}
n += inc
@@ -331,14 +333,14 @@ func (p *Poly) Write(data []byte) (n int, err error) {
// MarshalBinary encodes the object into a binary form on a newly allocated slice of bytes.
func (p *Poly) MarshalBinary() (data []byte, err error) {
data = make([]byte, p.BinarySize())
_, err = p.Read(data)
return
buf := bytes.NewBuffer([]byte{})
_, err = p.WriteTo(buf)
return buf.Bytes(), nil
}
// UnmarshalBinary decodes a slice of bytes generated by MarshalBinary,
// WriteTo or Read on the object.
// UnmarshalBinary decodes a slice of bytes generated by
// MarshalBinary or WriteTo on the object.
func (p *Poly) UnmarshalBinary(data []byte) (err error) {
_, err = p.Write(data)
_, err = p.ReadFrom(bytes.NewBuffer(data))
return err
}

View File

@@ -134,20 +134,22 @@ func (s Scale) Min(s1 Scale) (max Scale) {
return s
}
// BinarySize returns the size in bytes that the object once marshalled into a binary form.
func (s Scale) BinarySize() int {
return 48
// MarshalBinary encodes the object into a binary form on a newly allocated slice of bytes.
func (s Scale) MarshalBinary() (p []byte, err error) {
p = make([]byte, s.BinarySize())
_, err = s.Encode(p)
return
}
// MarshalBinary encodes the object into a binary form on a newly allocated slice of bytes.
func (s Scale) MarshalBinary() (data []byte, err error) {
data = make([]byte, s.BinarySize())
_, err = s.Read(data)
// UnmarshalBinary decodes a slice of bytes generated by
// MarshalBinary or WriteTo on the object.
func (s Scale) UnmarshalBinary(p []byte) (err error) {
_, err = s.Decode(p)
return
}
// MarshalJSON encodes the object into a binary form on a newly allocated slice of bytes.
func (s Scale) MarshalJSON() (data []byte, err error) {
func (s Scale) MarshalJSON() (p []byte, err error) {
aux := &struct {
Value *big.Float
Mod *big.Int
@@ -158,39 +160,7 @@ func (s Scale) MarshalJSON() (data []byte, err error) {
return json.Marshal(aux)
}
// Read encodes the object into a binary form on a preallocated slice of bytes
// and returns the number of bytes written.
func (s Scale) Read(data []byte) (ptr int, err error) {
var sBytes []byte
if sBytes, err = s.Value.MarshalText(); err != nil {
return
}
b := make([]byte, s.BinarySize())
if len(data) < len(b) {
return 0, fmt.Errorf("cannot write: len(data) < %d", len(b))
}
b[0] = uint8(len(sBytes))
copy(b[1:], sBytes)
copy(data, b)
if s.Mod != nil {
binary.LittleEndian.PutUint64(data[40:], s.Mod.Uint64())
}
return s.BinarySize(), nil
}
// UnmarshalBinary decodes a slice of bytes generated by MarshalBinary,
// WriteTo or Read on the object.
func (s Scale) UnmarshalBinary(data []byte) (err error) {
_, err = s.Write(data)
return
}
func (s *Scale) UnmarshalJSON(data []byte) (err error) {
func (s *Scale) UnmarshalJSON(p []byte) (err error) {
aux := &struct {
Value *big.Float
@@ -200,7 +170,7 @@ func (s *Scale) UnmarshalJSON(data []byte) (err error) {
Mod: s.Mod,
}
if err = json.Unmarshal(data, aux); err != nil {
if err = json.Unmarshal(p, aux); err != nil {
return
}
@@ -210,27 +180,58 @@ func (s *Scale) UnmarshalJSON(data []byte) (err error) {
return
}
// Write decodes a slice of bytes generated by MarshalBinary or
// Read on the object and returns the number of bytes read.
func (s *Scale) Write(data []byte) (ptr int, err error) {
// BinarySize returns the size in bytes of the object
// when encoded using Encode.
func (s Scale) BinarySize() int {
return 48
}
if dLen := s.BinarySize(); len(data) < dLen {
return 0, fmt.Errorf("cannot read: len(data) < %d", dLen)
// Encode encodes the object into a binary form on a preallocated slice of bytes
// and returns the number of bytes written.
func (s Scale) Encode(p []byte) (ptr int, err error) {
var sBytes []byte
if sBytes, err = s.Value.MarshalText(); err != nil {
return
}
bLen := data[0]
b := make([]byte, s.BinarySize())
if len(p) < len(b) {
return 0, fmt.Errorf("cannot Encode: len(p) < %d", len(b))
}
b[0] = uint8(len(sBytes))
copy(b[1:], sBytes)
copy(p, b)
if s.Mod != nil {
binary.LittleEndian.PutUint64(p[40:], s.Mod.Uint64())
}
return s.BinarySize(), nil
}
// Decode decodes a slice of bytes generated by Encode
// on the object and returns the number of bytes read.
func (s *Scale) Decode(p []byte) (ptr int, err error) {
if dLen := s.BinarySize(); len(p) < dLen {
return 0, fmt.Errorf("cannot Decode: len(p) < %d", dLen)
}
bLen := p[0]
v := new(big.Float)
if data[1] != 0x30 || bLen > 1 { // 0x30 indicates an empty big.Float
if err = v.UnmarshalText(data[1 : bLen+1]); err != nil {
if p[1] != 0x30 || bLen > 1 { // 0x30 indicates an empty big.Float
if err = v.UnmarshalText(p[1 : bLen+1]); err != nil {
return 0, err
}
v.SetPrec(ScalePrecision)
}
mod := binary.LittleEndian.Uint64(data[40:])
mod := binary.LittleEndian.Uint64(p[40:])
s.Value = *v

View File

@@ -1,6 +1,7 @@
package rlwe
import (
"bytes"
"io"
"github.com/google/go-cmp/cmp"
@@ -45,18 +46,11 @@ func (sk *SecretKey) CopyNew() *SecretKey {
return &SecretKey{*sk.Value.CopyNew()}
}
// BinarySize returns the size in bytes that the object once marshalled into a binary form.
func (sk *SecretKey) BinarySize() (dataLen int) {
return sk.Value.BinarySize()
}
// MarshalBinary encodes the object into a binary form on a newly allocated slice of bytes.
func (sk *SecretKey) MarshalBinary() (data []byte, err error) {
data = make([]byte, sk.BinarySize())
if _, err = sk.Read(data); err != nil {
return nil, err
}
return
func (sk *SecretKey) MarshalBinary() (p []byte, err error) {
buf := bytes.NewBuffer([]byte{})
_, err = sk.WriteTo(buf)
return buf.Bytes(), nil
}
// WriteTo writes the object on an io.Writer.
@@ -70,16 +64,10 @@ func (sk *SecretKey) WriteTo(w io.Writer) (n int64, err error) {
return sk.Value.WriteTo(w)
}
// Read encodes the object into a binary form on a preallocated slice of bytes
// and returns the number of bytes written.
func (sk *SecretKey) Read(data []byte) (ptr int, err error) {
return sk.Value.Read(data)
}
// UnmarshalBinary decodes a slice of bytes generated by MarshalBinary,
// WriteTo or Read on the object.
func (sk *SecretKey) UnmarshalBinary(data []byte) (err error) {
_, err = sk.Write(data)
// UnmarshalBinary decodes a slice of bytes generated by
// MarshalBinary or WriteTo on the object.
func (sk *SecretKey) UnmarshalBinary(p []byte) (err error) {
_, err = sk.ReadFrom(bytes.NewBuffer(p))
return
}
@@ -94,8 +82,20 @@ func (sk *SecretKey) ReadFrom(r io.Reader) (n int64, err error) {
return sk.Value.ReadFrom(r)
}
// Write decodes a slice of bytes generated by MarshalBinary or
// Read on the object and returns the number of bytes read.
func (sk *SecretKey) Write(data []byte) (ptr int, err error) {
return sk.Value.Write(data)
// BinarySize returns the size in bytes of the object
// when encoded using Encode.
func (sk *SecretKey) BinarySize() (dataLen int) {
return sk.Value.BinarySize()
}
// Encode encodes the object into a binary form on a preallocated slice of bytes
// and returns the number of bytes written.
func (sk *SecretKey) Encode(p []byte) (ptr int, err error) {
return sk.Value.Encode(p)
}
// Decode decodes a slice of bytes generated by Encode
// on the object and returns the number of bytes read.
func (sk *SecretKey) Decode(p []byte) (ptr int, err error) {
return sk.Value.Decode(p)
}

View File

@@ -57,31 +57,39 @@ func (c *Codec[V]) UnmarshalBinaryWrapper(p []byte, T interface{}) (err error) {
return binaryunmarshaler.UnmarshalBinary(p)
}
func (c *Codec[V]) ReadWrapper(p []byte, T interface{}) (n int, err error) {
reader, ok := T.(io.Reader)
if !ok {
return 0, fmt.Errorf("cannot Read: type T=%T does not implement io.Reader", T)
}
return reader.Read(p)
type Encoder interface {
Encode(p []byte) (n int, err error)
}
func (c *Codec[V]) WriteWrapper(p []byte, T interface{}) (n int, err error) {
writer, ok := T.(io.Writer)
func (c *Codec[V]) EncodeWrapper(p []byte, T interface{}) (n int, err error) {
encoder, ok := T.(Encoder)
if !ok {
return 0, fmt.Errorf("cannot Read: type T=%T does not implement io.Writer", T)
return 0, fmt.Errorf("cannot Encode: type T=%T does not implement Encoder", T)
}
return writer.Write(p)
return encoder.Encode(p)
}
type Decoder interface {
Decode(p []byte) (n int, err error)
}
func (c *Codec[V]) DecodeWrapper(p []byte, T interface{}) (n int, err error) {
decoder, ok := T.(Decoder)
if !ok {
return 0, fmt.Errorf("cannot Decode: type T=%T does not implement Decoder", T)
}
return decoder.Decode(p)
}
func (c *Codec[V]) WriteToWrapper(w io.Writer, T interface{}) (n int64, err error) {
writerto, ok := T.(io.WriterTo)
if !ok {
return 0, fmt.Errorf("cannot Read: type T=%T does not implement io.WriterTo", T)
return 0, fmt.Errorf("cannot WriteTo: type T=%T does not implement io.WriterTo", T)
}
return writerto.WriteTo(w)
@@ -91,7 +99,7 @@ func (c *Codec[V]) ReadFromWrapper(r io.Reader, T interface{}) (n int64, err err
readerfrom, ok := T.(io.ReaderFrom)
if !ok {
return 0, fmt.Errorf("cannot Read: type T=%T does not implement io.ReaderFrom", T)
return 0, fmt.Errorf("cannot ReadFrom: type T=%T does not implement io.ReaderFrom", T)
}
return readerfrom.ReadFrom(r)

View File

@@ -2,6 +2,7 @@ package structs
import (
"bufio"
"bytes"
"encoding/binary"
"fmt"
"io"
@@ -31,63 +32,17 @@ func (m Map[V, T]) CopyNew() *Map[V, T] {
return &mcpy
}
// BinarySize returns the size in bytes that the object once marshalled into a binary form.
func (m Map[V, T]) BinarySize() (size int) {
size = 4 // #Ct
codec := Codec[T]{}
var inc int
var err error
for _, v := range m {
size += 8
if inc, err = codec.BinarySizeWrapper(v); err != nil {
panic(err)
}
size += inc
}
return
}
// MarshalBinary encodes the object into a binary form on a newly allocated slice of bytes.
func (m *Map[V, T]) MarshalBinary() (p []byte, err error) {
p = make([]byte, m.BinarySize())
_, err = m.Read(p)
return
buf := bytes.NewBuffer([]byte{})
_, err = m.WriteTo(buf)
return buf.Bytes(), nil
}
// Read encodes the object into a binary form on a preallocated slice of bytes
// and returns the number of bytes written.
func (m *Map[V, T]) Read(p []byte) (n int, err error) {
if len(p) < m.BinarySize() {
return n, fmt.Errorf("cannot Read: len(p)=%d < %d", len(p), m.BinarySize())
}
codec := Codec[T]{}
mi := *m
binary.LittleEndian.PutUint32(p[n:], uint32(len(mi)))
n += 4
for _, key := range utils.GetSortedKeys(mi) {
binary.LittleEndian.PutUint64(p[n:], uint64(key))
n += 8
var inc int
if inc, err = codec.ReadWrapper(p[n:], mi[key]); err != nil {
return n + inc, err
}
n += inc
}
// UnmarshalBinary decodes a slice of bytes generated by
// MarshalBinary or WriteTo on the object.
func (m *Map[V, T]) UnmarshalBinary(p []byte) (err error) {
_, err = m.ReadFrom(bytes.NewBuffer(p))
return
}
@@ -138,44 +93,6 @@ func (m *Map[V, T]) WriteTo(w io.Writer) (n int64, err error) {
}
}
// UnmarshalBinary decodes a slice of bytes generated by MarshalBinary,
// WriteTo or Read on the object.
func (m *Map[V, T]) UnmarshalBinary(p []byte) (err error) {
_, err = m.Write(p)
return
}
// Write decodes a slice of bytes generated by MarshalBinary, WriteTo or
// Read on the object and returns the number of bytes read.
func (m *Map[V, T]) Write(p []byte) (n int, err error) {
mi := *m
size := int(binary.LittleEndian.Uint32(p[n:]))
n += 4
codec := Codec[T]{}
for i := 0; i < size; i++ {
idx := V(binary.LittleEndian.Uint64(p[n:]))
n += 8
if mi[idx] == nil {
mi[idx] = new(T)
}
var inc int
if inc, err = codec.WriteWrapper(p[n:], mi[idx]); err != nil {
return n + inc, err
}
n += inc
}
return
}
// ReadFrom reads on the object from an io.Writer.
// To ensure optimal efficiency and minimal allocations, the user is encouraged
// to provide a struct implementing the interface buffer.Reader, which defines
@@ -228,3 +145,88 @@ func (m *Map[V, T]) ReadFrom(r io.Reader) (n int64, err error) {
return m.ReadFrom(bufio.NewReader(r))
}
}
// BinarySize returns the size in bytes of the object
// when encoded using Encode.
func (m Map[V, T]) BinarySize() (size int) {
size = 4 // #Ct
codec := Codec[T]{}
var inc int
var err error
for _, v := range m {
size += 8
if inc, err = codec.BinarySizeWrapper(v); err != nil {
panic(err)
}
size += inc
}
return
}
// Encode encodes the object into a binary form on a preallocated slice of bytes
// and returns the number of bytes written.
func (m *Map[V, T]) Encode(p []byte) (n int, err error) {
if len(p) < m.BinarySize() {
return n, fmt.Errorf("cannot Encode: len(p)=%d < %d", len(p), m.BinarySize())
}
codec := Codec[T]{}
mi := *m
binary.LittleEndian.PutUint32(p[n:], uint32(len(mi)))
n += 4
for _, key := range utils.GetSortedKeys(mi) {
binary.LittleEndian.PutUint64(p[n:], uint64(key))
n += 8
var inc int
if inc, err = codec.EncodeWrapper(p[n:], mi[key]); err != nil {
return n + inc, err
}
n += inc
}
return
}
// Decode decodes a slice of bytes generated by Encode
// on the object and returns the number of bytes read.
func (m *Map[V, T]) Decode(p []byte) (n int, err error) {
mi := *m
size := int(binary.LittleEndian.Uint32(p[n:]))
n += 4
codec := Codec[T]{}
for i := 0; i < size; i++ {
idx := V(binary.LittleEndian.Uint64(p[n:]))
n += 8
if mi[idx] == nil {
mi[idx] = new(T)
}
var inc int
if inc, err = codec.DecodeWrapper(p[n:], mi[idx]); err != nil {
return n + inc, err
}
n += inc
}
return
}

View File

@@ -2,6 +2,7 @@ package structs
import (
"bufio"
"bytes"
"encoding/binary"
"fmt"
"io"
@@ -33,61 +34,17 @@ func (m Matrix[T]) CopyNew() *Matrix[T] {
return &mcpy
}
// BinarySize returns the size in bytes of the object
// when encoded using MarshalBinary, Read or WriteTo.
func (m Matrix[T]) BinarySize() (size int) {
size += 8
var err error
var inc int
codec := Codec[T]{}
for _, v := range m {
size += 8
for _, vi := range v {
if inc, err = codec.BinarySizeWrapper(vi); err != nil {
panic(err)
}
size += inc
}
}
return
}
// MarshalBinary encodes the object into a binary form on a newly allocated slice of bytes.
func (m *Matrix[T]) MarshalBinary() (p []byte, err error) {
p = make([]byte, m.BinarySize())
_, err = m.Read(p)
return
buf := bytes.NewBuffer([]byte{})
_, err = m.WriteTo(buf)
return buf.Bytes(), nil
}
// Read encodes the object into a binary form on a preallocated slice of bytes
// and returns the number of bytes written.
func (m Matrix[T]) Read(b []byte) (n int, err error) {
binary.LittleEndian.PutUint64(b[n:], uint64(len(m)))
n += 8
codec := Codec[T]{}
var inc int
for _, v := range m {
binary.LittleEndian.PutUint64(b[n:], uint64(len(v)))
n += 8
for _, vi := range v {
if inc, err = codec.ReadWrapper(b[n:], vi); err != nil {
return n + inc, err
}
n += inc
}
}
// UnmarshalBinary decodes a slice of bytes generated by
// MarshalBinary or WriteTo on the object.
func (m *Matrix[T]) UnmarshalBinary(p []byte) (err error) {
_, err = m.ReadFrom(bytes.NewBuffer(p))
return
}
@@ -140,55 +97,6 @@ func (m Matrix[T]) WriteTo(w io.Writer) (int64, error) {
}
}
// UnmarshalBinary decodes a slice of bytes generated by MarshalBinary,
// WriteTo or Read on the object.
func (m *Matrix[T]) UnmarshalBinary(p []byte) (err error) {
_, err = m.Write(p)
return
}
// Write decodes a slice of bytes generated by MarshalBinary, WriteTo or
// Read on the object and returns the number of bytes read.
func (m *Matrix[T]) Write(p []byte) (n int, err error) {
size := int(binary.LittleEndian.Uint64(p[n:]))
n += 8
if len(*m) != size {
*m = make([][]*T, size)
}
mi := *m
codec := Codec[T]{}
var inc int
for i := range mi {
size := int(binary.LittleEndian.Uint64(p[n:]))
n += 8
if len(mi[i]) != size {
mi[i] = make([]*T, size)
}
for j := range mi[i] {
if mi[i][j] == nil {
mi[i][j] = new(T)
}
if inc, err = codec.WriteWrapper(p[n:], mi[i][j]); err != nil {
return n + inc, err
}
n += inc
}
}
return
}
// ReadFrom reads on the object from an io.Writer.
// To ensure optimal efficiency and minimal allocations, the user is encouraged
// to provide a struct implementing the interface buffer.Reader, which defines
@@ -249,3 +157,96 @@ func (m *Matrix[T]) ReadFrom(r io.Reader) (int64, error) {
return m.ReadFrom(bufio.NewReader(r))
}
}
// BinarySize returns the size in bytes of the object
// when encoded using Encode.
func (m Matrix[T]) BinarySize() (size int) {
size += 8
var err error
var inc int
codec := Codec[T]{}
for _, v := range m {
size += 8
for _, vi := range v {
if inc, err = codec.BinarySizeWrapper(vi); err != nil {
panic(err)
}
size += inc
}
}
return
}
// Encode encodes the object into a binary form on a preallocated slice of bytes
// and returns the number of bytes written.
func (m Matrix[T]) Encode(b []byte) (n int, err error) {
binary.LittleEndian.PutUint64(b[n:], uint64(len(m)))
n += 8
codec := Codec[T]{}
var inc int
for _, v := range m {
binary.LittleEndian.PutUint64(b[n:], uint64(len(v)))
n += 8
for _, vi := range v {
if inc, err = codec.EncodeWrapper(b[n:], vi); err != nil {
return n + inc, err
}
n += inc
}
}
return
}
// Decode decodes a slice of bytes generated by Encode
// on the object and returns the number of bytes read.
func (m *Matrix[T]) Decode(p []byte) (n int, err error) {
size := int(binary.LittleEndian.Uint64(p[n:]))
n += 8
if len(*m) != size {
*m = make([][]*T, size)
}
mi := *m
codec := Codec[T]{}
var inc int
for i := range mi {
size := int(binary.LittleEndian.Uint64(p[n:]))
n += 8
if len(mi[i]) != size {
mi[i] = make([]*T, size)
}
for j := range mi[i] {
if mi[i][j] == nil {
mi[i][j] = new(T)
}
if inc, err = codec.DecodeWrapper(p[n:], mi[i][j]); err != nil {
return n + inc, err
}
n += inc
}
}
return
}

View File

@@ -2,6 +2,7 @@ package structs
import (
"bufio"
"bytes"
"fmt"
"io"
@@ -29,53 +30,17 @@ func (v Vector[T]) CopyNew() *Vector[T] {
return &vcpy
}
// BinarySize returns the size in bytes that the object once marshalled into a binary form.
func (v Vector[T]) BinarySize() (size int) {
var err error
var inc int
codec := Codec[T]{}
size += 8
for _, vi := range v {
if inc, err = codec.BinarySizeWrapper(vi); err != nil {
panic(err)
}
size += inc
}
return
}
// MarshalBinary encodes the object into a binary form on a newly allocated slice of bytes.
func (v *Vector[T]) MarshalBinary() (p []byte, err error) {
p = make([]byte, v.BinarySize())
_, err = v.Read(p)
return
buf := bytes.NewBuffer([]byte{})
_, err = v.WriteTo(buf)
return buf.Bytes(), nil
}
// Read encodes the object into a binary form on a preallocated slice of bytes
// and returns the number of bytes written.
func (v *Vector[T]) Read(b []byte) (n int, err error) {
vi := *v
binary.LittleEndian.PutUint64(b[n:], uint64(len(vi)))
n += 8
codec := Codec[T]{}
var inc int
for i := range vi {
if inc, err = codec.ReadWrapper(b[n:], vi[i]); err != nil {
return n + inc, err
}
n += inc
}
// UnmarshalBinary decodes a slice of bytes generated by
// MarshalBinary or WriteTo on the object.
func (v *Vector[T]) UnmarshalBinary(p []byte) (err error) {
_, err = v.ReadFrom(bytes.NewBuffer(p))
return
}
@@ -120,45 +85,6 @@ func (v *Vector[T]) WriteTo(w io.Writer) (int64, error) {
}
}
// UnmarshalBinary decodes a slice of bytes generated by MarshalBinary,
// WriteTo or Read on the object.
func (v *Vector[T]) UnmarshalBinary(p []byte) (err error) {
_, err = v.Write(p)
return
}
// Write decodes a slice of bytes generated by MarshalBinary, WriteTo or
// Read on the object and returns the number of bytes read.
func (v *Vector[T]) Write(p []byte) (n int, err error) {
size := int(binary.LittleEndian.Uint64(p[n:]))
n += 8
if len(*v) != size {
*v = make([]*T, size)
}
vi := *v
codec := Codec[T]{}
var inc int
for i := range vi {
if vi[i] == nil {
vi[i] = new(T)
}
if inc, err = codec.WriteWrapper(p[n:], vi[i]); err != nil {
return n + inc, err
}
n += inc
}
return
}
// ReadFrom reads on the object from an io.Writer.
// To ensure optimal efficiency and minimal allocations, the user is encouraged
// to provide a struct implementing the interface buffer.Reader, which defines
@@ -205,3 +131,79 @@ func (v *Vector[T]) ReadFrom(r io.Reader) (int64, error) {
return v.ReadFrom(bufio.NewReader(r))
}
}
// BinarySize returns the size in bytes of the object
// when encoded using Encode.
func (v Vector[T]) BinarySize() (size int) {
var err error
var inc int
codec := Codec[T]{}
size += 8
for _, vi := range v {
if inc, err = codec.BinarySizeWrapper(vi); err != nil {
panic(err)
}
size += inc
}
return
}
// Encode encodes the object into a binary form on a preallocated slice of bytes
// and returns the number of bytes written.
func (v *Vector[T]) Encode(b []byte) (n int, err error) {
vi := *v
binary.LittleEndian.PutUint64(b[n:], uint64(len(vi)))
n += 8
codec := Codec[T]{}
var inc int
for i := range vi {
if inc, err = codec.EncodeWrapper(b[n:], vi[i]); err != nil {
return n + inc, err
}
n += inc
}
return
}
// Decode decodes a slice of bytes generated by Encode
// on the object and returns the number of bytes read.
func (v *Vector[T]) Decode(p []byte) (n int, err error) {
size := int(binary.LittleEndian.Uint64(p[n:]))
n += 8
if len(*v) != size {
*v = make([]*T, size)
}
vi := *v
codec := Codec[T]{}
var inc int
for i := range vi {
if vi[i] == nil {
vi[i] = new(T)
}
if inc, err = codec.DecodeWrapper(p[n:], vi[i]); err != nil {
return n + inc, err
}
n += inc
}
return
}