Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds Prio3 a set of verifiable distributed aggregation functions. #522

Merged
merged 15 commits into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions internal/conv/conv.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"fmt"
"math/big"
"strings"

"golang.org/x/crypto/cryptobyte"
)

// BytesLe2Hex returns an hexadecimal string of a number stored in a
Expand Down Expand Up @@ -138,3 +140,34 @@ func BigInt2Uint64Le(z []uint64, x *big.Int) {
z[i] = 0
}
}

// MarshalBinary encodes a value into a byte array in a format readable by UnmarshalBinary.
func MarshalBinary(v cryptobyte.MarshalingValue) ([]byte, error) {
const DefaultSize = 32
b := cryptobyte.NewBuilder(make([]byte, 0, DefaultSize))
b.AddValue(v)
return b.Bytes()
}

// MarshalBinaryLen encodes a value into an array of n bytes in a format readable by UnmarshalBinary.
func MarshalBinaryLen(v cryptobyte.MarshalingValue, length uint) ([]byte, error) {
b := cryptobyte.NewFixedBuilder(make([]byte, 0, length))
b.AddValue(v)
return b.Bytes()
}

// A UnmarshalingValue decodes itself from a cryptobyte.String and advances the pointer.
// It reports whether the read was successful.
type UnmarshalingValue interface {
Unmarshal(*cryptobyte.String) bool
}

// UnmarshalBinary recovers a value from a byte array.
// It returns an error if the read was unsuccessful.
func UnmarshalBinary(v UnmarshalingValue, data []byte) (err error) {
s := cryptobyte.String(data)
if data == nil || !v.Unmarshal(&s) || !s.Empty() {
err = fmt.Errorf("cannot read %T from input string", v)
}
return
}
16 changes: 16 additions & 0 deletions math/integer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package math

import "math/bits"

armfazh marked this conversation as resolved.
Show resolved Hide resolved
// NextPow2 finds the next power of two (N=2^k, k>=0) greater than n.
// If n is already a power of two, then this function returns n, and log2(n).
func NextPow2(n uint) (N uint, k uint) {
if bits.OnesCount(n) == 1 {
k = uint(bits.TrailingZeros(n))
N = n
} else {
k = uint(bits.Len(n))
N = uint(1) << k
}
return
}
5 changes: 5 additions & 0 deletions vdaf/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Package vdaf provides verifiable distributed aggregation functions.
armfazh marked this conversation as resolved.
Show resolved Hide resolved
//
// This package supports Prio3 as specified in [v13].
// [v13]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vdaf-13
package vdaf
140 changes: 140 additions & 0 deletions vdaf/prio3/arith/arith.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
//go:generate go run gen.go

// Package arith provides arithmetic operations over prime fields, vectors,
// and polynomials.
package arith

import (
"encoding"
"io"

"github.com/cloudflare/circl/internal/conv"
"github.com/cloudflare/circl/internal/sha3"
"golang.org/x/crypto/cryptobyte"
)

// Elt is any type that stores a prime field element.
type Elt any

// Fp lists the functionality that a prime field element must have denoting
// methods with a pointer receiver.
armfazh marked this conversation as resolved.
Show resolved Hide resolved
// This interface considers the modulus is an NTT-friendly prime, i.e.,
// there exists a multiplicative subgroup formed by the N-th roots of unity.
type Fp[E Elt] interface {
*E
// Size returns the number of bytes to encode a field element.
Size() uint
// Returns true if the element is the neutral additive element.
IsZero() bool
// Returns true if the element is the neutral multiplicative element.
IsOne() bool
// Returns true if the element is equal to x.
IsEqual(x *E) bool
// Set the element to the neutral multiplicative element.
SetOne()
// Set the element to x if x < Order().
SetUint64(uint64) error
// Returns the integer representative of the element if x < 2^64.
GetUint64() (x uint64, err error)
// Set the element to the principal root of unity of order 2^n.
SetRootOfUnityTwoN(n uint)
// AddAssing calculates z = z + x.
AddAssign(x *E)
// SubAssign calculates z = z - x.
SubAssign(x *E)
// MulAssign calculates z = z * x.
MulAssign(x *E)
// Add calculates z = x + y.
Add(x, y *E)
// Sub calculates z = x - y.
Sub(x, y *E)
// Mul calculates z = x * y.
Mul(x, y *E)
// Sqr calculates z = x * x.
Sqr(x *E)
// Inv calculates z = 1 / x.
Inv(x *E)
// InvUint64 calculates z = 1 / x.
InvUint64(x uint64)
// InvTwoN calculates z = 1 / (2^n).
InvTwoN(n uint)
// Random samples an element from an io.Reader.
Random(io.Reader) error
// RandomSHA3 samples an element from a SHA3 state.
RandomSHA3(*sha3.State) error
armfazh marked this conversation as resolved.
Show resolved Hide resolved
// Encodes an element to bytes.
encoding.BinaryMarshaler
// Decodes an element from bytes.
encoding.BinaryUnmarshaler
// Encodes an element using a cryptobyte.Builder.
cryptobyte.MarshalingValue
// Decodes an element from a cryptobyte.String.
conv.UnmarshalingValue
cjpatton marked this conversation as resolved.
Show resolved Hide resolved
}

// NewVec returns a vector of length n with all elements set to zero.
func NewVec[V Vec[V, E], E Elt](n uint) V { return make(V, n) }

// Vec lists the funtionality of a vector of field elements.
type Vec[Vec ~[]E, E Elt] interface {
~[]E
// Size returns the number of bytes to encode the vector.
Size() uint
// AddAssing calculates z = z + x.
AddAssign(x Vec)
// SubAssign calculates z = z - x.
SubAssign(x Vec)
// ScalarMul calculates z[i] = z[i] * x.
ScalarMul(x *E)
// DotProduct calculates z[i] = z[i] * x[i].
DotProduct(x Vec) E
// NTT calculates the number theoretic transform of the vector.
NTT(Vec)
// InvNTT calculates the inverse number theoretic transform on values.
InvNTT(Vec)
// SplitBits sets the vector of elements corresponding to the bits of n.
armfazh marked this conversation as resolved.
Show resolved Hide resolved
// The receiving vector sets v[i] = SetUint64(n(i)), where n(i) is the i-th
// bit of n, and len(v) >= log2(n).
SplitBits(n uint64) error
// JoinBits calculates the element sum( 2^i * z[i] ).
JoinBits() E
// Random samples a vector from an io.Reader.
Random(io.Reader) error
// RandomSHA3 samples a vector from a SHA3 state.
RandomSHA3(*sha3.State) error
// RandomSHA3Bytes reads a vector from a SHA3 state copying the bytes read.
RandomSHA3Bytes([]byte, *sha3.State) error
// Encodes a vector to bytes.
encoding.BinaryMarshaler
// Decodes a vector from bytes.
encoding.BinaryUnmarshaler
// Encodes a vector using a cryptobyte.Builder.
cryptobyte.MarshalingValue
// Decodes a vector from a cryptobyte.String.
conv.UnmarshalingValue
}

// NewPoly returns a polynomial of the given degree with all coefficients set
// to zero.
func NewPoly[P Poly[P, E], E Elt](degree uint) P { return make(P, degree+1) }

// Poly lists the funtionality of polynomials with coefficients in a field.
type Poly[Poly ~[]E, E Elt] interface {
~[]E
// AddAssing calculates z = z + x.
AddAssign(Poly)
// SubAssign calculates z = z - x.
SubAssign(Poly)
// Mul calculates z = x * y.
Mul(x, y Poly)
// Sqr calculates z = x * x.
Sqr(Poly)
// Evaluate calculates the polynomial evaluation p(x).
Evaluate(x *E) E
// Strip removes the higher-degree zero terms.
Strip() Poly
// Interpolate a polynomial passing through the points (x[i], y[i]), where
// x are the powers of an N-th root of unity, y are the values, and
// N = len(y) must be a power of two.
Interpolate(y []E)
}
Loading
Loading