Skip to content

Commit

Permalink
Improves documentation of group interface.
Browse files Browse the repository at this point in the history
  • Loading branch information
armfazh committed Aug 1, 2022
1 parent 10a0004 commit dbf8547
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 39 deletions.
122 changes: 93 additions & 29 deletions group/group.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,67 +7,131 @@ import (
"io"
)

// Params stores the size in bytes of elements and scalars.
type Params struct {
ElementLength uint // Length in bytes of an element.
CompressedElementLength uint // Length in bytes of a compressed element.
ScalarLength uint // Length in bytes of a scalar.
}

// Group represents a prime-order group based on elliptic curves.
// Group represents an additive prime-order group based on elliptic curves.
type Group interface {
Params() *Params // Params returns parameters for the group
// Creates an element of the group set to the identity of the group.
NewElement() Element
// Creates a scalar of the group set to zero.
NewScalar() Scalar
// Creates an element of the group set to the identity of the group.
Identity() Element
// Creates an element of the group set to the generator of the group.
Generator() Element
// Returns a scalar set to the group order.
Order() Scalar
RandomElement(io.Reader) Element
RandomScalar(io.Reader) Scalar
// RandomElement creates an element chosen at random (using randomness
// from rnd) from the set of group elements. Use crypto/rand.Reader as
// a cryptographically secure random number generator
RandomElement(rnd io.Reader) Element
// RandomScalar creates a scalar chosen at random (using randomness
// from rnd) from the set of group scalars. Use crypto/rand.Reader as
// a cryptographically secure random number generator
RandomScalar(rnd io.Reader) Scalar
// RandomNonZeroScalar creates a scalar chosen at random (using randomness
// from rnd) from the set of group scalars. Use crypto/rand.Reader as
// a cryptographically secure random number generator. It is guaranteed
// the scalar is not zero.
RandomNonZeroScalar(io.Reader) Scalar
HashToElement(data, dst []byte) Element
HashToElementNonUniform(b, dst []byte) Element
HashToScalar(data, dst []byte) Scalar
// HashToElement hashes a message (msg) using a domain separation string
// (dst) producing a group element with uniform distribution.
HashToElement(msg, dst []byte) Element
// HashToElementNonUniform hashes a message (msg) using a domain separation
// string (dst) producing a group element with nonuniform distribution.
HashToElementNonUniform(msg, dst []byte) Element
// HashToScalar hashes a message (msg) using a domain separation string
// (dst) producing a group scalar with uniform distribution.
HashToScalar(msg, dst []byte) Scalar
}

// Element represents an abstract element of a prime-order group.
// Element represents an element of a prime-order group.
type Element interface {
// Returns the group that the element belongs to.
Group() Group
Set(Element) Element
// Set the receiver to x, and returns the receiver.
Set(x Element) Element
// Copy returns a new element equal to the receiver.
Copy() Element
// IsIdentity returns true if the receiver is the identity element of the
// group.
IsIdentity() bool
IsEqual(Element) bool
CMov(int, Element) Element
CSelect(int, Element, Element) Element
Add(Element, Element) Element
Dbl(Element) Element
Neg(Element) Element
Mul(Element, Scalar) Element
MulGen(Scalar) Element
// IsEqual returns true if the receiver is equal to x.
IsEqual(x Element) bool
// CMov sets the receiver to x if b=1; the receiver is unmodified if b=0;
// otherwise panics if b is not 0 or 1. In all the cases, it returns the
// receiver.
CMov(b int, x Element) Element
// CSelect sets the receiver to x if b=1; sets the receiver to y if b=0;
// otherwise panics if b is not 0 or 1. In all the cases, it returns the
// receiver.
CSelect(b int, x, y Element) Element
// Add sets the receiver to x + y, and returns the receiver.
Add(x, y Element) Element
// Dbl sets the receiver to 2 * x, and returns the receiver.
Dbl(x Element) Element
// Neg sets the receiver to -x, and returns the receiver.
Neg(x Element) Element
// Mul sets the receiver to s * x, and returns the receiver.
Mul(x Element, s Scalar) Element
// MulGen sets the receiver to s * Generator(), and returns the receiver.
MulGen(s Scalar) Element
// BinaryMarshaler returns a byte representation of the element.
encoding.BinaryMarshaler
// BinaryUnmarshaler recovers an element from a byte representation
// produced either by encoding.BinaryMarshaler or MarshalBinaryCompress.
encoding.BinaryUnmarshaler
// MarshalBinaryCompress returns a byte representation of an elment in a
// compact form whenever the group supports it; otherwise, returns the
// same byte representation produced by encoding.BinaryMarshaler.
MarshalBinaryCompress() ([]byte, error)
}

// Scalar represents an integer scalar.
// Scalar represents a scalar of a prime-order group.
type Scalar interface {
// Returns the group that the scalar belongs to.
Group() Group
Set(Scalar) Scalar
// Set the receiver to x, and returns the receiver.
Set(x Scalar) Scalar
// Copy returns a new scalar equal to the receiver.
Copy() Scalar
IsEqual(Scalar) bool
SetUint64(uint64)
CMov(int, Scalar) Scalar
CSelect(int, Scalar, Scalar) Scalar
Add(Scalar, Scalar) Scalar
Sub(Scalar, Scalar) Scalar
Mul(Scalar, Scalar) Scalar
Neg(Scalar) Scalar
Inv(Scalar) Scalar
// IsEqual returns true if the receiver is equal to x.
IsEqual(x Scalar) bool
// SetUint64 set the receiver to x, and returns the receiver.
SetUint64(x uint64) Scalar
// CMov sets the receiver to x if b=1; the receiver is unmodified if b=0;
// otherwise panics if b is not 0 or 1. In all the cases, it returns the
// receiver.
CMov(b int, x Scalar) Scalar
// CSelect sets the receiver to x if b=1; sets the receiver to y if b=0;
// otherwise panics if b is not 0 or 1. In all the cases, it returns the
// receiver.
CSelect(b int, x, y Scalar) Scalar
// Add sets the receiver to x + y, and returns the receiver.
Add(x, y Scalar) Scalar
// Sub sets the receiver to x - y, and returns the receiver.
Sub(x, y Scalar) Scalar
// Mul sets the receiver to x * y, and returns the receiver.
Mul(x, y Scalar) Scalar
// Neg sets the receiver to -x, and returns the receiver.
Neg(x Scalar) Scalar
// Inv sets the receiver to 1/x, and returns the receiver.
Inv(x Scalar) Scalar
// BinaryMarshaler returns a byte representation of the scalar.
encoding.BinaryMarshaler
// BinaryUnmarshaler recovers a scalar from a byte representation produced
// by encoding.BinaryMarshaler.
encoding.BinaryUnmarshaler
}

var (
ErrType = errors.New("type mismatch")
ErrUnmarshal = errors.New("error unmarshaling")
ErrType = errors.New("group: type mismatch")
ErrUnmarshal = errors.New("group: error unmarshaling")
ErrSelector = errors.New("group: selector must be 0 or 1")
)
6 changes: 3 additions & 3 deletions group/group_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,9 @@ func testCSelect(t *testing.T, testTimes int, g group.Group) {
test.CheckNoErr(t, err, "should fail with dif 0,1")

for i := 0; i < testTimes; i++ {
P := g.RandomElement(rand.Reader)
Q := g.RandomElement(rand.Reader)
R := g.RandomElement(rand.Reader)
P = g.RandomElement(rand.Reader)
Q = g.RandomElement(rand.Reader)
R = g.RandomElement(rand.Reader)

want := R.Copy()
got := P.CSelect(0, Q, R)
Expand Down
8 changes: 4 additions & 4 deletions group/ristretto255.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
"github.com/cloudflare/circl/expander"
)

// Ristretto255 is a quotient group generated from edwards25519 curve.
// Ristretto255 is a quotient group generated from the edwards25519 curve.
var Ristretto255 Group = ristrettoGroup{}

type ristrettoGroup struct{}
Expand Down Expand Up @@ -202,9 +202,9 @@ func (e *ristrettoElement) UnmarshalBinary(data []byte) error {
return e.p.UnmarshalBinary(data)
}

func (s *ristrettoScalar) Group() Group { return Ristretto255 }
func (s *ristrettoScalar) String() string { return fmt.Sprintf("0x%x", s.s.Bytes()) }
func (s *ristrettoScalar) SetUint64(n uint64) { s.s.SetUint64(n) }
func (s *ristrettoScalar) Group() Group { return Ristretto255 }
func (s *ristrettoScalar) String() string { return fmt.Sprintf("0x%x", s.s.Bytes()) }
func (s *ristrettoScalar) SetUint64(n uint64) Scalar { s.s.SetUint64(n); return s }

func (s *ristrettoScalar) IsEqual(x Scalar) bool {
return s.s.Equals(&x.(*ristrettoScalar).s)
Expand Down
6 changes: 3 additions & 3 deletions group/short.go
Original file line number Diff line number Diff line change
Expand Up @@ -271,9 +271,9 @@ type wScl struct {
k []byte
}

func (s *wScl) Group() Group { return s.wG }
func (s *wScl) String() string { return fmt.Sprintf("0x%x", s.k) }
func (s *wScl) SetUint64(n uint64) { s.fromBig(new(big.Int).SetUint64(n)) }
func (s *wScl) Group() Group { return s.wG }
func (s *wScl) String() string { return fmt.Sprintf("0x%x", s.k) }
func (s *wScl) SetUint64(n uint64) Scalar { s.fromBig(new(big.Int).SetUint64(n)); return s }
func (s *wScl) IsEqual(a Scalar) bool {
aa := s.cvtScl(a)
return subtle.ConstantTimeCompare(s.k, aa.k) == 1
Expand Down

0 comments on commit dbf8547

Please sign in to comment.