...

Source file src/github.com/cloudflare/circl/group/ristretto255.go

Documentation: github.com/cloudflare/circl/group

     1  package group
     2  
     3  import (
     4  	"crypto"
     5  	_ "crypto/sha512"
     6  	"fmt"
     7  	"io"
     8  	"math/big"
     9  
    10  	r255 "github.com/bwesterb/go-ristretto"
    11  	"github.com/cloudflare/circl/expander"
    12  	"github.com/cloudflare/circl/internal/conv"
    13  )
    14  
    15  // Ristretto255 is a quotient group generated from the edwards25519 curve.
    16  var Ristretto255 Group = ristrettoGroup{}
    17  
    18  type ristrettoGroup struct{}
    19  
    20  func (g ristrettoGroup) String() string {
    21  	return "ristretto255"
    22  }
    23  
    24  func (g ristrettoGroup) Params() *Params {
    25  	return &Params{32, 32, 32}
    26  }
    27  
    28  type ristrettoElement struct {
    29  	p r255.Point
    30  }
    31  
    32  type ristrettoScalar struct {
    33  	s r255.Scalar
    34  }
    35  
    36  func (g ristrettoGroup) NewElement() Element {
    37  	return g.Identity()
    38  }
    39  
    40  func (g ristrettoGroup) NewScalar() Scalar {
    41  	return &ristrettoScalar{
    42  		s: r255.Scalar{},
    43  	}
    44  }
    45  
    46  func (g ristrettoGroup) Identity() Element {
    47  	var zero r255.Point
    48  	zero.SetZero()
    49  	return &ristrettoElement{
    50  		p: zero,
    51  	}
    52  }
    53  
    54  func (g ristrettoGroup) Generator() Element {
    55  	var base r255.Point
    56  	base.SetBase()
    57  	return &ristrettoElement{
    58  		p: base,
    59  	}
    60  }
    61  
    62  func (g ristrettoGroup) Order() Scalar {
    63  	q := r255.Scalar{
    64  		0x5cf5d3ed, 0x5812631a, 0xa2f79cd6, 0x14def9de,
    65  		0x00000000, 0x00000000, 0x00000000, 0x10000000,
    66  	}
    67  	return &ristrettoScalar{
    68  		s: q,
    69  	}
    70  }
    71  
    72  func (g ristrettoGroup) RandomElement(r io.Reader) Element {
    73  	var x r255.Point
    74  	x.Rand()
    75  	return &ristrettoElement{
    76  		p: x,
    77  	}
    78  }
    79  
    80  func (g ristrettoGroup) RandomScalar(io.Reader) Scalar {
    81  	var x r255.Scalar
    82  	x.Rand()
    83  	return &ristrettoScalar{
    84  		s: x,
    85  	}
    86  }
    87  
    88  func (g ristrettoGroup) RandomNonZeroScalar(io.Reader) Scalar {
    89  	var s r255.Scalar
    90  	for {
    91  		s.Rand()
    92  		if s.IsNonZeroI() == 1 {
    93  			return &ristrettoScalar{s}
    94  		}
    95  	}
    96  }
    97  
    98  func (g ristrettoGroup) HashToElementNonUniform(b, dst []byte) Element {
    99  	return g.HashToElement(b, dst)
   100  }
   101  
   102  func (g ristrettoGroup) HashToElement(msg, dst []byte) Element {
   103  	// Compliant with draft-irtf-cfrg-hash-to-curve.
   104  	// Appendix B - Hashing to ristretto255
   105  	// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-14#appendix-B
   106  	// SuiteID: ristretto255_XMD:SHA-512_R255MAP_RO_
   107  	var buf [32]byte
   108  	xmd := expander.NewExpanderMD(crypto.SHA512, dst)
   109  	uniformBytes := xmd.Expand(msg, 64)
   110  	copy(buf[:], uniformBytes[:32])
   111  	p0 := new(r255.Point).SetElligator(&buf)
   112  	copy(buf[:], uniformBytes[32:])
   113  	p1 := new(r255.Point).SetElligator(&buf)
   114  	p0.Add(p0, p1)
   115  
   116  	return &ristrettoElement{*p0}
   117  }
   118  
   119  func (g ristrettoGroup) HashToScalar(msg, dst []byte) Scalar {
   120  	// Adapted to be compliant with draft-irtf-cfrg-voprf
   121  	// Section 4.1.1 - OPRF(ristretto255, SHA-512)
   122  	// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-voprf-09#section-4.1.1
   123  	var uniformBytes [64]byte
   124  	xmd := expander.NewExpanderMD(crypto.SHA512, dst)
   125  	copy(uniformBytes[:], xmd.Expand(msg, 64))
   126  	s := g.NewScalar()
   127  	s.(*ristrettoScalar).s.SetReduced(&uniformBytes)
   128  	return s
   129  }
   130  
   131  func (e *ristrettoElement) Group() Group { return Ristretto255 }
   132  
   133  func (e *ristrettoElement) String() string { return fmt.Sprintf("%x", e.p.Bytes()) }
   134  
   135  func (e *ristrettoElement) IsIdentity() bool {
   136  	var zero r255.Point
   137  	zero.SetZero()
   138  	return e.p.Equals(&zero)
   139  }
   140  
   141  func (e *ristrettoElement) IsEqual(x Element) bool {
   142  	return e.p.Equals(&x.(*ristrettoElement).p)
   143  }
   144  
   145  func (e *ristrettoElement) Set(x Element) Element {
   146  	e.p.Set(&x.(*ristrettoElement).p)
   147  	return e
   148  }
   149  
   150  func (e *ristrettoElement) Copy() Element {
   151  	return &ristrettoElement{*new(r255.Point).Set(&e.p)}
   152  }
   153  
   154  func (e *ristrettoElement) CMov(v int, x Element) Element {
   155  	if !(v == 0 || v == 1) {
   156  		panic(ErrSelector)
   157  	}
   158  	e.p.ConditionalSet(&x.(*ristrettoElement).p, int32(v))
   159  	return e
   160  }
   161  
   162  func (e *ristrettoElement) CSelect(v int, x Element, y Element) Element {
   163  	if !(v == 0 || v == 1) {
   164  		panic(ErrSelector)
   165  	}
   166  	e.p.ConditionalSet(&x.(*ristrettoElement).p, int32(v))
   167  	e.p.ConditionalSet(&y.(*ristrettoElement).p, int32(1-v))
   168  	return e
   169  }
   170  
   171  func (e *ristrettoElement) Add(x Element, y Element) Element {
   172  	e.p.Add(&x.(*ristrettoElement).p, &y.(*ristrettoElement).p)
   173  	return e
   174  }
   175  
   176  func (e *ristrettoElement) Dbl(x Element) Element {
   177  	return e.Add(x, x)
   178  }
   179  
   180  func (e *ristrettoElement) Neg(x Element) Element {
   181  	e.p.Neg(&x.(*ristrettoElement).p)
   182  	return e
   183  }
   184  
   185  func (e *ristrettoElement) Mul(x Element, y Scalar) Element {
   186  	e.p.ScalarMult(&x.(*ristrettoElement).p, &y.(*ristrettoScalar).s)
   187  	return e
   188  }
   189  
   190  func (e *ristrettoElement) MulGen(x Scalar) Element {
   191  	e.p.ScalarMultBase(&x.(*ristrettoScalar).s)
   192  	return e
   193  }
   194  
   195  func (e *ristrettoElement) MarshalBinaryCompress() ([]byte, error) {
   196  	return e.p.MarshalBinary()
   197  }
   198  
   199  func (e *ristrettoElement) MarshalBinary() ([]byte, error) {
   200  	return e.p.MarshalBinary()
   201  }
   202  
   203  func (e *ristrettoElement) UnmarshalBinary(data []byte) error {
   204  	return e.p.UnmarshalBinary(data)
   205  }
   206  
   207  func (s *ristrettoScalar) Group() Group                { return Ristretto255 }
   208  func (s *ristrettoScalar) String() string              { return conv.BytesLe2Hex(s.s.Bytes()) }
   209  func (s *ristrettoScalar) SetUint64(n uint64) Scalar   { s.s.SetUint64(n); return s }
   210  func (s *ristrettoScalar) SetBigInt(x *big.Int) Scalar { s.s.SetBigInt(x); return s }
   211  func (s *ristrettoScalar) IsZero() bool                { return s.s.IsNonZeroI() == 0 }
   212  func (s *ristrettoScalar) IsEqual(x Scalar) bool {
   213  	return s.s.Equals(&x.(*ristrettoScalar).s)
   214  }
   215  
   216  func (s *ristrettoScalar) Set(x Scalar) Scalar {
   217  	s.s.Set(&x.(*ristrettoScalar).s)
   218  	return s
   219  }
   220  
   221  func (s *ristrettoScalar) Copy() Scalar {
   222  	return &ristrettoScalar{*new(r255.Scalar).Set(&s.s)}
   223  }
   224  
   225  func (s *ristrettoScalar) CMov(v int, x Scalar) Scalar {
   226  	if !(v == 0 || v == 1) {
   227  		panic(ErrSelector)
   228  	}
   229  	s.s.ConditionalSet(&x.(*ristrettoScalar).s, int32(v))
   230  	return s
   231  }
   232  
   233  func (s *ristrettoScalar) CSelect(v int, x Scalar, y Scalar) Scalar {
   234  	if !(v == 0 || v == 1) {
   235  		panic(ErrSelector)
   236  	}
   237  	s.s.ConditionalSet(&x.(*ristrettoScalar).s, int32(v))
   238  	s.s.ConditionalSet(&y.(*ristrettoScalar).s, int32(1-v))
   239  	return s
   240  }
   241  
   242  func (s *ristrettoScalar) Add(x Scalar, y Scalar) Scalar {
   243  	s.s.Add(&x.(*ristrettoScalar).s, &y.(*ristrettoScalar).s)
   244  	return s
   245  }
   246  
   247  func (s *ristrettoScalar) Sub(x Scalar, y Scalar) Scalar {
   248  	s.s.Sub(&x.(*ristrettoScalar).s, &y.(*ristrettoScalar).s)
   249  	return s
   250  }
   251  
   252  func (s *ristrettoScalar) Mul(x Scalar, y Scalar) Scalar {
   253  	s.s.Mul(&x.(*ristrettoScalar).s, &y.(*ristrettoScalar).s)
   254  	return s
   255  }
   256  
   257  func (s *ristrettoScalar) Neg(x Scalar) Scalar {
   258  	s.s.Neg(&x.(*ristrettoScalar).s)
   259  	return s
   260  }
   261  
   262  func (s *ristrettoScalar) Inv(x Scalar) Scalar {
   263  	s.s.Inverse(&x.(*ristrettoScalar).s)
   264  	return s
   265  }
   266  
   267  func (s *ristrettoScalar) MarshalBinary() ([]byte, error) {
   268  	return s.s.MarshalBinary()
   269  }
   270  
   271  func (s *ristrettoScalar) UnmarshalBinary(data []byte) error {
   272  	return s.s.UnmarshalBinary(data)
   273  }
   274  

View as plain text