Documentation
¶
Overview ¶
Package voprf provides abstracted access to Oblivious Pseudorandom Functions (OPRF) and VOPRF Oblivious Pseudorandom Functions (VOPRF) using Elliptic Curves (EC(V)OPRF).
This work in progress implements https://tools.ietf.org/html/draft-irtf-cfrg-voprf
Integrations can use either base or verifiable mode with additive or multiplicative operations.
Example (BaseServer) ¶
package main import ( "encoding/hex" "github.com/bytemare/voprf" ) func main() { // We suppose the client sends this blinded element. blinded, _ := hex.DecodeString("7eaf3d7cbe43d54637274342ce53578b2aba836f297f4f07997a6e1dced1c058") // Set up a new server. A private key is automatically created if none is given. server, err := voprf.Ristretto255Sha512.Server(voprf.OPRF, nil) if err != nil { panic(err) } // The server evaluates the blinded input. evaluation, err := server.Evaluate(blinded, nil) if err != nil { panic(err) } // The server encodes the evaluation, and sends it to the client. _ = evaluation.Serialize() }
Output:
Example (VerifiableClient) ¶
package main import ( "encoding/hex" "github.com/bytemare/voprf" ) func exchangeWithServer(blinded []byte, verifiable bool) []byte { var server *voprf.Server var err error privateKey, _ := hex.DecodeString("8132542d5ed08594e7522b5eac6bee38bab5868996c25a3fd2a7739be1856b04") if verifiable { server, err = voprf.Ristretto255Sha512.Server(voprf.VOPRF, privateKey) if err != nil { panic(err) } } else { server, err = voprf.Ristretto255Sha512.Server(voprf.OPRF, privateKey) if err != nil { panic(err) } } evaluation, err := server.Evaluate(blinded, nil) if err != nil { panic(err) } ev := evaluation.Serialize() return ev } func main() { ciphersuite := voprf.Ristretto255Sha512 input := []byte("input") serverPubKey, _ := hex.DecodeString("066c39841db2ca3c2e83e251e71b619013674149692ca2ab41d1b33a1a4fff38") // Instantiate a new client with the preprocessed values. client, err := ciphersuite.Client(voprf.VOPRF, serverPubKey) if err != nil { panic(err) } // The client blinds the initial input, and sends this to the server. blinded := client.Blind(input, nil) // Exchange with the server is not covered here. The following call is to mock an exchange with a server. ev := exchangeWithServer(blinded, true) // The client needs to decode the evaluation to finalize the process. eval := new(voprf.Evaluation) if err := eval.Deserialize(ev); err != nil { panic(err) } // The client finalizes the protocol execution by reverting the blinding and hashing the protocol transcript. // If proof verification fails, an error is returned. output, err := client.Finalize(eval, nil) if output == nil || err != nil { panic(err) } }
Output:
Example (VerifiableServer) ¶
package main import ( "encoding/hex" "github.com/bytemare/voprf" ) func main() { privateKey, _ := hex.DecodeString("8132542d5ed08594e7522b5eac6bee38bab5868996c25a3fd2a7739be1856b04") // We suppose the client sends this blinded element. blinded, _ := hex.DecodeString("7eaf3d7cbe43d54637274342ce53578b2aba836f297f4f07997a6e1dced1c058") // Set up a new server. server, err := voprf.Ristretto255Sha512.Server(voprf.VOPRF, privateKey) if err != nil { panic(err) } // The server evaluates the blinded input. Proofs are embedded in the evaluation. evaluation, err := server.Evaluate(blinded, nil) if err != nil { panic(err) } // The server encodes the evaluation, and sends it to the client. _ = evaluation.Serialize() }
Output:
Index ¶
- type Client
- func (c *Client) Blind(input, info []byte) []byte
- func (c *Client) BlindBatch(input [][]byte, info []byte) (blinds, blindedElements [][]byte, err error)
- func (c *Client) BlindBatchWithBlinds(blinds, input [][]byte, info []byte) ([][]byte, error)
- func (o Client) DeriveKeyPair(seed, info []byte) (*group.Scalar, *group.Element)
- func (c *Client) Export() *State
- func (c *Client) Finalize(e *Evaluation, info []byte) ([]byte, error)
- func (c *Client) FinalizeBatch(e *Evaluation, info []byte) ([][]byte, error)
- func (o Client) HashToGroup(data []byte) *group.Element
- func (o Client) HashToScalar(data []byte) *group.Scalar
- func (c *Client) SetBlinds(blind []*group.Scalar)
- type Evaluation
- type Identifier
- func (i Identifier) Available() bool
- func (i Identifier) Client(mode Mode, serverPublicKey []byte) (*Client, error)
- func (i Identifier) Group() group.Group
- func (i Identifier) Hash() hash.Hashing
- func (i Identifier) KeyGen() *KeyPair
- func (i Identifier) Server(mode Mode, privateKey []byte) (*Server, error)
- func (i Identifier) String() string
- type KeyPair
- type Mode
- type Server
- func (o Server) DeriveKeyPair(seed, info []byte) (*group.Scalar, *group.Element)
- func (s *Server) Evaluate(blindedElement, info []byte) (*Evaluation, error)
- func (s *Server) EvaluateBatch(blindedElements [][]byte, info []byte) (*Evaluation, error)
- func (s *Server) FullEvaluate(input, info []byte) ([]byte, error)
- func (o Server) HashToGroup(data []byte) *group.Element
- func (o Server) HashToScalar(data []byte) *group.Scalar
- func (s *Server) Identifier() Identifier
- func (s *Server) KeyGen()
- func (s *Server) PrivateKey() []byte
- func (s *Server) PublicKey() []byte
- func (s *Server) SetProofNonce(r []byte)
- func (s *Server) VerifyFinalize(input, info, output []byte) bool
- func (s *Server) VerifyFinalizeBatch(input, output [][]byte, info []byte) bool
- type State
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client represents the Client/Verifier party in a (V)OPRF protocol session, and exposes relevant functions for its execution.
Example ¶
package main import ( "encoding/hex" "github.com/bytemare/voprf" ) func exchangeWithServer(blinded []byte, verifiable bool) []byte { var server *voprf.Server var err error privateKey, _ := hex.DecodeString("8132542d5ed08594e7522b5eac6bee38bab5868996c25a3fd2a7739be1856b04") if verifiable { server, err = voprf.Ristretto255Sha512.Server(voprf.VOPRF, privateKey) if err != nil { panic(err) } } else { server, err = voprf.Ristretto255Sha512.Server(voprf.OPRF, privateKey) if err != nil { panic(err) } } evaluation, err := server.Evaluate(blinded, nil) if err != nil { panic(err) } ev := evaluation.Serialize() return ev } func main() { input := []byte("input") // Set up a new client. Not indicating a server public key indicates we don't use the verifiable mode. client, err := voprf.Ristretto255Sha512.Client(voprf.OPRF, nil) if err != nil { panic(err) } // The client blinds the initial input, and sends this to the server. blinded := client.Blind(input, nil) // Exchange with the server is not covered here. The following call is to mock an exchange with a server. ev := exchangeWithServer(blinded, false) // The client needs to decode the evaluation to finalize the process. eval := new(voprf.Evaluation) if err := eval.Deserialize(ev); err != nil { panic(err) } // The client finalizes the protocol execution by reverting the blinding and hashing the protocol transcript. output, err := client.Finalize(eval, nil) if output == nil || err != nil { panic(err) } }
Output:
func (*Client) Blind ¶
Blind blinds, or masks, the input with a preset or new random blinding element.
func (*Client) BlindBatch ¶
func (c *Client) BlindBatch(input [][]byte, info []byte) (blinds, blindedElements [][]byte, err error)
BlindBatch allows blinding of batched input. If internal blinds are not set, new ones are created. In either case, the blinds are returned, and can safely be ignored if not needed externally. Subsequent calls on unblinding functions will automatically use the internal blinds, unless specified otherwise through unblindBatchWithBlinds().
func (*Client) BlindBatchWithBlinds ¶
BlindBatchWithBlinds enables blinding batches while specifying which blinds to use.
func (Client) DeriveKeyPair ¶
DeriveKeyPair deterministically generates a private and public key pair from input seed.
func (*Client) Export ¶
Export extracts the client's internal values that can be imported in another client for session resumption.
func (*Client) Finalize ¶
func (c *Client) Finalize(e *Evaluation, info []byte) ([]byte, error)
Finalize finalizes the protocol execution by verifying the proof if necessary, unblinding the evaluated element, and hashing the transcript.
func (*Client) FinalizeBatch ¶
func (c *Client) FinalizeBatch(e *Evaluation, info []byte) ([][]byte, error)
FinalizeBatch finalizes the protocol execution by verifying the proof if necessary, unblinding the evaluated elements, and hashing the transcript.
func (Client) HashToGroup ¶
HashToGroup maps the input data to an element of the group.
func (Client) HashToScalar ¶
HashToScalar maps the input data to a scalar.
type Evaluation ¶
type Evaluation struct { // Elements represents the unique serialization of an Elements Elements [][]byte `json:"e"` // Proofs ProofC []byte `json:"c,omitempty"` ProofS []byte `json:"s,omitempty"` }
Evaluation holds the serialized evaluated elements and serialized proof.
func (*Evaluation) Deserialize ¶
func (e *Evaluation) Deserialize(input []byte) error
Deserialize decodes the input into the Evaluation.
func (*Evaluation) Serialize ¶
func (e *Evaluation) Serialize() []byte
Serialize returns a compact encoding of the Evaluation.
type Identifier ¶
type Identifier string
Identifier of the OPRF compatible cipher suite to be used.
const ( // Ristretto255Sha512 is the OPRF cipher suite of the Ristretto255 group and SHA-512. Ristretto255Sha512 Identifier = "ristretto255-SHA512" // P256Sha256 is the OPRF cipher suite of the NIST P-256 group and SHA-256. P256Sha256 Identifier = "P256-SHA256" // P384Sha384 is the OPRF cipher suite of the NIST P-384 group and SHA-384. P384Sha384 Identifier = "P384-SHA384" // P521Sha512 is the OPRF cipher suite of the NIST P-512 group and SHA-512. P521Sha512 Identifier = "P521-SHA512" )
func FromGroup ¶
func FromGroup(g group.Group) (Identifier, error)
FromGroup returns a (V)OPRF Identifier given a Group Identifier.
func (Identifier) Available ¶
func (i Identifier) Available() bool
Available returns whether the Identifier is registered and available for usage.
func (Identifier) Client ¶
func (i Identifier) Client(mode Mode, serverPublicKey []byte) (*Client, error)
Client returns a (P|V)OPRF client. For the OPRF mode, serverPublicKey should be nil, and non-nil otherwise.
func (Identifier) Group ¶
func (i Identifier) Group() group.Group
Group returns the group identifier used in the cipher suite.
func (Identifier) Hash ¶
func (i Identifier) Hash() hash.Hashing
Hash returns the hash function identifier used in the cipher suite.
func (Identifier) KeyGen ¶
func (i Identifier) KeyGen() *KeyPair
KeyGen returns a fresh KeyPair for the given cipher suite.
func (Identifier) Server ¶
func (i Identifier) Server(mode Mode, privateKey []byte) (*Server, error)
Server returns a (P|V)OPRF server instantiated with the given encoded private key. If privateKey is nil, a new private/public key pair is created.
func (Identifier) String ¶
func (i Identifier) String() string
String implements the Stringer() interface for the Identifier.
type KeyPair ¶
type KeyPair struct { ID Identifier PublicKey []byte SecretKey []byte }
KeyPair assembles a VOPRF key pair. The SecretKey can be used as the evaluation key for the group identified by ID.
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server holds the (V)OPRF prover data.
func (Server) DeriveKeyPair ¶
DeriveKeyPair deterministically generates a private and public key pair from input seed.
func (*Server) Evaluate ¶
func (s *Server) Evaluate(blindedElement, info []byte) (*Evaluation, error)
Evaluate the input with the private key.
func (*Server) EvaluateBatch ¶
func (s *Server) EvaluateBatch(blindedElements [][]byte, info []byte) (*Evaluation, error)
EvaluateBatch evaluates the input batch of blindedElements and returns a pointer to the Evaluation. If the server was set to be un VOPRF mode, the proof will be included in the Evaluation.
func (*Server) FullEvaluate ¶
FullEvaluate reproduces the full PRF but without the blinding operations, using the client's input. This should output the same digest as the client's Finalize() function.
func (Server) HashToGroup ¶
HashToGroup maps the input data to an element of the group.
func (Server) HashToScalar ¶
HashToScalar maps the input data to a scalar.
func (*Server) Identifier ¶
func (s *Server) Identifier() Identifier
Identifier returns the cipher suite used in s' instance.
func (*Server) KeyGen ¶
func (s *Server) KeyGen()
KeyGen generates and sets a new private/public key pair.
func (*Server) PrivateKey ¶
PrivateKey returns the server's serialized private key.
func (*Server) SetProofNonce ¶
SetProofNonce sets the nonce used in the proof generation in the VOPRF and POPRF modes.
func (*Server) VerifyFinalize ¶
VerifyFinalize takes the client input (the un-blinded element) and the client's finalize() output, and returns whether it can match the client's output.
type State ¶
type State struct { Identifier Identifier `json:"s"` TweakedKey []byte `json:"t,omitempty"` ServerPublicKey []byte `json:"p,omitempty"` Input [][]byte `json:"i"` Blind [][]byte `json:"r"` Blinded [][]byte `json:"d"` Mode Mode `json:"m"` }
State represents a client's state, allowing internal values to be exported and imported to resume a session.
func (*State) RecoverClient ¶
RecoverClient returns a Client recovered form the state, from which a session can be resumed.