github.com/cloudflare/circl@v1.5.0/oprf/server.go (about)

     1  package oprf
     2  
     3  import (
     4  	"crypto/rand"
     5  	"crypto/subtle"
     6  
     7  	"github.com/cloudflare/circl/group"
     8  	"github.com/cloudflare/circl/zk/dleq"
     9  )
    10  
    11  type server struct {
    12  	params
    13  	privateKey *PrivateKey
    14  }
    15  
    16  type Server struct{ server }
    17  
    18  type VerifiableServer struct{ server }
    19  
    20  type PartialObliviousServer struct{ server }
    21  
    22  func (s server) PublicKey() *PublicKey { return s.privateKey.Public() }
    23  
    24  func (s server) evaluate(elements []Blinded, secret Blind) []Evaluated {
    25  	evaluations := make([]Evaluated, len(elements))
    26  	for i := range elements {
    27  		evaluations[i] = s.params.group.NewElement().Mul(elements[i], secret)
    28  	}
    29  
    30  	return evaluations
    31  }
    32  
    33  func (s Server) Evaluate(req *EvaluationRequest) (*Evaluation, error) {
    34  	evaluations := s.server.evaluate(req.Elements, s.privateKey.k)
    35  
    36  	return &Evaluation{evaluations, nil}, nil
    37  }
    38  
    39  func (s VerifiableServer) Evaluate(req *EvaluationRequest) (*Evaluation, error) {
    40  	evaluations := s.server.evaluate(req.Elements, s.privateKey.k)
    41  
    42  	proof, err := dleq.Prover{Params: s.getDLEQParams()}.ProveBatch(
    43  		s.privateKey.k,
    44  		s.params.group.Generator(),
    45  		s.PublicKey().e,
    46  		req.Elements,
    47  		evaluations,
    48  		rand.Reader,
    49  	)
    50  	if err != nil {
    51  		return nil, err
    52  	}
    53  
    54  	return &Evaluation{evaluations, proof}, nil
    55  }
    56  
    57  func (s PartialObliviousServer) Evaluate(req *EvaluationRequest, info []byte) (*Evaluation, error) {
    58  	keyProof, evalSecret, err := s.secretFromInfo(info)
    59  	if err != nil {
    60  		return nil, err
    61  	}
    62  
    63  	evaluations := s.server.evaluate(req.Elements, evalSecret)
    64  
    65  	proof, err := dleq.Prover{Params: s.getDLEQParams()}.ProveBatch(
    66  		keyProof,
    67  		s.params.group.Generator(),
    68  		s.params.group.NewElement().MulGen(keyProof),
    69  		evaluations,
    70  		req.Elements,
    71  		rand.Reader,
    72  	)
    73  	if err != nil {
    74  		return nil, err
    75  	}
    76  
    77  	return &Evaluation{evaluations, proof}, nil
    78  }
    79  
    80  func (s server) secretFromInfo(info []byte) (t, tInv group.Scalar, err error) {
    81  	m, err := s.params.scalarFromInfo(info)
    82  	if err != nil {
    83  		return nil, nil, err
    84  	}
    85  	t = s.params.group.NewScalar().Add(m, s.privateKey.k)
    86  
    87  	if zero := s.params.group.NewScalar(); t.IsEqual(zero) {
    88  		return nil, nil, ErrInverseZero
    89  	}
    90  	tInv = s.params.group.NewScalar().Inv(t)
    91  
    92  	return t, tInv, nil
    93  }
    94  
    95  func (s server) fullEvaluate(input, info []byte) ([]byte, error) {
    96  	evalSecret := s.privateKey.k
    97  	if s.params.m == PartialObliviousMode {
    98  		var err error
    99  		_, evalSecret, err = s.secretFromInfo(info)
   100  		if err != nil {
   101  			return nil, err
   102  		}
   103  	}
   104  
   105  	element := s.params.group.HashToElement(input, s.params.getDST(hashToGroupDST))
   106  	evaluation := s.params.group.NewElement().Mul(element, evalSecret)
   107  	serEval, err := evaluation.MarshalBinaryCompress()
   108  	if err != nil {
   109  		return nil, err
   110  	}
   111  
   112  	return s.finalizeHash(s.params.hash.New(), input, info, serEval), nil
   113  }
   114  
   115  func (s Server) FullEvaluate(input []byte) (output []byte, err error) {
   116  	return s.fullEvaluate(input, nil)
   117  }
   118  
   119  func (s VerifiableServer) FullEvaluate(input []byte) (output []byte, err error) {
   120  	return s.fullEvaluate(input, nil)
   121  }
   122  
   123  func (s PartialObliviousServer) FullEvaluate(input, info []byte) (output []byte, err error) {
   124  	return s.fullEvaluate(input, info)
   125  }
   126  
   127  func (s server) verifyFinalize(input, info, expectedOutput []byte) bool {
   128  	gotOutput, err := s.fullEvaluate(input, info)
   129  	if err != nil {
   130  		return false
   131  	}
   132  
   133  	return subtle.ConstantTimeCompare(gotOutput, expectedOutput) == 1
   134  }
   135  
   136  func (s Server) VerifyFinalize(input, expectedOutput []byte) bool {
   137  	return s.verifyFinalize(input, nil, expectedOutput)
   138  }
   139  
   140  func (s VerifiableServer) VerifyFinalize(input, expectedOutput []byte) bool {
   141  	return s.verifyFinalize(input, nil, expectedOutput)
   142  }
   143  
   144  func (s PartialObliviousServer) VerifyFinalize(input, info, expectedOutput []byte) bool {
   145  	return s.verifyFinalize(input, info, expectedOutput)
   146  }