diff --git a/go/Makefile b/go/Makefile index 97f7248..43552bc 100644 --- a/go/Makefile +++ b/go/Makefile @@ -1,7 +1,7 @@ -TEST_FLAGS=./... -cover -count=1 +TEST_FLAGS=./... -cover -count=1 -mod=vendor BENCH_FLAGS=$(TEST_FLAGS) -bench=. COMPILED=voprf-go -BUILD_FLAGS=-o $(COMPILED) +BUILD_FLAGS=-o $(COMPILED) -mod=vendor # defaults GROUP=P384 diff --git a/go/client/client.go b/go/client/client.go index 2a30e38..bfdf9c0 100644 --- a/go/client/client.go +++ b/go/client/client.go @@ -14,7 +14,6 @@ import ( "github.com/alxdavids/voprf-poc/go/jsonrpc" "github.com/alxdavids/voprf-poc/go/oprf" gg "github.com/alxdavids/voprf-poc/go/oprf/groups" - "github.com/alxdavids/voprf-poc/go/oprf/groups/dleq" ) const ( @@ -44,7 +43,7 @@ type Config struct { // CreateConfig instantiates the client that will communicate with the HTTP // server running the (V)OPRF -func CreateConfig(ciphersuite string, pogInit gg.PrimeOrderGroup, n int, outputPath string, testIndex int) (*Config, error) { +func CreateConfig(ciphersuite int, pogInit gg.PrimeOrderGroup, n int, outputPath string, testIndex int) (*Config, error) { ptpnt, err := oprf.Client{}.Setup(ciphersuite, pogInit) if err != nil { return nil, err @@ -64,7 +63,7 @@ func CreateConfig(ciphersuite string, pogInit gg.PrimeOrderGroup, n int, outputP test: test, } if test { - raw, err := ioutil.ReadFile(fmt.Sprintf("../test-vectors/%s.json", ciphersuite)) + raw, err := ioutil.ReadFile(fmt.Sprintf("../test-vectors/%s.json", gg.IDtoName(ciphersuite))) if err != nil { return nil, err } @@ -223,7 +222,7 @@ func (cfg *Config) processServerResponse(jsonrpcResp *jsonrpc.ResponseSuccess) ( } // if the ciphersuite is verifiable then construct the proof object - if cfg.ocli.Ciphersuite().Verifiable() { + if cfg.ocli.Verifiable() { cBytes, err := hex.DecodeString(result.Proof[0]) if err != nil { return nil, nil, nil, oprf.BatchedEvaluation{}, err @@ -233,7 +232,7 @@ func (cfg *Config) processServerResponse(jsonrpcResp *jsonrpc.ResponseSuccess) ( return nil, nil, nil, oprf.BatchedEvaluation{}, err } var proofBytes = [][]byte{cBytes, sBytes} - ev.Proof = dleq.Proof{}.Deserialize(pog, proofBytes) + ev.Proof = oprf.Proof{}.Deserialize(pog, proofBytes) } // run the unblinding steps @@ -281,7 +280,7 @@ func (cfg *Config) createJSONRPCRequest(eles [][]byte, id int) *jsonrpc.Request Method: "eval", Params: jsonrpc.RequestParams{ Data: hexParams, - Ciphersuite: cfg.ocli.Ciphersuite().Name(), + Ciphersuite: cfg.ocli.Ciphersuite().ID(), }, ID: id, } @@ -352,7 +351,7 @@ func (cfg *Config) PrintStorage() error { outputStrings[j] = outString } - evJSON, err := storedEvaluations.ToJSON(cfg.ocli.Ciphersuite().Verifiable()) + evJSON, err := storedEvaluations.ToJSON(cfg.ocli.Verifiable()) if err != nil { return err } diff --git a/go/client/client_test.go b/go/client/client_test.go index 044054d..7fe3282 100644 --- a/go/client/client_test.go +++ b/go/client/client_test.go @@ -14,14 +14,8 @@ import ( "github.com/stretchr/testify/assert" ) -var ( - validOPRFP384Ciphersuite = "OPRF-P384-HKDF-SHA512-SSWU-RO" - validOPRFP521Ciphersuite = "OPRF-P521-HKDF-SHA512-SSWU-RO" - validOPRFC448Ciphersuite = "OPRF-curve448-HKDF-SHA512-ELL2-RO" -) - func TestCreateConfigP384(t *testing.T) { - cfg, err := CreateConfig(validOPRFP384Ciphersuite, ecgroup.GroupCurve{}, 1, "some_file", -1) + cfg, err := CreateConfig(gg.OPRF_P384_SHA512, ecgroup.GroupCurve{}, 1, "some_file", -1) if err != nil { t.Fatal(err) } @@ -32,7 +26,7 @@ func TestCreateConfigP384(t *testing.T) { } func TestCreateConfigP521(t *testing.T) { - cfg, err := CreateConfig(validOPRFP521Ciphersuite, ecgroup.GroupCurve{}, 1, "some_file", -1) + cfg, err := CreateConfig(gg.OPRF_P521_SHA512, ecgroup.GroupCurve{}, 1, "some_file", -1) if err != nil { t.Fatal(err) } @@ -43,7 +37,7 @@ func TestCreateConfigP521(t *testing.T) { } func TestCreateConfigC448(t *testing.T) { - cfg, err := CreateConfig(validOPRFC448Ciphersuite, ecgroup.GroupCurve{}, 1, "some_file", -1) + cfg, err := CreateConfig(gg.OPRF_CURVE448_SHA512, ecgroup.GroupCurve{}, 1, "some_file", -1) if err != nil { t.Fatal(err) } @@ -54,26 +48,26 @@ func TestCreateConfigC448(t *testing.T) { } func TestInvalidCiphersuite(t *testing.T) { - _, err := CreateConfig("OPRF-P256-HKDF-SHA512-SSWU-RO", ecgroup.GroupCurve{}, 1, "", -1) + _, err := CreateConfig(gg.GROUP_P256, ecgroup.GroupCurve{}, 1, "", -1) if !errors.Is(err, oerr.ErrUnsupportedGroup) { t.Fatal("bad group should have triggered a bad ciphersuite error") } } func TestCreateOPRFRequestP384(t *testing.T) { - CreateOPRFRequest(t, validOPRFP384Ciphersuite) + CreateOPRFRequest(t, gg.OPRF_P384_SHA512) } func TestCreateOPRFRequestP521(t *testing.T) { - CreateOPRFRequest(t, validOPRFP521Ciphersuite) + CreateOPRFRequest(t, gg.OPRF_P521_SHA512) } func TestCreateOPRFRequestC448(t *testing.T) { - CreateOPRFRequest(t, validOPRFC448Ciphersuite) + CreateOPRFRequest(t, gg.OPRF_CURVE448_SHA512) } -func CreateOPRFRequest(t *testing.T, config string) { - cfg, err := CreateConfig(config, ecgroup.GroupCurve{}, 1, "", -1) +func CreateOPRFRequest(t *testing.T, ciph int) { + cfg, err := CreateConfig(ciph, ecgroup.GroupCurve{}, 1, "", -1) if err != nil { t.Fatal(err) } @@ -112,19 +106,19 @@ func CreateOPRFRequest(t *testing.T, config string) { } func TestCreateOPRFRequestBadNP384(t *testing.T) { - CreateOPRFRequestBadN(t, validOPRFP384Ciphersuite) + CreateOPRFRequestBadN(t, gg.OPRF_P384_SHA512) } func TestCreateOPRFRequestBadNP521(t *testing.T) { - CreateOPRFRequestBadN(t, validOPRFP521Ciphersuite) + CreateOPRFRequestBadN(t, gg.OPRF_P521_SHA512) } func TestCreateOPRFRequestBadNC448(t *testing.T) { - CreateOPRFRequestBadN(t, validOPRFC448Ciphersuite) + CreateOPRFRequestBadN(t, gg.OPRF_CURVE448_SHA512) } -func CreateOPRFRequestBadN(t *testing.T, config string) { - cfg, err := CreateConfig(config, ecgroup.GroupCurve{}, -1, "", -1) +func CreateOPRFRequestBadN(t *testing.T, ciphID int) { + cfg, err := CreateConfig(ciphID, ecgroup.GroupCurve{}, -1, "", -1) if err != nil { t.Fatal(err) } @@ -135,19 +129,19 @@ func CreateOPRFRequestBadN(t *testing.T, config string) { } func TestCreateJSONRPCRequestP384(t *testing.T) { - CreateJSONRPCRequest(t, validOPRFP384Ciphersuite) + CreateJSONRPCRequest(t, gg.OPRF_P384_SHA512) } func TestCreateJSONRPCRequestP521(t *testing.T) { - CreateJSONRPCRequest(t, validOPRFP521Ciphersuite) + CreateJSONRPCRequest(t, gg.OPRF_P521_SHA512) } func TestCreateJSONRPCRequestC448(t *testing.T) { - CreateJSONRPCRequest(t, validOPRFC448Ciphersuite) + CreateJSONRPCRequest(t, gg.OPRF_CURVE448_SHA512) } -func CreateJSONRPCRequest(t *testing.T, config string) { - cfg, err := CreateConfig(config, ecgroup.GroupCurve{}, 1, "", -1) +func CreateJSONRPCRequest(t *testing.T, ciph int) { + cfg, err := CreateConfig(ciph, ecgroup.GroupCurve{}, 1, "", -1) if err != nil { t.Fatal(err) } @@ -162,19 +156,19 @@ func CreateJSONRPCRequest(t *testing.T, config string) { } func TestParseJSONRPCResponseSuccessP384(t *testing.T) { - ParseJSONRPCResponseSuccess(t, validOPRFP384Ciphersuite) + ParseJSONRPCResponseSuccess(t, gg.OPRF_P384_SHA512) } func TestParseJSONRPCResponseSuccessP521(t *testing.T) { - ParseJSONRPCResponseSuccess(t, validOPRFP521Ciphersuite) + ParseJSONRPCResponseSuccess(t, gg.OPRF_P521_SHA512) } func TestParseJSONRPCResponseSuccessC448(t *testing.T) { - ParseJSONRPCResponseSuccess(t, validOPRFC448Ciphersuite) + ParseJSONRPCResponseSuccess(t, gg.OPRF_CURVE448_SHA512) } -func ParseJSONRPCResponseSuccess(t *testing.T, config string) { - cfg, err := CreateConfig(config, ecgroup.GroupCurve{}, 1, "", -1) +func ParseJSONRPCResponseSuccess(t *testing.T, ciph int) { + cfg, err := CreateConfig(ciph, ecgroup.GroupCurve{}, 1, "", -1) if err != nil { t.Fatal(err) } @@ -199,19 +193,19 @@ func ParseJSONRPCResponseSuccess(t *testing.T, config string) { } func TestParseJSONRPCResponseErrorP384(t *testing.T) { - ParseJSONRPCResponseError(t, validOPRFP384Ciphersuite) + ParseJSONRPCResponseError(t, gg.OPRF_P384_SHA512) } func TestParseJSONRPCResponseErrorP521(t *testing.T) { - ParseJSONRPCResponseError(t, validOPRFP521Ciphersuite) + ParseJSONRPCResponseError(t, gg.OPRF_P521_SHA512) } func TestParseJSONRPCResponseErrorC448(t *testing.T) { - ParseJSONRPCResponseError(t, validOPRFC448Ciphersuite) + ParseJSONRPCResponseError(t, gg.OPRF_CURVE448_SHA512) } -func ParseJSONRPCResponseError(t *testing.T, config string) { - cfg, err := CreateConfig(config, ecgroup.GroupCurve{}, 1, "", -1) +func ParseJSONRPCResponseError(t *testing.T, ciph int) { + cfg, err := CreateConfig(ciph, ecgroup.GroupCurve{}, 1, "", -1) if err != nil { t.Fatal(err) } @@ -238,19 +232,19 @@ func ParseJSONRPCResponseError(t *testing.T, config string) { } func TestParseJSONRPCResponseInvalidResultP384(t *testing.T) { - ParseJSONRPCResponseInvalidResult(t, validOPRFP384Ciphersuite) + ParseJSONRPCResponseInvalidResult(t, gg.OPRF_P384_SHA512) } func TestParseJSONRPCResponseInvalidResultP521(t *testing.T) { - ParseJSONRPCResponseInvalidResult(t, validOPRFP521Ciphersuite) + ParseJSONRPCResponseInvalidResult(t, gg.OPRF_P521_SHA512) } func TestParseJSONRPCResponseInvalidResultC448(t *testing.T) { - ParseJSONRPCResponseInvalidResult(t, validOPRFC448Ciphersuite) + ParseJSONRPCResponseInvalidResult(t, gg.OPRF_CURVE448_SHA512) } -func ParseJSONRPCResponseInvalidResult(t *testing.T, config string) { - cfg, err := CreateConfig(config, ecgroup.GroupCurve{}, 1, "", -1) +func ParseJSONRPCResponseInvalidResult(t *testing.T, ciph int) { + cfg, err := CreateConfig(ciph, ecgroup.GroupCurve{}, 1, "", -1) if err != nil { t.Fatal(err) } @@ -269,19 +263,19 @@ func ParseJSONRPCResponseInvalidResult(t *testing.T, config string) { } func TestParseJSONRPCResponseInvalidFieldP384(t *testing.T) { - ParseJSONRPCResponseInvalidField(t, validOPRFP384Ciphersuite) + ParseJSONRPCResponseInvalidField(t, gg.OPRF_P384_SHA512) } func TestParseJSONRPCResponseInvalidFieldP521(t *testing.T) { - ParseJSONRPCResponseInvalidField(t, validOPRFP521Ciphersuite) + ParseJSONRPCResponseInvalidField(t, gg.OPRF_P521_SHA512) } func TestParseJSONRPCResponseInvalidFieldC448(t *testing.T) { - ParseJSONRPCResponseInvalidField(t, validOPRFC448Ciphersuite) + ParseJSONRPCResponseInvalidField(t, gg.OPRF_CURVE448_SHA512) } -func ParseJSONRPCResponseInvalidField(t *testing.T, config string) { - cfg, err := CreateConfig(config, ecgroup.GroupCurve{}, 1, "", -1) +func ParseJSONRPCResponseInvalidField(t *testing.T, ciph int) { + cfg, err := CreateConfig(ciph, ecgroup.GroupCurve{}, 1, "", -1) if err != nil { t.Fatal(err) } diff --git a/go/jsonrpc/jsonrpc.go b/go/jsonrpc/jsonrpc.go index c2e5d86..49027df 100644 --- a/go/jsonrpc/jsonrpc.go +++ b/go/jsonrpc/jsonrpc.go @@ -13,7 +13,7 @@ type Request struct { // RequestParams objects are sent as the main payload of the Request object type RequestParams struct { Data []string `json:"data"` - Ciphersuite string `json:"ciph"` + Ciphersuite int `json:"ciph"` } // ResponseSuccess constructs a successful JSONRPC response back to a diff --git a/go/main.go b/go/main.go index 0de6248..6e78907 100644 --- a/go/main.go +++ b/go/main.go @@ -7,20 +7,16 @@ import ( "os" "github.com/alxdavids/voprf-poc/go/client" + gg "github.com/alxdavids/voprf-poc/go/oprf/groups" "github.com/alxdavids/voprf-poc/go/oprf/groups/ecgroup" "github.com/alxdavids/voprf-poc/go/server" ) -var ( - validP384Ciphersuite = "OPRF-P384-HKDF-SHA512-SSWU-RO" - validP521Ciphersuite = "OPRF-P521-HKDF-SHA512-SSWU-RO" -) - func main() { - var mode, ciphersuite, clientOutFolder, pk string - var max, n, test int + var mode, clientOutFolder, pk string + var ciphersuite, max, n, test int flag.StringVar(&mode, "mode", "", "Specifies which mode to run in, options: (client|server).") - flag.StringVar(&ciphersuite, "ciph", validP384Ciphersuite, "Specifies the VOPRF ciphersuite to use.") + flag.IntVar(&ciphersuite, "ciph", gg.OPRF_P384_SHA512, "Specifies the VOPRF ciphersuite to use.") flag.StringVar(&clientOutFolder, "out_folder", "", "Specifies an output folder to write files containing the client's stored variables after invocation. If left empty, output is written to console.") flag.IntVar(&max, "max_evals", 10, "Specifies the maximum number of OPRF evaluations that are permitted by the server") flag.IntVar(&n, "n", 1, "Specifies the number of OPRF evaluations to be attempted by the client") @@ -48,7 +44,7 @@ func main() { } } -func runServer(ciphersuite string, max, test int) error { +func runServer(ciphersuite, max, test int) error { cfgServer, err := server.CreateConfig(ciphersuite, ecgroup.GroupCurve{}, max, false, test) if err != nil { return err @@ -63,7 +59,7 @@ func runServer(ciphersuite string, max, test int) error { return nil } -func runClient(ciphersuite, clientOutFolder string, n int, pk string, test int) error { +func runClient(ciphersuite int, clientOutFolder string, n int, pk string, test int) error { cfgClient, err := client.CreateConfig(ciphersuite, ecgroup.GroupCurve{}, n, clientOutFolder, test) if err != nil { return err diff --git a/go/oerr/oerr.go b/go/oerr/oerr.go index 69320f2..54163cc 100644 --- a/go/oerr/oerr.go +++ b/go/oerr/oerr.go @@ -61,6 +61,10 @@ var ( // ErrUnsupportedH2C indicates that the requested hash-to-curve function is // not supported. ErrUnsupportedH2C = errors.New("The chosen hash-to-curve function is not supported, currently supported functions: [SSWU-RO (for NIST curves)]") + // ErrUnsupportedCiphersuite indicates that the requested ciphersuite is + // not supported. + // TODO: fill in supported ciphersuites + ErrUnsupportedCiphersuite = errors.New("The chosen ciphersuite is not supported, currently supported ciphersuites: [TODO]") // ErrIncompatibleGroupParams indicates that the requested group has a // parameter setting that is incompatible with our implementation ErrIncompatibleGroupParams = errors.New("The chosen group has an incompatible parameter setting") diff --git a/go/oprf/groups/dleq/dleq.go b/go/oprf/groups/dleq/dleq.go index 1733c5e..29e561f 100644 --- a/go/oprf/groups/dleq/dleq.go +++ b/go/oprf/groups/dleq/dleq.go @@ -1,295 +1,295 @@ package dleq -import ( - "hash" - "math/big" - - "github.com/alxdavids/voprf-poc/go/oerr" - gg "github.com/alxdavids/voprf-poc/go/oprf/groups" - "github.com/alxdavids/voprf-poc/go/oprf/groups/ecgroup" - "github.com/alxdavids/voprf-poc/go/oprf/utils" -) - -// Proof corresponds to the DLEQ proof object that is used to prove that the -// server has correctly evaluated the random function during VOPRF evaluation -type Proof struct { - pog gg.PrimeOrderGroup - C, S *big.Int -} - -// Generate constructs a new Proof object using a VOPRF secret key and the group -// elements that were provided as input -func Generate(pog gg.PrimeOrderGroup, h2 utils.ExtractorExpander, h3 hash.Hash, k *big.Int, Y, blindToken, elem gg.GroupElement) (Proof, error) { - t, err := pog.RandomScalar() - if err != nil { - return Proof{}, err - } - - return FixedGenerate(pog, h2, h3, k, Y, blindToken, elem, t) -} - -// FixedGenerate constructs a new Proof object with the random scalar t -// explicitly generated -func FixedGenerate(pog gg.PrimeOrderGroup, h2 utils.ExtractorExpander, h3 hash.Hash, k *big.Int, Y, blindToken, elem gg.GroupElement, t *big.Int) (Proof, error) { - // A := tG, B := tM - A, err := pog.GeneratorMult(t) - if err != nil { - return Proof{}, err - } - B, err := blindToken.ScalarMult(t) - if err != nil { - return Proof{}, err - } - - // compute hash output c - c, err := computeDleqChallenge(pog, h2, h3, pog.Generator(), Y, blindToken, elem, A, B) - if err != nil { - return Proof{}, err - } - // s = t-ck - ck := new(big.Int).Mul(c, k) - n := pog.(ecgroup.GroupCurve).Order() - s := new(big.Int).Sub(t, ck) - - return Proof{pog: pog, C: c.Mod(c, n), S: s.Mod(s, n)}, nil -} - -// BatchGenerate generates a batched DLEQ proof evaluated over multiple values -// of the form elem[i] = kM[i], wrt to the public key Y = kG -func BatchGenerate(pog gg.PrimeOrderGroup, h2 utils.ExtractorExpander, h3 hash.Hash, k *big.Int, Y gg.GroupElement, blindTokens, elems []gg.GroupElement) (Proof, error) { - // compute composite group elements - blindToken, elem, err := batchComposites(pog, h2, h3, Y, blindTokens, elems) - if err != nil { - return Proof{}, err - } - - // generate DLEQ proof object - return Generate(pog, h2, h3, k, Y, blindToken, elem) -} - -// FixedBatchGenerate generates a batched DLEQ proof with fixed proof generation -func FixedBatchGenerate(pog gg.PrimeOrderGroup, h2 utils.ExtractorExpander, h3 hash.Hash, k *big.Int, Y gg.GroupElement, blindTokens, elems []gg.GroupElement, t *big.Int) (Proof, error) { - // compute composite group elements - blindToken, elem, err := batchComposites(pog, h2, h3, Y, blindTokens, elems) - if err != nil { - return Proof{}, err - } - - // generate DLEQ proof object - return FixedGenerate(pog, h2, h3, k, Y, blindToken, elem, t) -} - -// Verify runs the DLEQ proof validation algorithm and returns a bool -// indicating success or failure -func (proof Proof) Verify(pog gg.PrimeOrderGroup, h2 utils.ExtractorExpander, h3 hash.Hash, Y, blindToken, elem gg.GroupElement) bool { - // A = sG + cY - sG, err := pog.GeneratorMult(proof.S) - if err != nil { - return false - } - cY, err := Y.ScalarMult(proof.C) - if err != nil { - return false - } - A, err := sG.Add(cY) - if err != nil { - return false - } - // B = sM + cZ - sM, err := blindToken.ScalarMult(proof.S) - if err != nil { - return false - } - cZ, err := elem.ScalarMult(proof.C) - if err != nil { - return false - } - B, err := sM.Add(cZ) - if err != nil { - return false - } - - // recompute hash output - c, err := computeDleqChallenge(pog, h2, h3, pog.Generator(), Y, blindToken, elem, A, B) - if err != nil { - return false - } - - // check hash outputs - if c.Mod(c, pog.Order()).Cmp(proof.C) == 0 { - return true - } - return false -} - -// BatchVerify verifies a batched DLEQ proof object over an array of -// GroupElement objects of the form Zi = kMi where Y = kG. -func (proof Proof) BatchVerify(pog gg.PrimeOrderGroup, h2 utils.ExtractorExpander, h3 hash.Hash, Y gg.GroupElement, blindTokens, elems []gg.GroupElement) bool { - // compute composite group elements - blindToken, elem, err := batchComposites(pog, h2, h3, Y, blindTokens, elems) - if err != nil { - return false - } - - // Verify standalone DLEQ proof object - return proof.Verify(pog, h2, h3, Y, blindToken, elem) -} - -// Serialize takes the values of the proof object and converts them into bytes -func (proof Proof) Serialize() [][]byte { - return [][]byte{proof.pog.ScalarToBytes(proof.C), proof.pog.ScalarToBytes(proof.S)} -} - -// Deserialize takes the provided bytes and converts them into a valid Proof -// object -func (proof Proof) Deserialize(pog gg.PrimeOrderGroup, proofBytes [][]byte) Proof { - return Proof{pog: pog, C: new(big.Int).SetBytes(proofBytes[0]), S: new(big.Int).SetBytes(proofBytes[1])} -} - -// computeSeed constructs the initial seed that is used for constructing and -// verifying batched DLEQ proofs -func computeSeed(pog gg.PrimeOrderGroup, h4 hash.Hash, Y gg.GroupElement, blindTokens, elems []gg.GroupElement) ([]byte, error) { - m := len(blindTokens) - if m != len(elems) { - return nil, oerr.ErrDLEQInvalidInput - } - - // compute seed - inputs := append(blindTokens, elems...) - inputs = append([]gg.GroupElement{pog.Generator(), Y}, inputs...) - seed, err := computeHash(h4, inputs...) - if err != nil { - return nil, err - } - return seed, nil -} - -// computeComposites constructs the composite GroupElement objects that are -// used for generating and verifying a batched DLEQ proof -func computeComposites(pog gg.PrimeOrderGroup, h2 utils.ExtractorExpander, h3 hash.Hash, seed []byte, blindTokens, elems []gg.GroupElement) (gg.GroupElement, gg.GroupElement, error) { - var blindToken gg.GroupElement - var elem gg.GroupElement - ctr := 0 - for i := 0; i < len(blindTokens); i++ { - ctrBytes, err := utils.I2osp(ctr, 4) - if err != nil { - return nil, nil, err - } - ctr++ - hkdfInp := append(ctrBytes, []byte("voprf_batch_dleq")...) - - // sample coefficient and reject if it is too big - di := computeExpansion(pog, h2, h3, seed, hkdfInp) - if di.Cmp(pog.Order()) > 0 { - i-- - continue - } - - // multiply group elements by coefficients - diMi, err := blindTokens[i].ScalarMult(di) - if err != nil { - return nil, nil, err - } - diZi, err := elems[i].ScalarMult(di) - if err != nil { - return nil, nil, err - } - - // init blindToken if haven't already done so - if blindToken == nil { - blindToken = diMi - elem = diZi - continue - } - - // Add points together - blindToken, err = blindToken.Add(diMi) - if err != nil { - return nil, nil, err - } - elem, err = elem.Add(diZi) - if err != nil { - return nil, nil, err - } - } - return blindToken, elem, nil -} - -func batchComposites(pog gg.PrimeOrderGroup, h2 utils.ExtractorExpander, h3 hash.Hash, Y gg.GroupElement, blindTokens, elems []gg.GroupElement) (gg.GroupElement, gg.GroupElement, error) { - seed, err := computeSeed(pog, h3, Y, blindTokens, elems) - if err != nil { - return nil, nil, err - } - return computeComposites(pog, h2, h3, seed, blindTokens, elems) -} - -// computeHash serializes the group elements and computes the hash output c -func computeHash(h hash.Hash, eles ...gg.GroupElement) ([]byte, error) { - serialized, err := getSerializedElements(eles...) - if err != nil { - return nil, err - } - h.Reset() - for _, buf := range serialized { - _, err = h.Write(buf) - if err != nil { - return nil, err - } - } - return h.Sum(nil), nil -} - -// computeDleqChallenge outputs a BigInt value corresponding to the -// randomly distributed challenge in an invocation of the DLEQ NIZK (in -// accordance with the FS transform) -func computeDleqChallenge(pog gg.PrimeOrderGroup, ee utils.ExtractorExpander, h hash.Hash, eles ...gg.GroupElement) (*big.Int, error) { - seed, err := computeHash(h, eles...) - if err != nil { - return nil, err - } - - // rejection sampling for values that are less than the group order - ctr := 0 - for { - ctrBytes, err := utils.I2osp(ctr, 4) - if err != nil { - return nil, err - } - c := computeExpansion(pog, ee, h, seed, append(ctrBytes, []byte("voprf_dleq_challenge")...)) - if c.Cmp(pog.Order()) >= 0 { - continue - } - return c, nil - } -} - -// computeExpansion computes a scalar value for the scalar field GF(p) -// associated with the prime-order group from the expansion of an initial seed -// and label -func computeExpansion(pog gg.PrimeOrderGroup, ee utils.ExtractorExpander, h hash.Hash, seed, label []byte) *big.Int { - expander := ee.Expander() - output := expander(func() hash.Hash { h.Reset(); return h }, seed, label) - bitSize := pog.Order().BitLen() - byteLen := (bitSize + 7) >> 3 - r := make([]byte, byteLen) - output.Read(r) - // we have to mask off excess bits if the size of the underlying field is - // not a whole number of bytes (see - // https://github.com/golang/go/blob/master/src/crypto/elliptic/elliptic.go#L273) - r = utils.MaskScalar(r, bitSize) - return new(big.Int).SetBytes(r) -} - -// getSerializedElements returns the serializations of multiple GroupElement -// objects -func getSerializedElements(eles ...gg.GroupElement) ([][]byte, error) { - serialized := make([][]byte, len(eles)) - for i, x := range eles { - buf, err := x.Serialize() - if err != nil { - return nil, err - } - serialized[i] = buf - } - return serialized, nil -} +// import ( +// "hash" +// "math/big" + +// "github.com/alxdavids/voprf-poc/go/oerr" +// gg "github.com/alxdavids/voprf-poc/go/oprf/groups" +// "github.com/alxdavids/voprf-poc/go/oprf/groups/ecgroup" +// "github.com/alxdavids/voprf-poc/go/oprf/utils" +// ) + +// // Proof corresponds to the DLEQ proof object that is used to prove that the +// // server has correctly evaluated the random function during VOPRF evaluation +// type Proof struct { +// pog gg.PrimeOrderGroup +// C, S *big.Int +// } + +// // Generate constructs a new Proof object using a VOPRF secret key and the group +// // elements that were provided as input +// func Generate(pog gg.PrimeOrderGroup, h hash.Hash, k *big.Int, Y, blindToken, elem gg.GroupElement) (Proof, error) { +// t, err := pog.RandomScalar() +// if err != nil { +// return Proof{}, err +// } + +// return FixedGenerate(pog, h, k, Y, blindToken, elem, t) +// } + +// // FixedGenerate constructs a new Proof object with the random scalar t +// // explicitly generated +// func FixedGenerate(pog gg.PrimeOrderGroup, h hash.Hash, k *big.Int, Y, blindToken, elem gg.GroupElement, t *big.Int) (Proof, error) { +// // A := tG, B := tM +// A, err := pog.GeneratorMult(t) +// if err != nil { +// return Proof{}, err +// } +// B, err := blindToken.ScalarMult(t) +// if err != nil { +// return Proof{}, err +// } + +// // compute hash output c +// c, err := computeDleqChallenge(pog, h, pog.Generator(), Y, blindToken, elem, A, B) +// if err != nil { +// return Proof{}, err +// } +// // s = t-ck +// ck := new(big.Int).Mul(c, k) +// n := pog.(ecgroup.GroupCurve).Order() +// s := new(big.Int).Sub(t, ck) + +// return Proof{pog: pog, C: c.Mod(c, n), S: s.Mod(s, n)}, nil +// } + +// // BatchGenerate generates a batched DLEQ proof evaluated over multiple values +// // of the form elem[i] = kM[i], wrt to the public key Y = kG +// func BatchGenerate(pog gg.PrimeOrderGroup, h hash.Hash, k *big.Int, Y gg.GroupElement, blindTokens, elems []gg.GroupElement) (Proof, error) { +// // compute composite group elements +// blindToken, elem, err := batchComposites(pog, h, Y, blindTokens, elems) +// if err != nil { +// return Proof{}, err +// } + +// // generate DLEQ proof object +// return Generate(pog, h, k, Y, blindToken, elem) +// } + +// // FixedBatchGenerate generates a batched DLEQ proof with fixed proof generation +// func FixedBatchGenerate(pog gg.PrimeOrderGroup, h hash.Hash, k *big.Int, Y gg.GroupElement, blindTokens, elems []gg.GroupElement, t *big.Int) (Proof, error) { +// // compute composite group elements +// blindToken, elem, err := batchComposites(pog, h, Y, blindTokens, elems) +// if err != nil { +// return Proof{}, err +// } + +// // generate DLEQ proof object +// return FixedGenerate(pog, h, k, Y, blindToken, elem, t) +// } + +// // Verify runs the DLEQ proof validation algorithm and returns a bool +// // indicating success or failure +// func (proof Proof) Verify(pog gg.PrimeOrderGroup, h hash.Hash, Y, blindToken, elem gg.GroupElement) bool { +// // A = sG + cY +// sG, err := pog.GeneratorMult(proof.S) +// if err != nil { +// return false +// } +// cY, err := Y.ScalarMult(proof.C) +// if err != nil { +// return false +// } +// A, err := sG.Add(cY) +// if err != nil { +// return false +// } +// // B = sM + cZ +// sM, err := blindToken.ScalarMult(proof.S) +// if err != nil { +// return false +// } +// cZ, err := elem.ScalarMult(proof.C) +// if err != nil { +// return false +// } +// B, err := sM.Add(cZ) +// if err != nil { +// return false +// } + +// // recompute hash output +// c, err := computeDleqChallenge(pog, h, pog.Generator(), Y, blindToken, elem, A, B) +// if err != nil { +// return false +// } + +// // check hash outputs +// if c.Mod(c, pog.Order()).Cmp(proof.C) == 0 { +// return true +// } +// return false +// } + +// // BatchVerify verifies a batched DLEQ proof object over an array of +// // GroupElement objects of the form Zi = kMi where Y = kG. +// func (proof Proof) BatchVerify(pog gg.PrimeOrderGroup, h hash.Hash, Y gg.GroupElement, blindTokens, elems []gg.GroupElement) bool { +// // compute composite group elements +// blindToken, elem, err := batchComposites(pog, h, Y, blindTokens, elems) +// if err != nil { +// return false +// } + +// // Verify standalone DLEQ proof object +// return proof.Verify(pog, h, Y, blindToken, elem) +// } + +// // Serialize takes the values of the proof object and converts them into bytes +// func (proof Proof) Serialize() [][]byte { +// return [][]byte{proof.pog.ScalarToBytes(proof.C), proof.pog.ScalarToBytes(proof.S)} +// } + +// // Deserialize takes the provided bytes and converts them into a valid Proof +// // object +// func (proof Proof) Deserialize(pog gg.PrimeOrderGroup, proofBytes [][]byte) Proof { +// return Proof{pog: pog, C: new(big.Int).SetBytes(proofBytes[0]), S: new(big.Int).SetBytes(proofBytes[1])} +// } + +// // computeSeed constructs the initial seed that is used for constructing and +// // verifying batched DLEQ proofs +// func computeSeed(pog gg.PrimeOrderGroup, h4 hash.Hash, Y gg.GroupElement, blindTokens, elems []gg.GroupElement) ([]byte, error) { +// m := len(blindTokens) +// if m != len(elems) { +// return nil, oerr.ErrDLEQInvalidInput +// } + +// // compute seed +// inputs := append(blindTokens, elems...) +// inputs = append([]gg.GroupElement{pog.Generator(), Y}, inputs...) +// seed, err := computeHash(h4, inputs...) +// if err != nil { +// return nil, err +// } +// return seed, nil +// } + +// // computeComposites constructs the composite GroupElement objects that are +// // used for generating and verifying a batched DLEQ proof +// func computeComposites(pog gg.PrimeOrderGroup, h hash.Hash, seed []byte, blindTokens, elems []gg.GroupElement) (gg.GroupElement, gg.GroupElement, error) { +// var blindToken gg.GroupElement +// var elem gg.GroupElement +// ctr := 0 +// for i := 0; i < len(blindTokens); i++ { +// ctrBytes, err := utils.I2osp(ctr, 4) +// if err != nil { +// return nil, nil, err +// } +// ctr++ +// hkdfInp := append(ctrBytes, []byte("voprf_batch_dleq")...) + +// // sample coefficient and reject if it is too big +// di := computeExpansion(pog, h, seed, hkdfInp) +// if di.Cmp(pog.Order()) > 0 { +// i-- +// continue +// } + +// // multiply group elements by coefficients +// diMi, err := blindTokens[i].ScalarMult(di) +// if err != nil { +// return nil, nil, err +// } +// diZi, err := elems[i].ScalarMult(di) +// if err != nil { +// return nil, nil, err +// } + +// // init blindToken if haven't already done so +// if blindToken == nil { +// blindToken = diMi +// elem = diZi +// continue +// } + +// // Add points together +// blindToken, err = blindToken.Add(diMi) +// if err != nil { +// return nil, nil, err +// } +// elem, err = elem.Add(diZi) +// if err != nil { +// return nil, nil, err +// } +// } +// return blindToken, elem, nil +// } + +// func batchComposites(pog gg.PrimeOrderGroup, h hash.Hash, Y gg.GroupElement, blindTokens, elems []gg.GroupElement) (gg.GroupElement, gg.GroupElement, error) { +// seed, err := computeSeed(pog, h3, Y, blindTokens, elems) +// if err != nil { +// return nil, nil, err +// } +// return computeComposites(pog, h, seed, blindTokens, elems) +// } + +// // computeHash serializes the group elements and computes the hash output c +// func computeHash(h hash.Hash, eles ...gg.GroupElement) ([]byte, error) { +// serialized, err := getSerializedElements(eles...) +// if err != nil { +// return nil, err +// } +// h.Reset() +// for _, buf := range serialized { +// _, err = h.Write(buf) +// if err != nil { +// return nil, err +// } +// } +// return h.Sum(nil), nil +// } + +// // computeDleqChallenge outputs a BigInt value corresponding to the +// // randomly distributed challenge in an invocation of the DLEQ NIZK (in +// // accordance with the FS transform) +// func computeDleqChallenge(pog gg.PrimeOrderGroup, h hash.Hash, eles ...gg.GroupElement) (*big.Int, error) { +// seed, err := computeHash(h, eles...) +// if err != nil { +// return nil, err +// } + +// // rejection sampling for values that are less than the group order +// ctr := 0 +// for { +// ctrBytes, err := utils.I2osp(ctr, 4) +// if err != nil { +// return nil, err +// } +// c := computeExpansion(pog, h, seed, append(ctrBytes, []byte("voprf_dleq_challenge")...)) +// if c.Cmp(pog.Order()) >= 0 { +// continue +// } +// return c, nil +// } +// } + +// // computeExpansion computes a scalar value for the scalar field GF(p) +// // associated with the prime-order group from the expansion of an initial seed +// // and label +// func computeExpansion(pog gg.PrimeOrderGroup, h hash.Hash, seed, label []byte) *big.Int { +// expander := ee.Expander() +// output := expander(func() hash.Hash { h.Reset(); return h }, seed, label) +// bitSize := pog.Order().BitLen() +// byteLen := (bitSize + 7) >> 3 +// r := make([]byte, byteLen) +// output.Read(r) +// // we have to mask off excess bits if the size of the underlying field is +// // not a whole number of bytes (see +// // https://github.com/golang/go/blob/master/src/crypto/elliptic/elliptic.go#L273) +// r = utils.MaskScalar(r, bitSize) +// return new(big.Int).SetBytes(r) +// } + +// // getSerializedElements returns the serializations of multiple GroupElement +// // objects +// func getSerializedElements(eles ...gg.GroupElement) ([][]byte, error) { +// serialized := make([][]byte, len(eles)) +// for i, x := range eles { +// buf, err := x.Serialize() +// if err != nil { +// return nil, err +// } +// serialized[i] = buf +// } +// return serialized, nil +// } diff --git a/go/oprf/groups/dleq/dleq_test.go b/go/oprf/groups/dleq/dleq_test.go index 716ca31..433b14a 100644 --- a/go/oprf/groups/dleq/dleq_test.go +++ b/go/oprf/groups/dleq/dleq_test.go @@ -1,402 +1,401 @@ package dleq -import ( - "errors" - "fmt" - "hash" - "math/big" - "testing" - - "github.com/alxdavids/voprf-poc/go/oerr" - gg "github.com/alxdavids/voprf-poc/go/oprf/groups" - "github.com/alxdavids/voprf-poc/go/oprf/groups/ecgroup" - "github.com/alxdavids/voprf-poc/go/oprf/utils" -) - -func TestValidDLEQP384(t *testing.T) { - validateDLEQ(t, "P384") -} - -func TestValidDLEQP521(t *testing.T) { - validateDLEQ(t, "P521") -} - -func TestValidBatchedDLEQP384(t *testing.T) { - validateBatchedDLEQ(t, "P384") -} - -func TestValidBatchedDLEQP521(t *testing.T) { - validateBatchedDLEQ(t, "P521") -} - -func TestValidDLEQC448(t *testing.T) { - validateDLEQ(t, "curve448") -} - -func TestValidBatchedDLEQC448(t *testing.T) { - validateBatchedDLEQ(t, "curve448") -} - -func TestBatchedDLEQInvalidLengths(t *testing.T) { - pog, h2, h3, sk, pk, blindTokens, elems, proof, err := createBatchedProof("P384", 5) - if err != nil { - t.Fatal(err) - } - extraZ, err := pog.HashToGroup([]byte("last_element")) - if err != nil { - t.Fatal(err) - } - badBatchZ := append(elems, extraZ) - - _, err = BatchGenerate(pog, h2, h3, sk, pk, blindTokens, badBatchZ) - if !errors.Is(err, oerr.ErrDLEQInvalidInput) { - t.Fatal(err) - } - if proof.BatchVerify(pog, h2, h3, pk, blindTokens, badBatchZ) { - t.Fatal("verification should have failed for bad lengths") - } -} - -func TestBatchedDLEQBadElement(t *testing.T) { - pog, h2, h3, sk, pk, blindTokens, _, proof, err := createBatchedProof("P384", 5) - if err != nil { - t.Fatal(err) - } - - // create bad element - badZ, err := pog.HashToGroup([]byte("bad_element")) - if err != nil { - t.Fatal(err) - } - badBatchZ := blindTokens - badBatchZ[2] = badZ - - // fail verify for bad proof - badProof, err := BatchGenerate(pog, h2, h3, sk, pk, blindTokens, badBatchZ) - if err != nil { - t.Fatal(err) - } - if badProof.BatchVerify(pog, h2, h3, pk, blindTokens, badBatchZ) { - t.Fatal("verification should have failed due to bad element") - } - - // fail verify for good proof but bad verify input - if proof.BatchVerify(pog, h2, h3, pk, blindTokens, badBatchZ) { - t.Fatal("verification should have failed for bad input element") - } -} - -func validateDLEQ(t *testing.T, groupName string) { - pog, h2, h3, _, pk, blindToken, elem, proof, err := createProof(groupName) - if err != nil { - t.Fatal(err) - } - if !proof.Verify(pog, h2, h3, pk, blindToken, elem) { - t.Fatal("Proof failed to validate") - } -} - -func validateBatchedDLEQ(t *testing.T, groupName string) { - pog, h2, h3, _, pk, blindTokens, elems, proof, err := createBatchedProof(groupName, 5) - if err != nil { - t.Fatal(err) - } - if !proof.BatchVerify(pog, h2, h3, pk, blindTokens, elems) { - t.Fatal("Batch proof failed to verify") - } -} - -func generateAndEval(pog gg.PrimeOrderGroup, sk *big.Int, lbl string) (gg.GroupElement, gg.GroupElement, error) { - blindToken, err := pog.HashToGroup([]byte(lbl)) - if err != nil { - return nil, nil, err - } - elem, err := blindToken.ScalarMult(sk) - if err != nil { - return nil, nil, err - } - return blindToken, elem, nil -} - -func setup(groupName string) (gg.PrimeOrderGroup, utils.ExtractorExpander, hash.Hash, *big.Int, gg.GroupElement, error) { - ciphName := fmt.Sprintf("VOPRF-%s-HKDF-SHA512-SSWU-RO", groupName) - ciph, err := gg.Ciphersuite{}.FromString(ciphName, ecgroup.GroupCurve{}) - if err != nil { - return nil, nil, nil, nil, nil, err - } - pog := ciph.POG() - h2 := ciph.H2() - h3 := ciph.H3() - sk, err := pog.RandomScalar() - if err != nil { - return nil, nil, nil, nil, nil, err - } - pk, err := pog.GeneratorMult(sk) - if err != nil { - return nil, nil, nil, nil, nil, err - } - return pog, h2, h3, sk, pk, nil -} - -func createProof(groupName string) (gg.PrimeOrderGroup, utils.ExtractorExpander, hash.Hash, *big.Int, gg.GroupElement, gg.GroupElement, gg.GroupElement, Proof, error) { - pog, h2, h3, sk, pk, err := setup(groupName) - if err != nil { - return nil, nil, nil, nil, nil, nil, nil, Proof{}, err - } - blindToken, elem, err := generateAndEval(pog, sk, "random_input") - if err != nil { - return nil, nil, nil, nil, nil, nil, nil, Proof{}, err - } - - proof, err := Generate(pog, h2, h3, sk, pk, blindToken, elem) - if err != nil { - return nil, nil, nil, nil, nil, nil, nil, Proof{}, err - } - return pog, h2, h3, sk, pk, blindToken, elem, proof, nil -} - -func createBatchedProof(groupName string, n int) (gg.PrimeOrderGroup, utils.ExtractorExpander, hash.Hash, *big.Int, gg.GroupElement, []gg.GroupElement, []gg.GroupElement, Proof, error) { - pog, h2, h3, sk, pk, err := setup(groupName) - if err != nil { - return nil, nil, nil, nil, nil, nil, nil, Proof{}, err - } - blindTokens := make([]gg.GroupElement, n) - elems := make([]gg.GroupElement, n) - for i := 0; i < n; i++ { - blindTokens[i], elems[i], err = generateAndEval(pog, sk, fmt.Sprintf("random_input_%v", i)) - if err != nil { - return nil, nil, nil, nil, nil, nil, nil, Proof{}, err - } - } - - proof, err := BatchGenerate(pog, h2, h3, sk, pk, blindTokens, elems) - if err != nil { - return nil, nil, nil, nil, nil, nil, nil, Proof{}, err - } - - return pog, h2, h3, sk, pk, blindTokens, elems, proof, nil -} - -/** - * Benchmarks - */ - -func BenchmarkGenerateP384(b *testing.B) { - benchGenerate(b, "P384") -} - -func BenchmarkGenerateP521(b *testing.B) { - benchGenerate(b, "P521") -} - -func BenchmarkGenerateC448(b *testing.B) { - benchGenerate(b, "curve448") -} - -func benchGenerate(b *testing.B, groupName string) { - pog, h2, h3, sk, pk, blindToken, elem, _, err := createProof(groupName) - if err != nil { - b.Fatal(err) - } - - for i := 0; i < b.N; i++ { - _, err := Generate(pog, h2, h3, sk, pk, blindToken, elem) - if err != nil { - b.Fatal(err) - } - } -} - -func BenchmarkVerifyP384(b *testing.B) { - benchVerify(b, "P384") -} - -func BenchmarkVerifyP521(b *testing.B) { - benchVerify(b, "P521") -} - -func BenchmarkVerifyC448(b *testing.B) { - benchVerify(b, "Curve448") -} - -func benchVerify(b *testing.B, groupName string) { - pog, h2, h3, _, pk, blindToken, elem, proof, err := createProof(groupName) - if err != nil { - b.Fatal(err) - } - - for i := 0; i < b.N; i++ { - if !proof.Verify(pog, h2, h3, pk, blindToken, elem) { - b.Fatal("bad verification") - } - } -} - -func BenchmarkGenerateP384_2(b *testing.B) { - benchBatchedGenerate(b, "P384", 2) -} - -func BenchmarkGenerateP384_5(b *testing.B) { - benchBatchedGenerate(b, "P384", 5) -} - -func BenchmarkGenerateP384_10(b *testing.B) { - benchBatchedGenerate(b, "P384", 10) -} - -func BenchmarkGenerateP384_25(b *testing.B) { - benchBatchedGenerate(b, "P384", 25) -} - -func BenchmarkGenerateP384_50(b *testing.B) { - benchBatchedGenerate(b, "P384", 50) -} - -func BenchmarkGenerateP384_100(b *testing.B) { - benchBatchedGenerate(b, "P384", 100) -} - -func BenchmarkGenerateP521_2(b *testing.B) { - benchBatchedGenerate(b, "P521", 2) -} - -func BenchmarkGenerateP521_5(b *testing.B) { - benchBatchedGenerate(b, "P521", 5) -} - -func BenchmarkGenerateP521_10(b *testing.B) { - benchBatchedGenerate(b, "P521", 10) -} - -func BenchmarkGenerateP521_25(b *testing.B) { - benchBatchedGenerate(b, "P521", 25) -} - -func BenchmarkGenerateP521_50(b *testing.B) { - benchBatchedGenerate(b, "P521", 50) -} - -func BenchmarkGenerateP521_100(b *testing.B) { - benchBatchedGenerate(b, "P521", 100) -} - -func BenchmarkGenerateC448_2(b *testing.B) { - benchBatchedGenerate(b, "curve448", 2) -} - -func BenchmarkGenerateC448_5(b *testing.B) { - benchBatchedGenerate(b, "curve448", 5) -} - -func BenchmarkGenerateC448_10(b *testing.B) { - benchBatchedGenerate(b, "curve448", 10) -} - -func BenchmarkGenerateC448_25(b *testing.B) { - benchBatchedGenerate(b, "curve448", 25) -} - -func BenchmarkGenerateC448_50(b *testing.B) { - benchBatchedGenerate(b, "curve448", 50) -} - -func BenchmarkGenerateC448_100(b *testing.B) { - benchBatchedGenerate(b, "curve448", 100) -} - -func benchBatchedGenerate(b *testing.B, groupName string, n int) { - pog, h2, h3, sk, pk, blindTokens, elems, _, err := createBatchedProof(groupName, n) - if err != nil { - b.Fatal(err) - } - for i := 0; i < b.N; i++ { - _, err = BatchGenerate(pog, h2, h3, sk, pk, blindTokens, elems) - if err != nil { - b.Fatal(err) - } - } -} - -func BenchmarkVerifyP384_2(b *testing.B) { - benchBatchedVerify(b, "P384", 2) -} - -func BenchmarkVerifyP384_5(b *testing.B) { - benchBatchedVerify(b, "P384", 5) -} - -func BenchmarkVerifyP384_10(b *testing.B) { - benchBatchedVerify(b, "P384", 10) -} - -func BenchmarkVerifyP384_25(b *testing.B) { - benchBatchedVerify(b, "P384", 25) -} - -func BenchmarkVerifyP384_50(b *testing.B) { - benchBatchedVerify(b, "P384", 50) -} - -func BenchmarkVerifyP384_100(b *testing.B) { - benchBatchedVerify(b, "P384", 100) -} - -func BenchmarkVerifyP521_2(b *testing.B) { - benchBatchedVerify(b, "P521", 2) -} - -func BenchmarkVerifyP521_5(b *testing.B) { - benchBatchedVerify(b, "P521", 5) -} - -func BenchmarkVerifyP521_10(b *testing.B) { - benchBatchedVerify(b, "P521", 10) -} - -func BenchmarkVerifyP521_25(b *testing.B) { - benchBatchedVerify(b, "P521", 25) -} - -func BenchmarkVerifyP521_50(b *testing.B) { - benchBatchedVerify(b, "P521", 50) -} - -func BenchmarkVerifyP521_100(b *testing.B) { - benchBatchedVerify(b, "P521", 100) -} - -func BenchmarkVerifyC448_2(b *testing.B) { - benchBatchedVerify(b, "curve448", 2) -} - -func BenchmarkVerifyC448_5(b *testing.B) { - benchBatchedVerify(b, "curve448", 5) -} - -func BenchmarkVerifyC448_10(b *testing.B) { - benchBatchedVerify(b, "curve448", 10) -} - -func BenchmarkVerifyC448_25(b *testing.B) { - benchBatchedVerify(b, "curve448", 25) -} - -func BenchmarkVerifyC448_50(b *testing.B) { - benchBatchedVerify(b, "curve448", 50) -} - -func BenchmarkVerifyC448_100(b *testing.B) { - benchBatchedVerify(b, "curve448", 100) -} - -func benchBatchedVerify(b *testing.B, groupName string, n int) { - pog, h2, h3, _, pk, blindTokens, elems, proof, err := createBatchedProof(groupName, n) - if err != nil { - b.Fatal(err) - } - for i := 0; i < b.N; i++ { - if !proof.BatchVerify(pog, h2, h3, pk, blindTokens, elems) { - b.Fatal("bad batch verification") - } - } -} +// import ( +// "errors" +// "fmt" +// "hash" +// "math/big" +// "testing" + +// "github.com/alxdavids/voprf-poc/go/oerr" +// gg "github.com/alxdavids/voprf-poc/go/oprf/groups" +// "github.com/alxdavids/voprf-poc/go/oprf/groups/ecgroup" +// "github.com/alxdavids/voprf-poc/go/oprf/utils" +// ) + +// func TestValidDLEQP384(t *testing.T) { +// validateDLEQ(t, "P384") +// } + +// func TestValidDLEQP521(t *testing.T) { +// validateDLEQ(t, "P521") +// } + +// func TestValidBatchedDLEQP384(t *testing.T) { +// validateBatchedDLEQ(t, "P384") +// } + +// func TestValidBatchedDLEQP521(t *testing.T) { +// validateBatchedDLEQ(t, "P521") +// } + +// func TestValidDLEQC448(t *testing.T) { +// validateDLEQ(t, "curve448") +// } + +// func TestValidBatchedDLEQC448(t *testing.T) { +// validateBatchedDLEQ(t, "curve448") +// } + +// func TestBatchedDLEQInvalidLengths(t *testing.T) { +// pog, h, sk, pk, blindTokens, elems, proof, err := createBatchedProof("P384", 5) +// if err != nil { +// t.Fatal(err) +// } +// extraZ, err := pog.HashToGroup([]byte("last_element")) +// if err != nil { +// t.Fatal(err) +// } +// badBatchZ := append(elems, extraZ) + +// _, err = BatchGenerate(pog, h, sk, pk, blindTokens, badBatchZ) +// if !errors.Is(err, oerr.ErrDLEQInvalidInput) { +// t.Fatal(err) +// } +// if proof.BatchVerify(pog, h, pk, blindTokens, badBatchZ) { +// t.Fatal("verification should have failed for bad lengths") +// } +// } + +// func TestBatchedDLEQBadElement(t *testing.T) { +// pog, h, sk, pk, blindTokens, _, proof, err := createBatchedProof("P384", 5) +// if err != nil { +// t.Fatal(err) +// } + +// // create bad element +// badZ, err := pog.HashToGroup([]byte("bad_element")) +// if err != nil { +// t.Fatal(err) +// } +// badBatchZ := blindTokens +// badBatchZ[2] = badZ + +// // fail verify for bad proof +// badProof, err := BatchGenerate(pog, h, sk, pk, blindTokens, badBatchZ) +// if err != nil { +// t.Fatal(err) +// } +// if badProof.BatchVerify(pog, h, pk, blindTokens, badBatchZ) { +// t.Fatal("verification should have failed due to bad element") +// } + +// // fail verify for good proof but bad verify input +// if proof.BatchVerify(pog, h, pk, blindTokens, badBatchZ) { +// t.Fatal("verification should have failed for bad input element") +// } +// } + +// func validateDLEQ(t *testing.T, groupName string) { +// pog, h, _, pk, blindToken, elem, proof, err := createProof(groupName) +// if err != nil { +// t.Fatal(err) +// } +// if !proof.Verify(pog, h, pk, blindToken, elem) { +// t.Fatal("Proof failed to validate") +// } +// } + +// func validateBatchedDLEQ(t *testing.T, groupName string) { +// pog, h, _, pk, blindTokens, elems, proof, err := createBatchedProof(groupName, 5) +// if err != nil { +// t.Fatal(err) +// } +// if !proof.BatchVerify(pog, h, pk, blindTokens, elems) { +// t.Fatal("Batch proof failed to verify") +// } +// } + +// func generateAndEval(pog gg.PrimeOrderGroup, sk *big.Int, lbl string) (gg.GroupElement, gg.GroupElement, error) { +// blindToken, err := pog.HashToGroup([]byte(lbl)) +// if err != nil { +// return nil, nil, err +// } +// elem, err := blindToken.ScalarMult(sk) +// if err != nil { +// return nil, nil, err +// } +// return blindToken, elem, nil +// } + +// func setup(groupName string) (gg.PrimeOrderGroup, hash.Hash, *big.Int, gg.GroupElement, error) { +// ciphName := fmt.Sprintf("VOPRF-%s-HKDF-SHA512-SSWU-RO", groupName) +// ciph, err := gg.Ciphersuite{}.FromString(ciphName, ecgroup.GroupCurve{}) +// if err != nil { +// return nil, nil, nil, nil, nil, err +// } +// h := ciph.Hash() +// pog := ciph.POG() +// sk, err := pog.RandomScalar() +// if err != nil { +// return nil, nil, nil, nil, nil, err +// } +// pk, err := pog.GeneratorMult(sk) +// if err != nil { +// return nil, nil, nil, nil, nil, err +// } +// return pog, h, sk, pk, nil +// } + +// func createProof(groupName string) (gg.PrimeOrderGroup, hash.Hash, *big.Int, gg.GroupElement, gg.GroupElement, gg.GroupElement, Proof, error) { +// pog, h, sk, pk, err := setup(groupName) +// if err != nil { +// return nil, nil, nil, nil, nil, nil, Proof{}, err +// } +// blindToken, elem, err := generateAndEval(pog, sk, "random_input") +// if err != nil { +// return nil, nil, nil, nil, nil, nil, Proof{}, err +// } + +// proof, err := Generate(pog, h, sk, pk, blindToken, elem) +// if err != nil { +// return nil, nil, nil, nil, nil, nil, Proof{}, err +// } +// return pog, h, sk, pk, blindToken, elem, proof, nil +// } + +// func createBatchedProof(groupName string, n int) (gg.PrimeOrderGroup, utils.ExtractorExpander, hash.Hash, *big.Int, gg.GroupElement, []gg.GroupElement, []gg.GroupElement, Proof, error) { +// pog, h, sk, pk, err := setup(groupName) +// if err != nil { +// return nil, nil, nil, nil, nil, nil, nil, Proof{}, err +// } +// blindTokens := make([]gg.GroupElement, n) +// elems := make([]gg.GroupElement, n) +// for i := 0; i < n; i++ { +// blindTokens[i], elems[i], err = generateAndEval(pog, sk, fmt.Sprintf("random_input_%v", i)) +// if err != nil { +// return nil, nil, nil, nil, nil, nil, nil, Proof{}, err +// } +// } + +// proof, err := BatchGenerate(pog, h, sk, pk, blindTokens, elems) +// if err != nil { +// return nil, nil, nil, nil, nil, nil, nil, Proof{}, err +// } + +// return pog, h, sk, pk, blindTokens, elems, proof, nil +// } + +// /** +// * Benchmarks +// */ + +// func BenchmarkGenerateP384(b *testing.B) { +// benchGenerate(b, "P384") +// } + +// func BenchmarkGenerateP521(b *testing.B) { +// benchGenerate(b, "P521") +// } + +// func BenchmarkGenerateC448(b *testing.B) { +// benchGenerate(b, "curve448") +// } + +// func benchGenerate(b *testing.B, groupName string) { +// pog, h, sk, pk, blindToken, elem, _, err := createProof(groupName) +// if err != nil { +// b.Fatal(err) +// } + +// for i := 0; i < b.N; i++ { +// _, err := Generate(pog, h, sk, pk, blindToken, elem) +// if err != nil { +// b.Fatal(err) +// } +// } +// } + +// func BenchmarkVerifyP384(b *testing.B) { +// benchVerify(b, "P384") +// } + +// func BenchmarkVerifyP521(b *testing.B) { +// benchVerify(b, "P521") +// } + +// func BenchmarkVerifyC448(b *testing.B) { +// benchVerify(b, "Curve448") +// } + +// func benchVerify(b *testing.B, groupName string) { +// pog, h, _, pk, blindToken, elem, proof, err := createProof(groupName) +// if err != nil { +// b.Fatal(err) +// } + +// for i := 0; i < b.N; i++ { +// if !proof.Verify(pog, h, pk, blindToken, elem) { +// b.Fatal("bad verification") +// } +// } +// } + +// func BenchmarkGenerateP384_2(b *testing.B) { +// benchBatchedGenerate(b, "P384", 2) +// } + +// func BenchmarkGenerateP384_5(b *testing.B) { +// benchBatchedGenerate(b, "P384", 5) +// } + +// func BenchmarkGenerateP384_10(b *testing.B) { +// benchBatchedGenerate(b, "P384", 10) +// } + +// func BenchmarkGenerateP384_25(b *testing.B) { +// benchBatchedGenerate(b, "P384", 25) +// } + +// func BenchmarkGenerateP384_50(b *testing.B) { +// benchBatchedGenerate(b, "P384", 50) +// } + +// func BenchmarkGenerateP384_100(b *testing.B) { +// benchBatchedGenerate(b, "P384", 100) +// } + +// func BenchmarkGenerateP521_2(b *testing.B) { +// benchBatchedGenerate(b, "P521", 2) +// } + +// func BenchmarkGenerateP521_5(b *testing.B) { +// benchBatchedGenerate(b, "P521", 5) +// } + +// func BenchmarkGenerateP521_10(b *testing.B) { +// benchBatchedGenerate(b, "P521", 10) +// } + +// func BenchmarkGenerateP521_25(b *testing.B) { +// benchBatchedGenerate(b, "P521", 25) +// } + +// func BenchmarkGenerateP521_50(b *testing.B) { +// benchBatchedGenerate(b, "P521", 50) +// } + +// func BenchmarkGenerateP521_100(b *testing.B) { +// benchBatchedGenerate(b, "P521", 100) +// } + +// func BenchmarkGenerateC448_2(b *testing.B) { +// benchBatchedGenerate(b, "curve448", 2) +// } + +// func BenchmarkGenerateC448_5(b *testing.B) { +// benchBatchedGenerate(b, "curve448", 5) +// } + +// func BenchmarkGenerateC448_10(b *testing.B) { +// benchBatchedGenerate(b, "curve448", 10) +// } + +// func BenchmarkGenerateC448_25(b *testing.B) { +// benchBatchedGenerate(b, "curve448", 25) +// } + +// func BenchmarkGenerateC448_50(b *testing.B) { +// benchBatchedGenerate(b, "curve448", 50) +// } + +// func BenchmarkGenerateC448_100(b *testing.B) { +// benchBatchedGenerate(b, "curve448", 100) +// } + +// func benchBatchedGenerate(b *testing.B, groupName string, n int) { +// pog, h, sk, pk, blindTokens, elems, _, err := createBatchedProof(groupName, n) +// if err != nil { +// b.Fatal(err) +// } +// for i := 0; i < b.N; i++ { +// _, err = BatchGenerate(pog, h, sk, pk, blindTokens, elems) +// if err != nil { +// b.Fatal(err) +// } +// } +// } + +// func BenchmarkVerifyP384_2(b *testing.B) { +// benchBatchedVerify(b, "P384", 2) +// } + +// func BenchmarkVerifyP384_5(b *testing.B) { +// benchBatchedVerify(b, "P384", 5) +// } + +// func BenchmarkVerifyP384_10(b *testing.B) { +// benchBatchedVerify(b, "P384", 10) +// } + +// func BenchmarkVerifyP384_25(b *testing.B) { +// benchBatchedVerify(b, "P384", 25) +// } + +// func BenchmarkVerifyP384_50(b *testing.B) { +// benchBatchedVerify(b, "P384", 50) +// } + +// func BenchmarkVerifyP384_100(b *testing.B) { +// benchBatchedVerify(b, "P384", 100) +// } + +// func BenchmarkVerifyP521_2(b *testing.B) { +// benchBatchedVerify(b, "P521", 2) +// } + +// func BenchmarkVerifyP521_5(b *testing.B) { +// benchBatchedVerify(b, "P521", 5) +// } + +// func BenchmarkVerifyP521_10(b *testing.B) { +// benchBatchedVerify(b, "P521", 10) +// } + +// func BenchmarkVerifyP521_25(b *testing.B) { +// benchBatchedVerify(b, "P521", 25) +// } + +// func BenchmarkVerifyP521_50(b *testing.B) { +// benchBatchedVerify(b, "P521", 50) +// } + +// func BenchmarkVerifyP521_100(b *testing.B) { +// benchBatchedVerify(b, "P521", 100) +// } + +// func BenchmarkVerifyC448_2(b *testing.B) { +// benchBatchedVerify(b, "curve448", 2) +// } + +// func BenchmarkVerifyC448_5(b *testing.B) { +// benchBatchedVerify(b, "curve448", 5) +// } + +// func BenchmarkVerifyC448_10(b *testing.B) { +// benchBatchedVerify(b, "curve448", 10) +// } + +// func BenchmarkVerifyC448_25(b *testing.B) { +// benchBatchedVerify(b, "curve448", 25) +// } + +// func BenchmarkVerifyC448_50(b *testing.B) { +// benchBatchedVerify(b, "curve448", 50) +// } + +// func BenchmarkVerifyC448_100(b *testing.B) { +// benchBatchedVerify(b, "curve448", 100) +// } + +// func benchBatchedVerify(b *testing.B, groupName string, n int) { +// pog, h, _, pk, blindTokens, elems, proof, err := createBatchedProof(groupName, n) +// if err != nil { +// b.Fatal(err) +// } +// for i := 0; i < b.N; i++ { +// if !proof.BatchVerify(pog, h, pk, blindTokens, elems) { +// b.Fatal("bad batch verification") +// } +// } +// } diff --git a/go/oprf/groups/ecgroup/ec.go b/go/oprf/groups/ecgroup/ec.go index cfb65b6..5d71d6b 100644 --- a/go/oprf/groups/ecgroup/ec.go +++ b/go/oprf/groups/ecgroup/ec.go @@ -28,12 +28,24 @@ const ( CurveNameCurve448 = "curve-448" ) +func IDtoName(id int) string { + switch id { + case gg.GROUP_P384: + return CurveNameP384 + case gg.GROUP_P521: + return CurveNameP521 + case gg.GROUP_CURVE448: + return CurveNameCurve448 + } + return "Unsupported Group" +} + // GroupCurve implements the PrimeOrderGroup interface using an elliptic curve // to provide the underlying group structure. The abstraction of the curve // interface is based on the one used in draft-irtf-hash-to-curve-05. type GroupCurve struct { ops elliptic.Curve - name string + id int hash hash.Hash ee utils.ExtractorExpander byteLength int @@ -44,10 +56,10 @@ type GroupCurve struct { // New constructs a new GroupCurve object implementing the PrimeOrderGroup // interface. -func (c GroupCurve) New(name string) (gg.PrimeOrderGroup, error) { +func (c GroupCurve) New(id int) (gg.PrimeOrderGroup, error) { var gc GroupCurve - switch name { - case CurveNameP384: + switch id { + case gg.GROUP_P384: gc.ops = p384.P384() curve := gc.ops gc.encoding = EncodingWeierstrass @@ -55,7 +67,7 @@ func (c GroupCurve) New(name string) (gg.PrimeOrderGroup, error) { gc.consts.b = curve.Params().B gc.consts.isSqExp = new(big.Int).Mod(new(big.Int).Mul(new(big.Int).Sub(curve.Params().P, constants.One), new(big.Int).ModInverse(constants.Two, curve.Params().P)), curve.Params().P) gc.consts.sqrtExp = new(big.Int).Mod(new(big.Int).Mul(new(big.Int).Add(curve.Params().P, constants.One), new(big.Int).ModInverse(constants.Four, curve.Params().P)), curve.Params().P) - case CurveNameP521: + case gg.GROUP_P521: gc.ops = elliptic.P521() curve := gc.ops gc.encoding = EncodingWeierstrass @@ -63,7 +75,7 @@ func (c GroupCurve) New(name string) (gg.PrimeOrderGroup, error) { gc.consts.b = curve.Params().B gc.consts.isSqExp = new(big.Int).Mod(new(big.Int).Mul(new(big.Int).Sub(curve.Params().P, constants.One), new(big.Int).ModInverse(constants.Two, curve.Params().P)), curve.Params().P) gc.consts.sqrtExp = new(big.Int).Mod(new(big.Int).Mul(new(big.Int).Add(curve.Params().P, constants.One), new(big.Int).ModInverse(constants.Four, curve.Params().P)), curve.Params().P) - case CurveNameCurve448: + case gg.GROUP_CURVE448: gc.ops = p448.Curve448() curve := gc.ops gc.encoding = EncodingMontgomery @@ -75,7 +87,7 @@ func (c GroupCurve) New(name string) (gg.PrimeOrderGroup, error) { return nil, oerr.ErrUnsupportedGroup } gc.byteLength = (gc.ops.Params().BitSize + 7) / 8 - gc.name = name + gc.id = id gc.hash = sha512.New() gc.ee = utils.HKDFExtExp{} gc.sgn0 = utils.Sgn0LE @@ -195,7 +207,7 @@ func (c GroupCurve) ScalarToBytes(x *big.Int) []byte { } // Name returns the name of the elliptic curve that is being used (e.g. P384). -func (c GroupCurve) Name() string { return c.name } +func (c GroupCurve) Name() string { return IDtoName(c.id) } // Hash returns the name of the hash function used in conjunction with the // elliptic curve. This is also used when encoding bytes as random elements in diff --git a/go/oprf/groups/ecgroup/ec_test.go b/go/oprf/groups/ecgroup/ec_test.go index 8adbd5d..a21f548 100644 --- a/go/oprf/groups/ecgroup/ec_test.go +++ b/go/oprf/groups/ecgroup/ec_test.go @@ -5,8 +5,6 @@ import ( "errors" "fmt" "math/big" - "reflect" - "strings" "testing" "github.com/alxdavids/voprf-poc/go/oerr" @@ -16,35 +14,27 @@ import ( ) var ( - testCurves = []string{CurveNameP384, CurveNameP521, CurveNameCurve448} -) - -func TestCiphersuiteFromString(t *testing.T) { - for _, b := range []bool{false, true} { - for _, c := range testCurves { - ciphersuiteFromString(t, c, b) - } - } -} - -func TestCiphersuiteFromStringInvalidH2C(t *testing.T) { - for _, c := range testCurves { - ciphersuiteFromStringInvalidH2C(t, c) + testCiphersuites = []int{ + //gg.OPRF_CURVE25519_SHA512, + gg.OPRF_CURVE448_SHA512, + //gg.OPRF_P256_SHA512, + gg.OPRF_P384_SHA512, + gg.OPRF_P521_SHA512, } -} +) -func TestCiphersuiteFromStringInvalidHash(t *testing.T) { - for _, c := range testCurves { - ciphersuiteFromStringInvalidHash(t, c) +func TestCiphersuiteFromID(t *testing.T) { + for _, c := range testCiphersuites { + ciphersuiteFromID(t, c) } } -func TestCiphersuiteFromStringInvalidGroup(t *testing.T) { - ciphersuiteFromStringInvalidGroup(t, "P-256") +func TestCiphersuiteFromIDInvalid(t *testing.T) { + ciphersuiteFromIDInvalid(t, gg.OPRF_INVALID_CIPHERSUITE) } func TestGroupCurveEncodingP384(t *testing.T) { - curve := initCurve(t, CurveNameP384) + curve := initCurve(t, gg.GROUP_P384) _, err := curveEncoding(curve) if err != nil { t.Fatal(err) @@ -52,7 +42,7 @@ func TestGroupCurveEncodingP384(t *testing.T) { } func TestGroupCurvePointSerializationP384(t *testing.T) { - curve := initCurve(t, CurveNameP384) + curve := initCurve(t, gg.GROUP_P384) P, err := curveEncoding(curve) if err != nil { t.Fatal(err) @@ -65,7 +55,7 @@ func TestGroupCurvePointSerializationP384(t *testing.T) { } func TestGroupCurvePointSerializationWithCompressionP384(t *testing.T) { - curve := initCurve(t, CurveNameP384) + curve := initCurve(t, gg.GROUP_P384) P, err := curveEncoding(curve) if err != nil { t.Fatal(err) @@ -79,7 +69,7 @@ func TestGroupCurvePointSerializationWithCompressionP384(t *testing.T) { } func TestGroupCurveEncodingP521(t *testing.T) { - curve := initCurve(t, CurveNameP521) + curve := initCurve(t, gg.GROUP_P521) _, err := curveEncoding(curve) if err != nil { t.Fatal(err) @@ -87,7 +77,7 @@ func TestGroupCurveEncodingP521(t *testing.T) { } func TestGroupCurvePointSerializationP521(t *testing.T) { - curve := initCurve(t, CurveNameP521) + curve := initCurve(t, gg.GROUP_P521) P, err := curveEncoding(curve) if err != nil { t.Fatal(err) @@ -100,7 +90,7 @@ func TestGroupCurvePointSerializationP521(t *testing.T) { } func TestGroupCurvePointSerializationWithCompressionP521(t *testing.T) { - curve := initCurve(t, CurveNameP521) + curve := initCurve(t, gg.GROUP_P521) P, err := curveEncoding(curve) if err != nil { t.Fatal(err) @@ -114,7 +104,7 @@ func TestGroupCurvePointSerializationWithCompressionP521(t *testing.T) { } func TestGroupCurvePointSerializationC448(t *testing.T) { - curve := initCurve(t, CurveNameCurve448) + curve := initCurve(t, gg.GROUP_CURVE448) P, err := curveEncoding(curve) if err != nil { t.Fatal(err) @@ -127,7 +117,7 @@ func TestGroupCurvePointSerializationC448(t *testing.T) { } func TestGroupCurvePointSerializationWithCompressionC448(t *testing.T) { - curve := initCurve(t, CurveNameCurve448) + curve := initCurve(t, gg.GROUP_CURVE448) P, err := curveEncoding(curve) if err != nil { t.Fatal(err) @@ -141,29 +131,29 @@ func TestGroupCurvePointSerializationWithCompressionC448(t *testing.T) { } func TestPointAdditionP384(t *testing.T) { - checkPointAddition(t, CurveNameP384) + checkPointAddition(t, gg.GROUP_P384) } func TestPointAdditionP521(t *testing.T) { - checkPointAddition(t, CurveNameP521) + checkPointAddition(t, gg.GROUP_P521) } func TestPointEqualityP384(t *testing.T) { - checkPointEquality(t, CurveNameP384) + checkPointEquality(t, gg.GROUP_P384) } func TestPointEqualityP521(t *testing.T) { - checkPointEquality(t, CurveNameP521) + checkPointEquality(t, gg.GROUP_P521) } func TestPointEqualityFailsOnBadGroups(t *testing.T) { - p384 := initCurve(t, CurveNameP384) + p384 := initCurve(t, gg.GROUP_P384) P, err := curveEncoding(p384) if err != nil { t.Fatal(err) } - p521 := initCurve(t, CurveNameP521) + p521 := initCurve(t, gg.GROUP_P521) Q, err := curveEncoding(p521) if err != nil { t.Fatal(err) @@ -172,14 +162,14 @@ func TestPointEqualityFailsOnBadGroups(t *testing.T) { } func TestPointEqualityFailsOnInvalidCallerPoint(t *testing.T) { - p384 := initCurve(t, CurveNameP384) + p384 := initCurve(t, gg.GROUP_P384) P, err := curveEncoding(p384) if err != nil { t.Fatal(err) } P.X = constants.MinusOne - p521 := initCurve(t, CurveNameP521) + p521 := initCurve(t, gg.GROUP_P521) Q, err := curveEncoding(p521) if err != nil { t.Fatal(err) @@ -188,13 +178,13 @@ func TestPointEqualityFailsOnInvalidCallerPoint(t *testing.T) { } func TestPointEqualityFailsOnInvalidInputPoint(t *testing.T) { - p384 := initCurve(t, CurveNameP384) + p384 := initCurve(t, gg.GROUP_P384) P, err := curveEncoding(p384) if err != nil { t.Fatal(err) } - p521 := initCurve(t, CurveNameP521) + p521 := initCurve(t, gg.GROUP_P521) Q, err := curveEncoding(p521) if err != nil { t.Fatal(err) @@ -203,8 +193,8 @@ func TestPointEqualityFailsOnInvalidInputPoint(t *testing.T) { assert.False(t, P.Equal(Q)) } -func checkPointAddition(t *testing.T, curveName string) { - curve := initCurve(t, curveName) +func checkPointAddition(t *testing.T, curveID int) { + curve := initCurve(t, curveID) P, err := curveEncoding(curve) if err != nil { t.Fatal(err) @@ -244,8 +234,8 @@ func checkPointAddition(t *testing.T, curveName string) { assert.True(t, xyP.Equal(xP1yP2)) } -func checkPointEquality(t *testing.T, curveName string) { - curve := initCurve(t, curveName) +func checkPointEquality(t *testing.T, curveID int) { + curve := initCurve(t, curveID) P, err := curveEncoding(curve) if err != nil { t.Fatal(err) @@ -254,59 +244,22 @@ func checkPointEquality(t *testing.T, curveName string) { assert.True(t, P.Equal(Q)) } -func ciphersuiteFromString(t *testing.T, groupName string, verifiable bool) { - var s, ciphName string - - if verifiable { - s = "V" - } - - if groupName == CurveNameP384 || groupName == CurveNameP521 { - ciphName = fmt.Sprintf("%sOPRF-%s-HKDF-SHA512-SSWU-RO", s, strings.ReplaceAll(groupName, "-", "")) - } else if groupName == CurveNameCurve448 { - ciphName = fmt.Sprintf("%sOPRF-%s-HKDF-SHA512-ELL2-RO", s, strings.ReplaceAll(groupName, "-", "")) - } - - ciph, err := gg.Ciphersuite{}.FromString(ciphName, GroupCurve{}) +func ciphersuiteFromID(t *testing.T, id int) { + ciph, err := gg.Ciphersuite{}.FromID(id, GroupCurve{}) if err != nil { t.Fatal(err) } - assert.Equal(t, ciph.Name(), ciphName) - assert.Equal(t, ciph.H3(), sha512.New()) - assert.Equal(t, ciph.POG().Name(), groupName) - assert.Equal(t, ciph.Verifiable(), verifiable) - if verifiable { - assert.Equal(t, reflect.TypeOf(ciph.H2()).Name(), "HKDFExtExp") - } else { - assert.Equal(t, ciph.H2(), nil) - } -} - -func ciphersuiteFromStringInvalidH2C(t *testing.T, groupName string) { - ciphName := fmt.Sprintf("OPRF-%s-HKDF-SHA512-ELL2", strings.ReplaceAll(groupName, "-", "")) - _, err := gg.Ciphersuite{}.FromString(ciphName, GroupCurve{}) - if !errors.Is(err, oerr.ErrUnsupportedH2C) { - t.Fatal("Error didn't occur") - } + assert.Equal(t, ciph.ID(), id) + assert.Equal(t, ciph.Hash(), sha512.New()) } -func ciphersuiteFromStringInvalidHash(t *testing.T, groupName string) { - ciphName := fmt.Sprintf("OPRF-%s-HKDF-SHA256-SSWU-RO", strings.ReplaceAll(groupName, "-", "")) - _, err := gg.Ciphersuite{}.FromString(ciphName, GroupCurve{}) - if !errors.Is(err, oerr.ErrUnsupportedHash) { +func ciphersuiteFromIDInvalid(t *testing.T, id int) { + _, err := gg.Ciphersuite{}.FromID(id, GroupCurve{}) + if !errors.Is(err, oerr.ErrUnsupportedCiphersuite) { t.Fatal("Error didn't occur") } } - -func ciphersuiteFromStringInvalidGroup(t *testing.T, groupName string) { - ciphName := fmt.Sprintf("OPRF-%s-HKDF-SHA512-SSWU-RO", strings.ReplaceAll(groupName, "-", "")) - _, err := gg.Ciphersuite{}.FromString(ciphName, GroupCurve{}) - if !errors.Is(err, oerr.ErrUnsupportedGroup) { - t.Fatal("Error didn't occur") - } -} - func curveEncoding(curve GroupCurve) (Point, error) { P, err := curve.HashToGroup([]byte("test")) if err != nil { @@ -354,8 +307,8 @@ func checkSerialize(curve GroupCurve, P Point) error { return nil } -func initCurve(t *testing.T, curveName string) GroupCurve { - g, err := GroupCurve{}.New(curveName) +func initCurve(t *testing.T, curveID int) GroupCurve { + g, err := GroupCurve{}.New(curveID) if err != nil { t.Fatal(err) } diff --git a/go/oprf/groups/ecgroup/h2c.go b/go/oprf/groups/ecgroup/h2c.go index 76c4957..b7cd3c0 100644 --- a/go/oprf/groups/ecgroup/h2c.go +++ b/go/oprf/groups/ecgroup/h2c.go @@ -4,6 +4,7 @@ import ( "math/big" "github.com/alxdavids/voprf-poc/go/oerr" + gg "github.com/alxdavids/voprf-poc/go/oprf/groups" h2c "github.com/armfazh/h2c-go-ref" ) @@ -41,12 +42,12 @@ func (h hasher2point) HashToScalar(msg []byte) (*big.Int, error) { func getH2CSuiteWithDST(gc GroupCurve, dst []byte) (HashToPoint, error) { var suite h2c.SuiteID - switch gc.Name() { - case CurveNameP384: + switch gc.id { + case gg.GROUP_P384: suite = h2c.P384_XMDSHA512_SSWU_RO_ - case CurveNameP521: + case gg.GROUP_P521: suite = h2c.P521_XMDSHA512_SSWU_RO_ - case CurveNameCurve448: + case gg.GROUP_CURVE448: suite = h2c.Curve448_XMDSHA512_ELL2_RO_ default: return nil, oerr.ErrUnsupportedGroup @@ -61,12 +62,12 @@ func getH2CSuiteWithDST(gc GroupCurve, dst []byte) (HashToPoint, error) { func getH2CSuite(gc GroupCurve) (HashToPoint, error) { var suite h2c.SuiteID - switch gc.Name() { - case CurveNameP384: + switch gc.id { + case gg.GROUP_P384: suite = h2c.P384_XMDSHA512_SSWU_RO_ - case CurveNameP521: + case gg.GROUP_P521: suite = h2c.P521_XMDSHA512_SSWU_RO_ - case CurveNameCurve448: + case gg.GROUP_CURVE448: suite = h2c.Curve448_XMDSHA512_ELL2_RO_ default: return nil, oerr.ErrUnsupportedGroup diff --git a/go/oprf/groups/ecgroup/h2c_test.go b/go/oprf/groups/ecgroup/h2c_test.go index 206bcab..2ed66e8 100644 --- a/go/oprf/groups/ecgroup/h2c_test.go +++ b/go/oprf/groups/ecgroup/h2c_test.go @@ -10,6 +10,8 @@ import ( "math/big" "strings" "testing" + + gg "github.com/alxdavids/voprf-poc/go/oprf/groups" ) type hashToCurveTestVectors struct { @@ -28,7 +30,7 @@ type expectedPoint struct { } func TestHashToCurveP384(t *testing.T) { - curve := initCurve(t, CurveNameP384) + curve := initCurve(t, gg.GROUP_CURVE448) buf, err := ioutil.ReadFile("../../../../test-vectors/hash-to-curve/P384_XMD:SHA-512_SSWU_RO_.json") if err != nil { t.Fatal(err) @@ -45,7 +47,7 @@ func TestHashToCurveP384(t *testing.T) { } func TestHashToCurveP521(t *testing.T) { - curve := initCurve(t, CurveNameP521) + curve := initCurve(t, gg.GROUP_P521) buf, err := ioutil.ReadFile("../../../../test-vectors/hash-to-curve/P521_XMD:SHA-512_SSWU_RO_.json") if err != nil { t.Fatal(err) @@ -62,7 +64,7 @@ func TestHashToCurveP521(t *testing.T) { } func TestHashToCurve448(t *testing.T) { - curve := initCurve(t, CurveNameCurve448) + curve := initCurve(t, gg.GROUP_CURVE448) buf, err := ioutil.ReadFile("../../../../test-vectors/hash-to-curve/curve448_XMD:SHA-512_ELL2_RO_.json") if err != nil { t.Fatal(err) @@ -122,15 +124,15 @@ func performHashToCurve(curve GroupCurve, testVectors hashToCurveTestVectors) er } func BenchmarkHashToCurveP384(b *testing.B) { - benchmarkHashToCurve(b, benchInitCurve(b, CurveNameP384)) + benchmarkHashToCurve(b, benchInitCurve(b, gg.GROUP_CURVE448)) } func BenchmarkHashToCurveP521(b *testing.B) { - benchmarkHashToCurve(b, benchInitCurve(b, CurveNameP521)) + benchmarkHashToCurve(b, benchInitCurve(b, gg.GROUP_P521)) } func BenchmarkHashToCurveC448(b *testing.B) { - benchmarkHashToCurve(b, benchInitCurve(b, CurveNameCurve448)) + benchmarkHashToCurve(b, benchInitCurve(b, gg.GROUP_CURVE448)) } func benchmarkHashToCurve(b *testing.B, curve GroupCurve) { @@ -153,8 +155,8 @@ func benchmarkHashToCurve(b *testing.B, curve GroupCurve) { } } -func benchInitCurve(b *testing.B, curveName string) GroupCurve { - gg, err := GroupCurve{}.New(curveName) +func benchInitCurve(b *testing.B, curveID int) GroupCurve { + gg, err := GroupCurve{}.New(curveID) if err != nil { b.Fatal(err) } diff --git a/go/oprf/groups/group.go b/go/oprf/groups/group.go index 92cc507..ea2e27b 100644 --- a/go/oprf/groups/group.go +++ b/go/oprf/groups/group.go @@ -1,16 +1,32 @@ package groups import ( - "crypto/sha512" "hash" "math/big" - "reflect" - "strings" "github.com/alxdavids/voprf-poc/go/oerr" "github.com/alxdavids/voprf-poc/go/oprf/utils" ) +// IDs for supported ciphersuites. +const ( + OPRF_CURVE25519_SHA512 = iota + 1 + OPRF_CURVE448_SHA512 + OPRF_P256_SHA512 + OPRF_P384_SHA512 + OPRF_P521_SHA512 + + OPRF_INVALID_CIPHERSUITE = 255 +) + +const ( + GROUP_CURVE25519 = iota + 1 + GROUP_CURVE448 + GROUP_P256 + GROUP_P384 + GROUP_P521 +) + // Ciphersuite corresponds to the OPRF ciphersuite that is chosen. The // Ciphersuite object determines the prime-order group (pog) that is used for // performing the (V)OPRF operations, along with the different hash function @@ -21,104 +37,52 @@ import ( // "P521"], extractor-expander ∈ ["HKDF"], hash_func ∈ ["SHA-512"], h2c-name ∈ // ["SSWU-RO"]. type Ciphersuite struct { - // name of the ciphersuite - name string + // id of the ciphersuite + id int // PrimeOrderGroup instantiation for performing the OPRF operations. pog PrimeOrderGroup - // TODO: replace hash functions with single Hash + // hash function hash hash.Hash - - // A hash function that is used for generating the final output derived from - // the OPRF protocol - hash1 hash.Hash - - // A hash function that is modeled as a random oracle and expands inputs - // into random outputs of sufficient length - hash2 utils.ExtractorExpander - - // A generic hash function that is typically used as the base underlying - // hash function when instantiating the other hash functionalities. We - // currently only support SHA-512 - hashGeneric hash.Hash - - // Indicates whether the ciphersuite supports verifiable functionality - verifiable bool } -// FromString creates a Ciphersuite object can be created from a string of the -// form defined above. -func (c Ciphersuite) FromString(s string, pog PrimeOrderGroup) (Ciphersuite, error) { - split := strings.SplitN(s, "-", 5) - - // construct the PrimeOrderGroup object +// FromID creates a Ciphersuite object can be created from a +// ciphersuite ID. +func (c Ciphersuite) FromID(id int, pog PrimeOrderGroup) (Ciphersuite, error) { + // TODO: construct the PrimeOrderGroup object var pogNew PrimeOrderGroup var err error - switch split[1] { - case "P384": - pogNew, err = pog.New("P-384") - case "P521": - pogNew, err = pog.New("P-521") - case "curve448": - pogNew, err = pog.New("curve-448") + switch id { + case OPRF_CURVE25519_SHA512: + pogNew, err = pog.New(GROUP_CURVE25519) + case OPRF_CURVE448_SHA512: + pogNew, err = pog.New(GROUP_CURVE448) + case OPRF_P521_SHA512: + pogNew, err = pog.New(GROUP_P521) + case OPRF_P256_SHA512: + pogNew, err = pog.New(GROUP_P256) + case OPRF_P384_SHA512: + pogNew, err = pog.New(GROUP_P384) default: - return Ciphersuite{}, oerr.ErrUnsupportedGroup + return Ciphersuite{}, oerr.ErrUnsupportedCiphersuite } if err != nil { return Ciphersuite{}, err } - // Check ExtractorExpander{} is supported (only HKDF currently) - switch split[2] { - case "HKDF": - if reflect.TypeOf(pogNew.EE()).Name() != "HKDFExtExp" { - return Ciphersuite{}, oerr.ErrUnsupportedEE - } - default: - return Ciphersuite{}, oerr.ErrUnsupportedEE - } - - // check hash function support - switch split[3] { - case "SHA512": - if reflect.DeepEqual(pog.Hash(), sha512.New()) { - // do a quick check to see if the hash function is the same - return Ciphersuite{}, oerr.ErrUnsupportedHash - } - default: - return Ciphersuite{}, oerr.ErrUnsupportedHash - } - - // check hash-to-curve support - switch split[4] { - case "SSWU-RO", "ELL2-RO": - // do nothing - break - default: - return Ciphersuite{}, oerr.ErrUnsupportedH2C - } - - // derive Ciphersuite object - hashGeneric := pogNew.Hash() - var h2 utils.ExtractorExpander - verifiable := false - if split[0] == "VOPRF" { - verifiable = true - h2 = pogNew.EE() - } return Ciphersuite{ - name: s, - pog: pogNew, - hash1: hashGeneric, - hash2: h2, - hashGeneric: hashGeneric, - verifiable: verifiable, + id: id, + pog: pogNew, + hash: pogNew.Hash(), }, nil } // Name returns the name of the Ciphersuite -func (c Ciphersuite) Name() string { return c.name } +func (c Ciphersuite) Name() string { return IDtoName(c.id) } + +// ID returns the ID of the Ciphersuite +func (c Ciphersuite) ID() int { return c.id } // Hash returns the hash function specified in Ciphersuite func (c Ciphersuite) Hash() hash.Hash { @@ -126,27 +90,24 @@ func (c Ciphersuite) Hash() hash.Hash { return c.hash } -// H1 returns the hash1 function specified in Ciphersuite -func (c Ciphersuite) H1() hash.Hash { - c.hash1.Reset() - return c.hash1 -} - -// H2 returns the hash2 function specified in Ciphersuite -func (c Ciphersuite) H2() utils.ExtractorExpander { return c.hash2 } - -// H3 returns the hashGeneric function specified in Ciphersuite -func (c Ciphersuite) H3() hash.Hash { - c.hashGeneric.Reset() - return c.hashGeneric -} - // POG returns the PrimeOrderGroup for the current Ciphersuite func (c Ciphersuite) POG() PrimeOrderGroup { return c.pog } -// Verifiable returns a bool indicating whether the ciphersuite corresponds to a -// VOPRF or not -func (c Ciphersuite) Verifiable() bool { return c.verifiable } +func IDtoName(id int) string { + switch id { + case OPRF_CURVE25519_SHA512: + return "OPRF_CURVE25519_SHA512" + case OPRF_CURVE448_SHA512: + return "OPRF_CURVE448_SHA512" + case OPRF_P256_SHA512: + return "OPRF_P256_SHA512" + case OPRF_P384_SHA512: + return "OPRF_P384_SHA512" + case OPRF_P521_SHA512: + return "OPRF_P521_SHA512" + } + return "Unsupported Ciphersuite" +} // PrimeOrderGroup is an interface that defines operations within additive // groups of prime order. This is the setting in which the (V)OPRF operations @@ -156,7 +117,7 @@ func (c Ciphersuite) Verifiable() bool { return c.verifiable } // prime-order-groups derived from the NIST P384 and P521 curves are supported. type PrimeOrderGroup interface { // Creates a new PrimeOrderGroup object - New(string) (PrimeOrderGroup, error) + New(int) (PrimeOrderGroup, error) // Returns the identifying name of the group Name() string diff --git a/go/oprf/oprf.go b/go/oprf/oprf.go index 504d481..103238a 100644 --- a/go/oprf/oprf.go +++ b/go/oprf/oprf.go @@ -5,15 +5,18 @@ import ( "encoding/hex" "encoding/json" "errors" - "fmt" "math/big" "github.com/alxdavids/voprf-poc/go/oerr" gg "github.com/alxdavids/voprf-poc/go/oprf/groups" - "github.com/alxdavids/voprf-poc/go/oprf/groups/dleq" "github.com/alxdavids/voprf-poc/go/oprf/utils" ) +const ( + modeBase int = 0 + modeVerifiable = 1 +) + // PublicKey represents a commitment to a given secret key that is made public // during the OPRF protocol type PublicKey gg.GroupElement @@ -49,7 +52,21 @@ type Token struct { Blind *big.Int } -type Proof [2]*big.Int +type Proof struct { + pog gg.PrimeOrderGroup + C, S *big.Int +} + +// Serialize takes the values of the proof object and converts them into bytes +func (proof Proof) Serialize() [][]byte { + return [][]byte{proof.pog.ScalarToBytes(proof.C), proof.pog.ScalarToBytes(proof.S)} +} + +// Deserialize takes the provided bytes and converts them into a valid Proof +// object +func (proof Proof) Deserialize(pog gg.PrimeOrderGroup, proofBytes [][]byte) Proof { + return Proof{pog: pog, C: new(big.Int).SetBytes(proofBytes[0]), S: new(big.Int).SetBytes(proofBytes[1])} +} // Evaluation corresponds to the output object of a (V)OPRF evaluation. // In the case of an OPRF, the object only consists of the output group element. For a @@ -64,7 +81,7 @@ type Evaluation struct { // VOPRF, it also consists of a proof object type BatchedEvaluation struct { Elements []gg.GroupElement - Proof dleq.Proof + Proof Proof } // ToJSON returns a formatted string containing the contents of the Evaluation @@ -94,7 +111,8 @@ func (ev BatchedEvaluation) ToJSON(verifiable bool) ([]byte, error) { // protocol type Participant interface { Ciphersuite() gg.Ciphersuite - Setup(string, gg.PrimeOrderGroup) (Participant, error) + Setup(int, gg.PrimeOrderGroup) (Participant, error) + SetupVerifiable(int, gg.PrimeOrderGroup) (Participant, error) Blind([]byte) (*Token, gg.GroupElement, error) Unblind(Evaluation, *Token, gg.GroupElement) (gg.GroupElement, error) BatchUnblind(BatchedEvaluation, []*Token, []gg.GroupElement) ([]gg.GroupElement, error) @@ -106,9 +124,10 @@ type Participant interface { // Server implements the OPRF interface for processing the server-side // operations of the OPRF protocol type Server struct { - contextString string + contextString []byte ciph gg.Ciphersuite sk SecretKey + verifiable bool } // Ciphersuite returns the Ciphersuite object associated with the Server @@ -122,8 +141,18 @@ func (s Server) SetSecretKey(sk SecretKey) Server { s.sk = sk; return s } // Setup is run by the server, it generates a SecretKey object based on the // choice of ciphersuite that is made -func (s Server) Setup(ciphersuite string, pogInit gg.PrimeOrderGroup) (Participant, error) { - ciph, err := gg.Ciphersuite{}.FromString(ciphersuite, pogInit) +func (s Server) Setup(ciphersuiteID int, pogInit gg.PrimeOrderGroup) (Participant, error) { + s.verifiable = false + return s.setup(ciphersuiteID, pogInit, modeBase) +} + +func (s Server) SetupVerifiable(ciphersuiteID int, pogInit gg.PrimeOrderGroup) (Participant, error) { + s.verifiable = true + return s.setup(ciphersuiteID, pogInit, modeVerifiable) +} + +func (s Server) setup(ciphersuiteID int, pogInit gg.PrimeOrderGroup, mode int) (Participant, error) { + ciph, err := gg.Ciphersuite{}.FromID(ciphersuiteID, pogInit) if err != nil { return nil, err } @@ -135,13 +164,26 @@ func (s Server) Setup(ciphersuite string, pogInit gg.PrimeOrderGroup) (Participa s.ciph = ciph s.sk = sk + + modeString, err := utils.I2osp(mode, 1) + if err != nil { + return nil, err + } + + idString, err := utils.I2osp(int(ciph.ID()), 2) + if err != nil { + return nil, err + } + + s.contextString = append(modeString, idString...) + return s, nil } // Evaluate computes the Server-side evaluation of the (V)OPRF using a secret key // and a provided group element func (s Server) Evaluate(blindToken gg.GroupElement) (Evaluation, error) { - if !s.Ciphersuite().Verifiable() { + if !s.Verifiable() { return s.oprfEval(blindToken) } return s.voprfEval(blindToken) @@ -150,16 +192,16 @@ func (s Server) Evaluate(blindToken gg.GroupElement) (Evaluation, error) { // BatchEvaluate computes the Server-side evaluation of the batched (V)OPRF using // a secret key and provided group elements func (s Server) BatchEvaluate(blindTokens []gg.GroupElement) (BatchedEvaluation, error) { - if !s.Ciphersuite().Verifiable() { + if !s.Verifiable() { return s.oprfBatchEval(blindTokens) } return s.voprfBatchEval(blindTokens) } -// FixedBatchEval computes the Server-side evaluation of the (V)OPRF with fixed DLEQ +// FixedEval computes the Server-side evaluation of the (V)OPRF with fixed DLEQ // values (for testing) func (s Server) FixedEval(blindToken gg.GroupElement, tDleq string) (Evaluation, error) { - if !s.Ciphersuite().Verifiable() { + if !s.Verifiable() { return s.oprfEval(blindToken) } return s.voprfFixedEval(blindToken, tDleq) @@ -168,7 +210,7 @@ func (s Server) FixedEval(blindToken gg.GroupElement, tDleq string) (Evaluation, // FixedBatchEval computes the Server-side evaluation of the (V)OPRF with fixed DLEQ // values (for testing) func (s Server) FixedBatchEval(blindTokens []gg.GroupElement, tDleq string) (BatchedEvaluation, error) { - if !s.Ciphersuite().Verifiable() { + if !s.Verifiable() { return s.oprfBatchEval(blindTokens) } return s.voprfFixedBatchEval(blindTokens, tDleq) @@ -207,7 +249,7 @@ func (s Server) voprfEval(blindToken gg.GroupElement) (Evaluation, error) { return Evaluation{}, err } - eval.Proof = *proof + eval.Proof = proof return eval, nil } @@ -220,13 +262,11 @@ func (s Server) voprfBatchEval(blindTokens []gg.GroupElement) (BatchedEvaluation } elems := eval.Elements - ciph := s.Ciphersuite() - sk := s.SecretKey() - var proof dleq.Proof + var proof Proof if len(blindTokens) == 1 { - proof, err = dleq.Generate(ciph.POG(), ciph.H2(), ciph.H3(), sk.K, sk.PubKey, blindTokens[0], elems[0]) + proof, err = s.GenerateProof(blindTokens[0], elems[0]) } else { - proof, err = dleq.BatchGenerate(ciph.POG(), ciph.H2(), ciph.H3(), sk.K, sk.PubKey, blindTokens, elems) + proof, err = s.BatchGenerateProof(blindTokens, elems) } if err != nil { return BatchedEvaluation{}, err @@ -242,12 +282,12 @@ func (s Server) voprfFixedEval(blindToken gg.GroupElement, tDleq string) (Evalua return Evaluation{}, err } - // t, ok := new(big.Int).SetString(tDleq, 16) - // if !ok { - // panic("Bad hex value specified for fixed DLEQ value") - // } + t, ok := new(big.Int).SetString(tDleq, 16) + if !ok { + panic("Bad hex value specified for fixed DLEQ value") + } - proof, err := s.FixedGenerateProof(blindToken, eval.Element) + proof, err := s.FixedGenerateProof(blindToken, eval.Element, t) if err != nil { return Evaluation{}, err } @@ -265,18 +305,12 @@ func (s Server) voprfFixedBatchEval(blindTokens []gg.GroupElement, tDleq string) } elems := eval.Elements - ciph := s.Ciphersuite() - sk := s.SecretKey() t, ok := new(big.Int).SetString(tDleq, 16) if !ok { panic("Bad hex value specified for fixed DLEQ value") } - var proof dleq.Proof - if len(blindTokens) == 1 { - proof, err = dleq.FixedGenerate(ciph.POG(), ciph.H2(), ciph.H3(), sk.K, sk.PubKey, blindTokens[0], elems[0], t) - } else { - proof, err = dleq.FixedBatchGenerate(ciph.POG(), ciph.H2(), ciph.H3(), sk.K, sk.PubKey, blindTokens, elems, t) - } + + proof, err := s.FixedBatchGenerateProof(blindTokens, elems, t) if err != nil { return BatchedEvaluation{}, err } @@ -284,42 +318,52 @@ func (s Server) voprfFixedBatchEval(blindTokens []gg.GroupElement, tDleq string) return BatchedEvaluation{Elements: elems, Proof: proof}, nil } -func (s Server) GenerateProof(blindToken, elem gg.GroupElement) (*Proof, error) { +func (s Server) GenerateProof(blindToken, elem gg.GroupElement) (Proof, error) { pog := s.ciph.POG() - G := pog.Generator() + r, err := pog.RandomScalar() + if err != nil { + return Proof{}, err + } + + return s.FixedGenerateProof(blindToken, elem, r) +} + +func (s Server) FixedGenerateProof(blindToken, elem gg.GroupElement, r *big.Int) (Proof, error) { blindTokens := gg.GroupElementList{blindToken} elements := gg.GroupElementList{elem} M, Z, err := s.ComputeComposites(blindTokens, elements) if err != nil { - return nil, err + return Proof{}, err } - r, err := pog.RandomScalar() - if err != nil { - return nil, err - } + return s.fixedGenerateProofInner(M, Z, r) +} + +func (s Server) fixedGenerateProofInner(M, Z gg.GroupElement, r *big.Int) (Proof, error) { + pog := s.ciph.POG() + G := pog.Generator() rG, err := G.ScalarMult(r) if err != nil { - return nil, err + return Proof{}, err } rM, err := M.ScalarMult(r) if err != nil { - return nil, err + return Proof{}, err } - challengeDST := "RFCXXXX-challenge-" + s.contextString + challengeDST := append([]byte("RFCXXXX-challenge-"), s.contextString...) h2Input, err := utils.ByteSliceLengthPrefixed(G, s.sk.PubKey, M, Z, rG, rM, challengeDST) if err != nil { - return nil, err + return Proof{}, err } c1, err := pog.HashToScalar(h2Input) if err != nil { - return nil, err + return Proof{}, err } c2 := big.NewInt(1) @@ -328,19 +372,43 @@ func (s Server) GenerateProof(blindToken, elem gg.GroupElement) (*Proof, error) c2.Sub(r, c2) c2.Mod(c2, pog.Order()) - return &Proof{c1, c2}, nil + return Proof{pog, c1, c2}, nil +} + +func (s Server) BatchGenerateProof(blindTokens, elems []gg.GroupElement) (Proof, error) { + pog := s.ciph.POG() + + r, err := pog.RandomScalar() + if err != nil { + return Proof{}, err + } + + return s.FixedBatchGenerateProof(blindTokens, elems, r) +} + +func (s Server) FixedBatchGenerateProof(blindTokens, elements []gg.GroupElement, r *big.Int) (Proof, error) { + M, Z, err := s.ComputeComposites(blindTokens, elements) + if err != nil { + return Proof{}, err + } + + return s.fixedGenerateProofInner(M, Z, r) +} + +func (s Server) Verifiable() bool { + return s.verifiable } func (s Server) ComputeComposites(blindTokens gg.GroupElementList, elements gg.GroupElementList) (M gg.GroupElement, Z gg.GroupElement, err error) { return computeComposites(s.ciph.POG(), s.contextString, s.sk.PubKey, blindTokens, elements) } -func computeComposites(pog gg.PrimeOrderGroup, contextString string, pubKey PublicKey, +func computeComposites(pog gg.PrimeOrderGroup, contextString []byte, pubKey PublicKey, blindTokens gg.GroupElementList, elements gg.GroupElementList) (M gg.GroupElement, Z gg.GroupElement, err error) { G := pog.Generator() - seedDST := "RFCXXXX-seed-" + contextString - compositeDST := "RFCXXXX-composite-" + contextString + seedDST := append([]byte("RFCXXXX-seed-"), contextString...) + compositeDST := append([]byte("RFCXXXX-composite-"), contextString...) h1Input, err := utils.ByteSliceLengthPrefixed(G, pubKey, blindTokens, elements, seedDST) if err != nil { @@ -404,10 +472,6 @@ func computeComposites(pog gg.PrimeOrderGroup, contextString string, pubKey Publ return M, Z, nil } -func (s Server) FixedGenerateProof(blindToken, elem gg.GroupElement) (Proof, error) { - return Proof{}, errors.New("not implemented") -} - // Blind is unimplemented for the server func (s Server) Blind(x []byte) (*Token, gg.GroupElement, error) { return nil, nil, oerr.ErrOPRFUnimplementedFunctionServer @@ -431,9 +495,10 @@ func (s Server) Finalize(token *Token, unblindedToken gg.GroupElement, info []by // Client implements the OPRF interface for processing the client-side // operations of the OPRF protocol type Client struct { - contextString string + contextString []byte ciph gg.Ciphersuite pk PublicKey + verifiable bool } // Ciphersuite returns the Ciphersuite object associated with the Client @@ -447,12 +512,35 @@ func (c Client) PublicKey() PublicKey { return c.pk } func (c Client) SetPublicKey(pk PublicKey) Client { c.pk = pk; return c } // Setup associates the client with a ciphersuite object -func (c Client) Setup(ciphersuite string, pogInit gg.PrimeOrderGroup) (Participant, error) { - ciph, err := gg.Ciphersuite{}.FromString(ciphersuite, pogInit) +func (c Client) Setup(ciphersuiteID int, pogInit gg.PrimeOrderGroup) (Participant, error) { + c.verifiable = false + return c.setup(ciphersuiteID, pogInit, modeBase) +} + +func (c Client) SetupVerifiable(ciphersuiteID int, pogInit gg.PrimeOrderGroup) (Participant, error) { + c.verifiable = true + return c.setup(ciphersuiteID, pogInit, modeVerifiable) +} + +func (c Client) setup(ciphersuiteID int, pogInit gg.PrimeOrderGroup, mode int) (Participant, error) { + ciph, err := gg.Ciphersuite{}.FromID(ciphersuiteID, pogInit) + if err != nil { + return nil, err + } + + modeString, err := utils.I2osp(mode, 1) + if err != nil { + return nil, err + } + + idString, err := utils.I2osp(int(ciph.ID()), 2) if err != nil { return nil, err } + c.ciph = ciph + c.contextString = append(modeString, idString...) + return c, nil } @@ -506,7 +594,7 @@ func (c Client) BlindFixed(x []byte, blind *big.Int) (gg.GroupElement, gg.GroupE // BatchUnblind returns the unblinded group element N = r^{-1}*elem if the DLEQ proof // check passes (proof check is omitted if the ciphersuite is not verifiable) func (c Client) Unblind(ev Evaluation, token *Token, blindToken gg.GroupElement) (gg.GroupElement, error) { - if !c.ciph.Verifiable() { + if !c.Verifiable() { return c.oprfUnblind(ev, token.Blind) } return c.voprfUnblind(ev, token, blindToken) @@ -520,7 +608,7 @@ func (c Client) BatchUnblind(ev BatchedEvaluation, tokens []*Token, blindTokens if len(ev.Elements) != len(blindTokens) { return nil, oerr.ErrClientInconsistentResponse } - if !c.ciph.Verifiable() { + if !c.Verifiable() { return c.oprfBatchUnblind(ev, tokens) } return c.voprfBatchUnblind(ev, tokens, blindTokens) @@ -540,19 +628,14 @@ func (c Client) voprfUnblind(ev Evaluation, token *Token, blindToken gg.GroupEle // voprfBatchUnblind runs VOPRF_Unblind as specified in draft-irtf-cfrg-voprf-02 func (c Client) voprfBatchUnblind(evs BatchedEvaluation, tokens []*Token, blindTokens []gg.GroupElement) ([]gg.GroupElement, error) { - ciph := c.ciph - eles := evs.Elements - proof := evs.Proof - // check DLEQ proof - b := false - if len(eles) == 1 { - b = proof.Verify(ciph.POG(), ciph.H2(), ciph.H3(), c.PublicKey(), blindTokens[0], eles[0]) - } else { - b = proof.BatchVerify(ciph.POG(), ciph.H2(), ciph.H3(), c.PublicKey(), blindTokens, eles) - } - if !b { + // check proof + if b, err := c.BatchVerifyProof(blindTokens, evs); !b { + if err != nil { + return nil, err + } return nil, oerr.ErrClientVerification } + return c.oprfBatchUnblind(evs, tokens) } @@ -586,9 +669,6 @@ func (c Client) oprfBatchUnblind(evs BatchedEvaluation, tokens []*Token) ([]gg.G } func (c Client) VerifyProof(blindToken gg.GroupElement, ev Evaluation) (bool, error) { - pog := c.ciph.POG() - G := pog.Generator() - blindTokens := gg.GroupElementList{blindToken} elements := gg.GroupElementList{ev.Element} @@ -597,13 +677,29 @@ func (c Client) VerifyProof(blindToken gg.GroupElement, ev Evaluation) (bool, er return false, err } + return c.verifyProofInner(M, Z, ev.Proof) +} + +func (c Client) BatchVerifyProof(blindTokens []gg.GroupElement, evs BatchedEvaluation) (bool, error) { + M, Z, err := c.ComputeComposites(blindTokens, evs.Elements) + if err != nil { + return false, err + } + + return c.verifyProofInner(M, Z, evs.Proof) +} + +func (c Client) verifyProofInner(M, Z gg.GroupElement, proof Proof) (bool, error) { + pog := c.ciph.POG() + G := pog.Generator() + // A' = (Ev.proof[1] * G + Ev.proof[0] * pkS) - A, err := G.ScalarMult(ev.Proof[1]) + A, err := G.ScalarMult(proof.S) if err != nil { return false, err } - A2, err := c.pk.ScalarMult(ev.Proof[0]) + A2, err := c.pk.ScalarMult(proof.C) if err != nil { return false, err } @@ -614,12 +710,12 @@ func (c Client) VerifyProof(blindToken gg.GroupElement, ev Evaluation) (bool, er } // B' = (Ev.proof[1] * M + Ev.proof[0] * Z) - B, err := M.ScalarMult(ev.Proof[1]) + B, err := M.ScalarMult(proof.S) if err != nil { return false, err } - B2, err := Z.ScalarMult(ev.Proof[0]) + B2, err := Z.ScalarMult(proof.C) if err != nil { return false, err } @@ -629,7 +725,7 @@ func (c Client) VerifyProof(blindToken gg.GroupElement, ev Evaluation) (bool, er return false, err } - challengeDST := "RFCXXXX-challenge-" + c.contextString + challengeDST := append([]byte("RFCXXXX-challenge-"), c.contextString...) h2Input, err := utils.ByteSliceLengthPrefixed(G, c.pk, M, Z, A, B, challengeDST) if err != nil { return false, err @@ -640,9 +736,11 @@ func (c Client) VerifyProof(blindToken gg.GroupElement, ev Evaluation) (bool, er return false, err } - fmt.Printf("c1 is %v, ev.proof[0] is %v\n", c1, ev.Proof[0]) + return c1.Cmp(proof.C) == 0, nil +} - return c1.Cmp(ev.Proof[0]) == 0, nil +func (c Client) Verifiable() bool { + return c.verifiable } func (c Client) ComputeComposites(blindTokens gg.GroupElementList, elements gg.GroupElementList) (M gg.GroupElement, Z gg.GroupElement, err error) { @@ -682,7 +780,7 @@ func (c Client) CreateFinalizeInput(token *Token, unblindedToken gg.GroupElement func (c Client) Finalize(token *Token, unblindedToken gg.GroupElement, info []byte) ([]byte, error) { ciph := c.ciph - hash := ciph.H1() + hash := ciph.Hash() input, err := c.CreateFinalizeInput(token, unblindedToken, info) if err != nil { return nil, err diff --git a/go/oprf/oprf_test.go b/go/oprf/oprf_test.go index a9af898..87c8343 100644 --- a/go/oprf/oprf_test.go +++ b/go/oprf/oprf_test.go @@ -3,432 +3,522 @@ package oprf import ( "crypto/hmac" "crypto/rand" - "encoding/binary" "errors" - "math/big" + "fmt" "testing" - "github.com/alxdavids/voprf-poc/go/oerr" gg "github.com/alxdavids/voprf-poc/go/oprf/groups" "github.com/alxdavids/voprf-poc/go/oprf/groups/ecgroup" "github.com/stretchr/testify/assert" ) -var ( - validOPRFP384Ciphersuite = "OPRF-P384-HKDF-SHA512-SSWU-RO" - validOPRFP521Ciphersuite = "OPRF-P521-HKDF-SHA512-SSWU-RO" - validOPRFC448Ciphersuite = "OPRF-curve448-HKDF-SHA512-ELL2-RO" - validVOPRFP384Ciphersuite = "VOPRF-P384-HKDF-SHA512-SSWU-RO" - validVOPRFP521Ciphersuite = "VOPRF-P521-HKDF-SHA512-SSWU-RO" - validVOPRFC448Ciphersuite = "VOPRF-curve448-HKDF-SHA512-ELL2-RO" -) - -func TestFullOPRFP384(t *testing.T) { - checkFull(t, validOPRFP384Ciphersuite) -} - -func TestFullOPRFP384Multiple(t *testing.T) { - checkFullBatch(t, validOPRFP384Ciphersuite, 5) -} - -func TestFullVOPRFP384(t *testing.T) { - checkFull(t, validVOPRFP384Ciphersuite) -} - -func TestFullVOPRFP384Multiple(t *testing.T) { - checkFullBatch(t, validVOPRFP384Ciphersuite, 5) -} - -func TestFullOPRFP521(t *testing.T) { - checkFull(t, validOPRFP521Ciphersuite) -} - -func TestFullOPRFP521Multiple(t *testing.T) { - checkFullBatch(t, validOPRFP521Ciphersuite, 5) -} - -func TestFullVOPRFP521(t *testing.T) { - checkFull(t, validVOPRFP521Ciphersuite) -} - -func TestFullVOPRFP521Multiple(t *testing.T) { - checkFullBatch(t, validVOPRFP521Ciphersuite, 5) -} - -func TestFullOPRFCurve448(t *testing.T) { - checkFull(t, validOPRFC448Ciphersuite) -} - -func TestFullOPRFCurve448Multiple(t *testing.T) { - checkFullBatch(t, validOPRFC448Ciphersuite, 5) -} - -func TestFullVOPRFCurve448(t *testing.T) { - checkFull(t, validVOPRFC448Ciphersuite) -} - -func TestFullVOPRFCurve448Multiple(t *testing.T) { - checkFullBatch(t, validVOPRFC448Ciphersuite, 5) -} - -func TestServerSetupP384(t *testing.T) { - checkServerSetup(t, validOPRFP384Ciphersuite) -} - -func TestServerSetupP521(t *testing.T) { - checkServerSetup(t, validOPRFP521Ciphersuite) -} - -func TestServerSetupCurve448(t *testing.T) { - checkServerSetup(t, validOPRFC448Ciphersuite) -} - -func TestServerEvalP384(t *testing.T) { - checkServerEval(t, validOPRFP384Ciphersuite, 1) -} - -func TestServerEvalP384Multiple(t *testing.T) { - checkServerEval(t, validOPRFP384Ciphersuite, 5) -} - -func TestServerEvalP384Verifiable(t *testing.T) { - checkServerEval(t, validVOPRFP384Ciphersuite, 1) -} - -func TestServerEvalP384VerifiableMultiple(t *testing.T) { - checkServerEval(t, validVOPRFP384Ciphersuite, 5) -} - -func TestServerEvalP521(t *testing.T) { - checkServerEval(t, validOPRFP521Ciphersuite, 1) -} - -func TestServerEvalP521Multiple(t *testing.T) { - checkServerEval(t, validOPRFP521Ciphersuite, 5) -} - -func TestServerEvalP521Verifiable(t *testing.T) { - checkServerEval(t, validVOPRFP521Ciphersuite, 1) -} - -func TestServerEvalP521VerifiableMultiple(t *testing.T) { - checkServerEval(t, validVOPRFP521Ciphersuite, 5) -} - -func TestServerEvalCurve448(t *testing.T) { - checkServerEval(t, validOPRFC448Ciphersuite, 1) -} - -func TestServerEvalCurve448Multiple(t *testing.T) { - checkServerEval(t, validOPRFC448Ciphersuite, 5) -} - -func TestServerEvalCurve448Verifiable(t *testing.T) { - checkServerEval(t, validVOPRFC448Ciphersuite, 1) +type testCfg struct { + t *testing.T + ciphersuite int + batch bool + verifiable bool } -func TestServerEvalCurve448VerifiableMultiple(t *testing.T) { - checkServerEval(t, validVOPRFC448Ciphersuite, 5) -} - -func TestServerBlind(t *testing.T) { - s, err := serverSetup(validOPRFP384Ciphersuite) - if err != nil { - t.Fatal(err) - } - _, _, err = s.Blind([]byte{}) - if !errors.Is(err, oerr.ErrOPRFUnimplementedFunctionServer) { - t.Fatal("Function should be unimplemented") +func batchStr(batch bool) string { + if batch { + return "Batch" + } else { + return "Single" } } -func TestServerUnblind(t *testing.T) { - s, err := serverSetup(validOPRFP384Ciphersuite) - if err != nil { - t.Fatal(err) - } - _, err = s.BatchUnblind(BatchedEvaluation{}, []*Token{new(Token)}, []gg.GroupElement{ecgroup.Point{}}) - if !errors.Is(err, oerr.ErrOPRFUnimplementedFunctionServer) { - t.Fatal("Function should be unimplemented") +func verifStr(verifiable bool) string { + if verifiable { + return "Verifiable" + } else { + return "Base" } } -func TestServerFinalize(t *testing.T) { - s, err := serverSetup(validOPRFP384Ciphersuite) - if err != nil { - t.Fatal(err) +func runTest(t *testing.T, testFunc func(*testCfg)) { + supported := []int{ + //gg.OPRF_CURVE25519_SHA512, //TODO + gg.OPRF_CURVE448_SHA512, + //gg.OPRF_P256_SHA512, //TODO + gg.OPRF_P384_SHA512, + gg.OPRF_P521_SHA512, } - var ge gg.GroupElement - - _, err = s.Finalize(&Token{}, ge, []byte{}) - if !errors.Is(err, oerr.ErrOPRFUnimplementedFunctionServer) { - t.Fatal("Function should be unimplemented") + for _, ciph := range supported { + for _, batch := range []bool{true, false} { + for _, verifiable := range []bool{true, false} { + t.Run(fmt.Sprintf("%s/%s/%s", gg.IDtoName(ciph), batchStr(batch), verifStr(verifiable)), + func(t *testing.T) { + testFunc(&testCfg{t, ciph, batch, verifiable}) + }) + } + } } } -func TestClientSetupP384(t *testing.T) { - checkClientSetup(t, validOPRFP384Ciphersuite) -} - -func TestClientSetupP521(t *testing.T) { - checkClientSetup(t, validOPRFP521Ciphersuite) +func TestFullOPRF(t *testing.T) { + runTest(t, checkFull) } -func TestClientSetupCurve448(t *testing.T) { - checkClientSetup(t, validOPRFC448Ciphersuite) -} +// func TestFullOPRFP384(t *testing.T) { +// checkFullBase(t, gg.OPRF_P384_SHA512) +// } -func TestClientBlindUnblindP384(t *testing.T) { - checkClientBlindUnblind(t, validOPRFP384Ciphersuite, 1) -} +// func TestFullOPRFP384Multiple(t *testing.T) { +// checkFullBatchBase(t, gg.OPRF_P384_SHA512, 5) +// } -func TestClientBlindUnblindP384Multiple(t *testing.T) { - checkClientBlindUnblind(t, validOPRFP384Ciphersuite, 5) -} +// func TestFullVOPRFP384(t *testing.T) { +// checkFullVerifiable(t, gg.OPRF_P384_SHA512) +// } -func TestClientBlindUnblindP384Verifiable(t *testing.T) { - checkClientBlindUnblind(t, validVOPRFP384Ciphersuite, 1) -} +// func TestFullVOPRFP384Multiple(t *testing.T) { +// checkFullBatchVerifiable(t, gg.OPRF_P384_SHA512, 5) +// } -func TestClientBlindUnblindP384VerifiableMultiple(t *testing.T) { - checkClientBlindUnblind(t, validVOPRFP384Ciphersuite, 5) -} +// func TestFullOPRFP521(t *testing.T) { +// checkFullBase(t, gg.OPRF_P521_SHA512) +// } -func TestClientBlindUnblindP521(t *testing.T) { - checkClientBlindUnblind(t, validOPRFP521Ciphersuite, 1) -} - -func TestClientBlindUnblindP521Multiple(t *testing.T) { - checkClientBlindUnblind(t, validOPRFP521Ciphersuite, 5) -} - -func TestClientBlindUnblindP521Verifiable(t *testing.T) { - checkClientBlindUnblind(t, validVOPRFP521Ciphersuite, 1) -} - -func TestClientBlindUnblindP521VerifiableMultiple(t *testing.T) { - checkClientBlindUnblind(t, validVOPRFP521Ciphersuite, 5) -} - -func TestClientBlindUnblindCurve448(t *testing.T) { - checkClientBlindUnblind(t, validOPRFC448Ciphersuite, 1) -} - -func TestClientBlindUnblindCurve448Multiple(t *testing.T) { - checkClientBlindUnblind(t, validOPRFC448Ciphersuite, 5) -} - -func TestClientBlindUnblindCurve448Verifiable(t *testing.T) { - checkClientBlindUnblind(t, validVOPRFC448Ciphersuite, 1) -} - -func TestClientBlindUnblindCurve448VerifiableMultiple(t *testing.T) { - checkClientBlindUnblind(t, validVOPRFC448Ciphersuite, 5) -} - -func TestClientFinalizeP384(t *testing.T) { - checkClientFinalize(t, validOPRFP384Ciphersuite) -} - -func TestClientFinalizeP521(t *testing.T) { - checkClientFinalize(t, validOPRFP521Ciphersuite) -} - -func TestClientFinalizeCurve448(t *testing.T) { - checkClientFinalize(t, validOPRFC448Ciphersuite) -} - -func TestClientEval(t *testing.T) { - c, err := clientSetup(validOPRFP384Ciphersuite) - if err != nil { - t.Fatal(err) - } - _, err = c.BatchEvaluate([]gg.GroupElement{ecgroup.Point{}}) - if !errors.Is(err, oerr.ErrOPRFUnimplementedFunctionClient) { - t.Fatal("Function should be unimplemented") - } -} - -func TestClientUnblindVerifiable(t *testing.T) { - c, err := clientSetup(validVOPRFP384Ciphersuite) - if err != nil { - t.Fatal(err) - } - pog := c.Ciphersuite().POG() - _, err = pog.RandomScalar() - if err != nil { - t.Fatal(err) - } -} +// func TestFullOPRFP521Multiple(t *testing.T) { +// checkFullBatchBase(t, gg.OPRF_P521_SHA512, 5) +// } -func checkServerSetup(t *testing.T, validCiphersuite string) { - s, err := serverSetup(validCiphersuite) +// func TestFullVOPRFP521(t *testing.T) { +// checkFullVerifiable(t, gg.OPRF_P521_SHA512) +// } + +// func TestFullVOPRFP521Multiple(t *testing.T) { +// checkFullBatchVerifiable(t, gg.OPRF_P521_SHA512, 5) +// } + +// func TestFullOPRFCurve448(t *testing.T) { +// checkFullBase(t, gg.OPRF_CURVE448_SHA512) +// } + +// func TestFullOPRFCurve448Multiple(t *testing.T) { +// checkFullBatchBase(t, gg.OPRF_CURVE448_SHA512, 5) +// } + +// func TestFullVOPRFCurve448(t *testing.T) { +// checkFullVerifiable(t, gg.OPRF_CURVE448_SHA512) +// } + +// func TestFullVOPRFCurve448Multiple(t *testing.T) { +// checkFullBatchVerifiable(t, gg.OPRF_CURVE448_SHA512, 5) +// } + +// func TestServerSetupP384(t *testing.T) { +// checkServerSetup(t, gg.OPRF_P384_SHA512) +// } + +// func TestServerSetupP521(t *testing.T) { +// checkServerSetup(t, gg.OPRF_P521_SHA512) +// } + +// func TestServerSetupCurve448(t *testing.T) { +// checkServerSetup(t, gg.OPRF_CURVE448_SHA512) +// } + +// func TestServerEvalP384(t *testing.T) { +// checkServerEval(t, gg.OPRF_P384_SHA512, 1) +// } + +// func TestServerEvalP384Multiple(t *testing.T) { +// checkServerEval(t, gg.OPRF_P384_SHA512, 5) +// } + +// func TestServerEvalP384Verifiable(t *testing.T) { +// checkServerEvalVerifiable(t, gg.OPRF_P384_SHA512, 1) +// } + +// func TestServerEvalP384VerifiableMultiple(t *testing.T) { +// checkServerEvalVerifiable(t, gg.OPRF_P384_SHA512, 5) +// } + +// func TestServerEvalP521(t *testing.T) { +// checkServerEval(t, gg.OPRF_P521_SHA512, 1) +// } + +// func TestServerEvalP521Multiple(t *testing.T) { +// checkServerEval(t, gg.OPRF_P521_SHA512, 5) +// } + +// func TestServerEvalP521Verifiable(t *testing.T) { +// checkServerEvalVerifiable(t, gg.OPRF_P521_SHA512, 1) +// } + +// func TestServerEvalP521VerifiableMultiple(t *testing.T) { +// checkServerEvalVerifiable(t, gg.OPRF_P521_SHA512, 5) +// } + +// func TestServerEvalCurve448(t *testing.T) { +// checkServerEval(t, gg.OPRF_CURVE448_SHA512, 1) +// } + +// func TestServerEvalCurve448Multiple(t *testing.T) { +// checkServerEval(t, gg.OPRF_CURVE448_SHA512, 5) +// } + +// func TestServerEvalCurve448Verifiable(t *testing.T) { +// checkServerEvalVerifiable(t, gg.OPRF_CURVE448_SHA512, 1) +// } + +// func TestServerEvalCurve448VerifiableMultiple(t *testing.T) { +// checkServerEvalVerifiable(t, gg.OPRF_CURVE448_SHA512, 5) +// } + +// func TestServerBlind(t *testing.T) { +// s, err := serverSetup(gg.OPRF_P384_SHA512) +// if err != nil { +// t.Fatal(err) +// } +// _, _, err = s.Blind([]byte{}) +// if !errors.Is(err, oerr.ErrOPRFUnimplementedFunctionServer) { +// t.Fatal("Function should be unimplemented") +// } +// } + +// func TestServerUnblind(t *testing.T) { +// s, err := serverSetup(gg.OPRF_P384_SHA512) +// if err != nil { +// t.Fatal(err) +// } +// _, err = s.BatchUnblind(BatchedEvaluation{}, []*Token{new(Token)}, []gg.GroupElement{ecgroup.Point{}}) +// if !errors.Is(err, oerr.ErrOPRFUnimplementedFunctionServer) { +// t.Fatal("Function should be unimplemented") +// } +// } + +// func TestServerFinalize(t *testing.T) { +// s, err := serverSetup(gg.OPRF_P384_SHA512) +// if err != nil { +// t.Fatal(err) +// } + +// var ge gg.GroupElement + +// _, err = s.Finalize(&Token{}, ge, []byte{}) +// if !errors.Is(err, oerr.ErrOPRFUnimplementedFunctionServer) { +// t.Fatal("Function should be unimplemented") +// } +// } + +// func TestClientSetupP384(t *testing.T) { +// checkClientSetup(t, gg.OPRF_P384_SHA512) +// } + +// func TestClientSetupP521(t *testing.T) { +// checkClientSetup(t, gg.OPRF_P521_SHA512) +// } + +// func TestClientSetupCurve448(t *testing.T) { +// checkClientSetup(t, gg.OPRF_CURVE448_SHA512) +// } + +// func TestClientBlindUnblindP384(t *testing.T) { +// checkClientBlindUnblind(t, gg.OPRF_P384_SHA512, 1) +// } + +// func TestClientBlindUnblindP384Multiple(t *testing.T) { +// checkClientBlindUnblind(t, gg.OPRF_P384_SHA512, 5) +// } + +// func TestClientBlindUnblindP384Verifiable(t *testing.T) { +// checkClientBlindUnblind(t, gg.OPRF_P384_SHA512, 1) +// } + +// func TestClientBlindUnblindP384VerifiableMultiple(t *testing.T) { +// checkClientBlindUnblind(t, gg.OPRF_P384_SHA512, 5) +// } + +// func TestClientBlindUnblindP521(t *testing.T) { +// checkClientBlindUnblind(t, gg.OPRF_P521_SHA512, 1) +// } + +// func TestClientBlindUnblindP521Multiple(t *testing.T) { +// checkClientBlindUnblind(t, gg.OPRF_P521_SHA512, 5) +// } + +// func TestClientBlindUnblindP521Verifiable(t *testing.T) { +// checkClientBlindUnblind(t, gg.OPRF_P521_SHA512, 1) +// } + +// func TestClientBlindUnblindP521VerifiableMultiple(t *testing.T) { +// checkClientBlindUnblind(t, gg.OPRF_P521_SHA512, 5) +// } + +// func TestClientBlindUnblindCurve448(t *testing.T) { +// checkClientBlindUnblind(t, gg.OPRF_CURVE448_SHA512, 1) +// } + +// func TestClientBlindUnblindCurve448Multiple(t *testing.T) { +// checkClientBlindUnblind(t, gg.OPRF_CURVE448_SHA512, 5) +// } + +// func TestClientBlindUnblindCurve448Verifiable(t *testing.T) { +// checkClientBlindUnblind(t, gg.OPRF_CURVE448_SHA512, 1) +// } + +// func TestClientBlindUnblindCurve448VerifiableMultiple(t *testing.T) { +// checkClientBlindUnblind(t, gg.OPRF_CURVE448_SHA512, 5) +// } + +// func TestClientFinalizeP384(t *testing.T) { +// checkClientFinalize(t, gg.OPRF_P384_SHA512) +// } + +// func TestClientFinalizeP521(t *testing.T) { +// checkClientFinalize(t, gg.OPRF_P521_SHA512) +// } + +// func TestClientFinalizeCurve448(t *testing.T) { +// checkClientFinalize(t, gg.OPRF_CURVE448_SHA512) +// } + +// func TestClientEval(t *testing.T) { +// c, err := clientSetup(gg.OPRF_P384_SHA512) +// if err != nil { +// t.Fatal(err) +// } +// _, err = c.BatchEvaluate([]gg.GroupElement{ecgroup.Point{}}) +// if !errors.Is(err, oerr.ErrOPRFUnimplementedFunctionClient) { +// t.Fatal("Function should be unimplemented") +// } +// } + +// func TestClientUnblindVerifiable(t *testing.T) { +// c, err := clientSetup(gg.OPRF_P384_SHA512) +// if err != nil { +// t.Fatal(err) +// } +// pog := c.Ciphersuite().POG() +// _, err = pog.RandomScalar() +// if err != nil { +// t.Fatal(err) +// } +// } + +// func checkServerSetup(t *testing.T, validCiphersuite int) { +// s, err := serverSetup(validCiphersuite) +// if err != nil { +// t.Fatal(err) +// } +// assert.NotEmpty(t, s) +// assert.NotEmpty(t, s.Ciphersuite()) +// assert.NotEmpty(t, s.SecretKey()) +// assert.NotEmpty(t, s.SecretKey().PubKey) +// } + +// func checkClientSetup(t *testing.T, validCiphersuite int) { +// c, err := clientSetup(validCiphersuite) +// if err != nil { +// t.Fatal(err) +// } +// assert.NotEmpty(t, c) +// assert.NotEmpty(t, c.Ciphersuite()) +// } + +func setup(cfg *testCfg) (Server, Client, error) { + s, err := serverSetup(cfg) if err != nil { - t.Fatal(err) + return Server{}, Client{}, err } - assert.NotEmpty(t, s) - assert.NotEmpty(t, s.Ciphersuite()) - assert.NotEmpty(t, s.SecretKey()) - assert.NotEmpty(t, s.SecretKey().PubKey) -} -func checkClientSetup(t *testing.T, validCiphersuite string) { - c, err := clientSetup(validCiphersuite) + c, err := clientSetup(cfg) if err != nil { - t.Fatal(err) + return Server{}, Client{}, err } - assert.NotEmpty(t, c) - assert.NotEmpty(t, c.Ciphersuite()) -} -func serverSetup(ciph string) (Server, error) { - s, err := Server{}.Setup(ciph, ecgroup.GroupCurve{}) - if err != nil { - return Server{}, err + if c.Ciphersuite().ID() != s.Ciphersuite().ID() { + return Server{}, Client{}, errors.New("inconsistent ciphersuites") } - return s.(Server), nil -} -func clientSetup(ciph string) (Client, error) { - s, err := Client{}.Setup(ciph, ecgroup.GroupCurve{}) - if err != nil { - return Client{}, err - } - return s.(Client), nil + return s, c, nil } -func checkServerEval(t *testing.T, validCiphersuite string, n int) { - s, _, eles, err := setupServerEval(validCiphersuite, n) - if err != nil { - t.Fatal(err) - } - ciph := s.Ciphersuite() - pog := ciph.POG() - - // evaluate the OPRF - ev, err := s.BatchEvaluate(eles) - if err != nil { - t.Fatal(err) - } - - // only one evaluation - for i, Q := range ev.Elements { - chkQ, err := eles[i].ScalarMult(s.SecretKey().K) - if err != nil { - t.Fatal(err) - } - if !Q.Equal(chkQ) { - t.Fatal("Server evaluation returned inconsistent result") - } - } - - // verify proof if necessary - if ciph.Verifiable() { - proof := ev.Proof - if n == 1 { - assert.True(t, proof.Verify(pog, ciph.H2(), ciph.H3(), s.SecretKey().PubKey, eles[0], ev.Elements[0])) - } else { - assert.True(t, proof.BatchVerify(pog, ciph.H2(), ciph.H3(), s.SecretKey().PubKey, eles, ev.Elements)) - } - } -} +func serverSetup(cfg *testCfg) (Server, error) { + var s Participant + var err error -func checkClientBlindUnblind(t *testing.T, validCiphersuite string, n int) { - c, eval, tokens, blindTokens, sk, err := clientSetupUnblind(validCiphersuite, n) - if err != nil { - t.Fatal(err) + if cfg.verifiable { + s, err = Server{}.SetupVerifiable(cfg.ciphersuite, ecgroup.GroupCurve{}) + } else { + s, err = Server{}.Setup(cfg.ciphersuite, ecgroup.GroupCurve{}) } - - // attempt unblind - unblindedTokens, err := c.BatchUnblind(eval, tokens, blindTokens) if err != nil { - t.Fatal(err) + return Server{}, err } - // check that the unblinded elements correspond - for i, unblindedToken := range unblindedTokens { - T, err := c.Ciphersuite().POG().HashToGroup(tokens[i].Data) - if err != nil { - t.Fatal(err) - } - - expected, err := T.ScalarMult(sk) - if err != nil { - t.Fatal(err) - } - assert.True(t, unblindedToken.Equal(expected)) - } + return s.(Server), nil } -func checkClientFinalize(t *testing.T, validCiphersuite string) { - c, err := clientSetup(validCiphersuite) - if err != nil { - t.Fatal(err) - } - - clientInput := []byte{1, 2, 3, 4, 5} - token := &Token{Data: clientInput} - info := []byte{6, 7, 8, 9, 10} - pog := c.Ciphersuite().POG() +func clientSetup(cfg *testCfg) (Client, error) { + var c Participant + var err error - unblindedToken, err := pog.HashToGroup(clientInput) - if err != nil { - t.Fatal(err) + if cfg.verifiable { + c, err = Client{}.SetupVerifiable(cfg.ciphersuite, ecgroup.GroupCurve{}) + } else { + c, err = Client{}.Setup(cfg.ciphersuite, ecgroup.GroupCurve{}) } - - output, err := c.Finalize(token, unblindedToken, info) if err != nil { - t.Fatal(err) + return Client{}, err } - // recompute - bytesUnblindedToken, err := unblindedToken.Serialize() + return c.(Client), nil +} + +// func checkServerEval(t *testing.T, validCiphersuite int, n int) { +// s, _, blindTokens, err := setupServerEval(validCiphersuite, n) +// if err != nil { +// t.Fatal(err) +// } +// ciph := s.Ciphersuite() + +// // evaluate the OPRF +// var ev Evaluation +// var evs BatchedEvaluation +// var elems []gg.GroupElement +// if n == 1 { +// ev, err := s.Evaluate(blindTokens[0]) +// if err != nil { +// t.Fatal(err) +// } +// elems = []gg.GroupElement{ev.Element} +// } else { +// evs, err := s.BatchEvaluate(blindTokens) +// if err != nil { +// t.Fatal(err) +// } +// elems = evs.Elements +// } + +// // only one evaluation +// for i, Q := range elems { +// chkQ, err := blindTokens[i].ScalarMult(s.SecretKey().K) +// if err != nil { +// t.Fatal(err) +// } +// if !Q.Equal(chkQ) { +// t.Fatal("Server evaluation returned inconsistent result") +// } +// } + +// // verify proof if necessary +// if ciph.Verifiable() { +// c, err := clientSetup(validCiphersuite) +// if err != nil { +// t.Fatal(err) +// } +// if n == 1 { +// valid, err := c.VerifyProof(blindTokens[0], ev) +// if err != nil { +// t.Fatal(err) +// } +// assert.True(t, valid) +// } else { +// valid, err := c.BatchVerifyProof(blindTokens, evs) +// if err != nil { +// t.Fatal(err) +// } +// assert.True(t, valid) +// } +// } +// } + +// func checkClientBlindUnblind(t *testing.T, validCiphersuite int, n int) { +// c, eval, tokens, blindTokens, sk, err := clientSetupUnblind(validCiphersuite, n) +// if err != nil { +// t.Fatal(err) +// } + +// // attempt unblind +// unblindedTokens, err := c.BatchUnblind(eval, tokens, blindTokens) +// if err != nil { +// t.Fatal(err) +// } + +// // check that the unblinded elements correspond +// for i, unblindedToken := range unblindedTokens { +// T, err := c.Ciphersuite().POG().HashToGroup(tokens[i].Data) +// if err != nil { +// t.Fatal(err) +// } + +// expected, err := T.ScalarMult(sk) +// if err != nil { +// t.Fatal(err) +// } +// assert.True(t, unblindedToken.Equal(expected)) +// } +// } + +// func checkClientFinalize(t *testing.T, validCiphersuite int) { +// c, err := clientSetup(validCiphersuite) +// if err != nil { +// t.Fatal(err) +// } + +// clientInput := []byte{1, 2, 3, 4, 5} +// token := &Token{Data: clientInput} +// info := []byte{6, 7, 8, 9, 10} +// pog := c.Ciphersuite().POG() + +// unblindedToken, err := pog.HashToGroup(clientInput) +// if err != nil { +// t.Fatal(err) +// } + +// output, err := c.Finalize(token, unblindedToken, info) +// if err != nil { +// t.Fatal(err) +// } + +// // recompute +// bytesUnblindedToken, err := unblindedToken.Serialize() +// if err != nil { +// t.Fatal(err) +// } +// DST := []byte("RFCXXXX-Finalize") + +// hash := c.Ciphersuite().Hash() +// lengthBuffer := make([]byte, 2) + +// binary.BigEndian.PutUint16(lengthBuffer, uint16(len(DST))) +// hash.Write(lengthBuffer) +// hash.Write(DST) + +// binary.BigEndian.PutUint16(lengthBuffer, uint16(len(clientInput))) +// hash.Write(lengthBuffer) +// hash.Write(clientInput) + +// binary.BigEndian.PutUint16(lengthBuffer, uint16(len(bytesUnblindedToken))) +// hash.Write(lengthBuffer) +// hash.Write(bytesUnblindedToken) + +// binary.BigEndian.PutUint16(lengthBuffer, uint16(len(info))) +// hash.Write(lengthBuffer) +// hash.Write(info) + +// outputCheck := hash.Sum(nil) + +// if !hmac.Equal(output, outputCheck) { +// t.Fatal("Finalize failed to produce the correct output") +// } +// } + +func checkFull(cfg *testCfg) { + s, c, err := setup(cfg) if err != nil { - t.Fatal(err) + cfg.t.Fatal(err) } - DST := []byte("RFCXXXX-Finalize") - - hash := c.Ciphersuite().H3() - lengthBuffer := make([]byte, 2) - - binary.BigEndian.PutUint16(lengthBuffer, uint16(len(DST))) - hash.Write(lengthBuffer) - hash.Write(DST) - binary.BigEndian.PutUint16(lengthBuffer, uint16(len(clientInput))) - hash.Write(lengthBuffer) - hash.Write(clientInput) - - binary.BigEndian.PutUint16(lengthBuffer, uint16(len(bytesUnblindedToken))) - hash.Write(lengthBuffer) - hash.Write(bytesUnblindedToken) - - binary.BigEndian.PutUint16(lengthBuffer, uint16(len(info))) - hash.Write(lengthBuffer) - hash.Write(info) - - outputCheck := hash.Sum(nil) - - if !hmac.Equal(output, outputCheck) { - t.Fatal("Finalize failed to produce the correct output") - } + checkFullOld(cfg.t, cfg.ciphersuite, s, c) } -func checkFull(t *testing.T, validCiphersuite string) { - s, err := serverSetup(validCiphersuite) - if err != nil { - t.Fatal(err) - } - c, err := clientSetup(validCiphersuite) - if err != nil { - t.Fatal(err) - } - - if c.Ciphersuite().Name() != s.Ciphersuite().Name() { - t.Fatal("Ciphersuites are inconsistent") - } +func checkFullOld(t *testing.T, validCiphersuite int, s Server, c Client) { infoFinal := []byte{6, 7, 8, 9, 10} c.pk = s.SecretKey().PubKey @@ -481,20 +571,7 @@ func checkFull(t *testing.T, validCiphersuite string) { assert.True(t, hmac.Equal(outputClient, outputServer)) } -func checkFullBatch(t *testing.T, validCiphersuite string, n int) { - s, err := serverSetup(validCiphersuite) - if err != nil { - t.Fatal(err) - } - c, err := clientSetup(validCiphersuite) - if err != nil { - t.Fatal(err) - } - - if c.Ciphersuite().Name() != s.Ciphersuite().Name() { - t.Fatal("Ciphersuites are inconsistent") - } - +func checkFullBatch(t *testing.T, validCiphersuite int, n int, s Server, c Client) { infoFinal := []byte{6, 7, 8, 9, 10} c.pk = s.SecretKey().PubKey @@ -557,483 +634,483 @@ func checkFullBatch(t *testing.T, validCiphersuite string, n int) { } } -func setupServerEval(validCiphersuite string, n int) (Server, [][]byte, []gg.GroupElement, error) { - s, err := serverSetup(validCiphersuite) - if err != nil { - return Server{}, nil, nil, err - } - ciph := s.Ciphersuite() - pog := ciph.POG() - inputs := make([][]byte, n) - eles := make([]gg.GroupElement, n) - for i := 0; i < n; i++ { - x := make([]byte, pog.ByteLength()) - rand.Read(x) - P, err := pog.HashToGroup(x) - if err != nil { - return Server{}, nil, nil, err - } - inputs[i] = x - eles[i] = P - } - return s, inputs, eles, nil -} - -func clientSetupUnblind(validCiphersuite string, n int) (Client, BatchedEvaluation, []*Token, []gg.GroupElement, *big.Int, error) { - c, err := clientSetup(validCiphersuite) - if err != nil { - return Client{}, BatchedEvaluation{}, nil, nil, nil, err - } - pog := c.Ciphersuite().POG() - - // create blinded points - blindTokens := make([]gg.GroupElement, n) - tokens := make([]*Token, n) - for i := 0; i < n; i++ { - x := make([]byte, pog.ByteLength()) - rand.Read(x) - token, blindToken, err := c.Blind(x) - if err != nil { - return Client{}, BatchedEvaluation{}, nil, nil, nil, err - } - - if !blindToken.IsValid() { - return Client{}, BatchedEvaluation{}, nil, nil, nil, errors.New("Point is not valid") - } - - blindTokens[i] = blindToken - tokens[i] = token - } - - // dummy server for generating keys and evaluating OPRF - // we need to do this as BatchUnblind also checks the DLEQ proof in the - // verifiable mode - s, err := serverSetup(validCiphersuite) - if err != nil { - return Client{}, BatchedEvaluation{}, nil, nil, nil, err - } - eval, err := s.BatchEvaluate(blindTokens) - if err != nil { - return Client{}, BatchedEvaluation{}, nil, nil, nil, err - } - c.pk = s.sk.PubKey - - return c, eval, tokens, blindTokens, s.SecretKey().K, err -} +// func setupServerEval(validCiphersuite int, n int) (Server, [][]byte, []gg.GroupElement, error) { +// s, err := serverSetup(validCiphersuite) +// if err != nil { +// return Server{}, nil, nil, err +// } +// ciph := s.Ciphersuite() +// pog := ciph.POG() +// inputs := make([][]byte, n) +// eles := make([]gg.GroupElement, n) +// for i := 0; i < n; i++ { +// x := make([]byte, pog.ByteLength()) +// rand.Read(x) +// P, err := pog.HashToGroup(x) +// if err != nil { +// return Server{}, nil, nil, err +// } +// inputs[i] = x +// eles[i] = P +// } +// return s, inputs, eles, nil +// } + +// func clientSetupUnblind(validCiphersuite int, n int) (Client, BatchedEvaluation, []*Token, []gg.GroupElement, *big.Int, error) { +// c, err := clientSetup(validCiphersuite) +// if err != nil { +// return Client{}, BatchedEvaluation{}, nil, nil, nil, err +// } +// pog := c.Ciphersuite().POG() + +// // create blinded points +// blindTokens := make([]gg.GroupElement, n) +// tokens := make([]*Token, n) +// for i := 0; i < n; i++ { +// x := make([]byte, pog.ByteLength()) +// rand.Read(x) +// token, blindToken, err := c.Blind(x) +// if err != nil { +// return Client{}, BatchedEvaluation{}, nil, nil, nil, err +// } + +// if !blindToken.IsValid() { +// return Client{}, BatchedEvaluation{}, nil, nil, nil, errors.New("Point is not valid") +// } + +// blindTokens[i] = blindToken +// tokens[i] = token +// } + +// // dummy server for generating keys and evaluating OPRF +// // we need to do this as BatchUnblind also checks the DLEQ proof in the +// // verifiable mode +// s, err := serverSetup(validCiphersuite) +// if err != nil { +// return Client{}, BatchedEvaluation{}, nil, nil, nil, err +// } +// eval, err := s.BatchEvaluate(blindTokens) +// if err != nil { +// return Client{}, BatchedEvaluation{}, nil, nil, nil, err +// } +// c.pk = s.sk.PubKey + +// return c, eval, tokens, blindTokens, s.SecretKey().K, err +// } /** * Benchmarks */ -func BenchmarkServerOPRFSetupP384(b *testing.B) { - benchServerSetup(b, validOPRFP384Ciphersuite) -} - -func BenchmarkServerVOPRFSetupP384(b *testing.B) { - benchServerSetup(b, validVOPRFP384Ciphersuite) -} - -func BenchmarkServerOPRFSetupP521(b *testing.B) { - benchServerSetup(b, validOPRFP521Ciphersuite) -} - -func BenchmarkServerVOPRFSetupP521(b *testing.B) { - benchServerSetup(b, validVOPRFP521Ciphersuite) -} - -func BenchmarkServerOPRFSetupC448(b *testing.B) { - benchServerSetup(b, validOPRFC448Ciphersuite) -} - -func BenchmarkServerVOPRFSetupC448(b *testing.B) { - benchServerSetup(b, validVOPRFC448Ciphersuite) -} - -func benchServerSetup(b *testing.B, validCiphersuite string) { - for i := 0; i < b.N; i++ { - _, err := serverSetup(validCiphersuite) - if err != nil { - b.Fatal(err) - } - } -} - -func BenchmarkServerOPRFEvalP384_1(b *testing.B) { - benchServerEval(b, validOPRFP384Ciphersuite, 1) -} - -func BenchmarkServerOPRFEvalP384_5(b *testing.B) { - benchServerEval(b, validOPRFP384Ciphersuite, 5) -} - -func BenchmarkServerOPRFEvalP384_10(b *testing.B) { - benchServerEval(b, validOPRFP384Ciphersuite, 10) -} - -func BenchmarkServerOPRFEvalP384_25(b *testing.B) { - benchServerEval(b, validOPRFP384Ciphersuite, 25) -} - -func BenchmarkServerOPRFEvalP384_50(b *testing.B) { - benchServerEval(b, validOPRFP384Ciphersuite, 50) -} - -func BenchmarkServerOPRFEvalP384_100(b *testing.B) { - benchServerEval(b, validOPRFP384Ciphersuite, 100) -} +// func BenchmarkServerOPRFSetupP384(b *testing.B) { +// benchServerSetup(b, gg.OPRF_P384_SHA512) +// } + +// func BenchmarkServerVOPRFSetupP384(b *testing.B) { +// benchServerSetup(b, gg.OPRF_P384_SHA512) +// } + +// func BenchmarkServerOPRFSetupP521(b *testing.B) { +// benchServerSetup(b, gg.OPRF_P521_SHA512) +// } + +// func BenchmarkServerVOPRFSetupP521(b *testing.B) { +// benchServerSetup(b, gg.OPRF_P521_SHA512) +// } + +// func BenchmarkServerOPRFSetupC448(b *testing.B) { +// benchServerSetup(b, gg.OPRF_CURVE448_SHA512) +// } + +// func BenchmarkServerVOPRFSetupC448(b *testing.B) { +// benchServerSetup(b, gg.OPRF_CURVE448_SHA512) +// } + +// // func benchServerSetup(b *testing.B, validCiphersuite int) { +// // for i := 0; i < b.N; i++ { +// // _, err := serverSetup(validCiphersuite) +// // if err != nil { +// // b.Fatal(err) +// // } +// // } +// // } -func BenchmarkServerVOPRFEvalP384_1(b *testing.B) { - benchServerEval(b, validVOPRFP384Ciphersuite, 1) -} +// func BenchmarkServerOPRFEvalP384_1(b *testing.B) { +// benchServerEval(b, gg.OPRF_P384_SHA512, 1) +// } -func BenchmarkServerVOPRFEvalP384_5(b *testing.B) { - benchServerEval(b, validVOPRFP384Ciphersuite, 5) -} +// func BenchmarkServerOPRFEvalP384_5(b *testing.B) { +// benchServerEval(b, gg.OPRF_P384_SHA512, 5) +// } -func BenchmarkServerVOPRFEvalP384_10(b *testing.B) { - benchServerEval(b, validVOPRFP384Ciphersuite, 10) -} +// func BenchmarkServerOPRFEvalP384_10(b *testing.B) { +// benchServerEval(b, gg.OPRF_P384_SHA512, 10) +// } -func BenchmarkServerVOPRFEvalP384_25(b *testing.B) { - benchServerEval(b, validVOPRFP384Ciphersuite, 25) -} +// func BenchmarkServerOPRFEvalP384_25(b *testing.B) { +// benchServerEval(b, gg.OPRF_P384_SHA512, 25) +// } -func BenchmarkServerVOPRFEvalP384_50(b *testing.B) { - benchServerEval(b, validVOPRFP384Ciphersuite, 50) -} +// func BenchmarkServerOPRFEvalP384_50(b *testing.B) { +// benchServerEval(b, gg.OPRF_P384_SHA512, 50) +// } -func BenchmarkServerVOPRFEvalP384_100(b *testing.B) { - benchServerEval(b, validVOPRFP384Ciphersuite, 100) -} +// func BenchmarkServerOPRFEvalP384_100(b *testing.B) { +// benchServerEval(b, gg.OPRF_P384_SHA512, 100) +// } -func BenchmarkServerOPRFEvalP521_1(b *testing.B) { - benchServerEval(b, validOPRFP521Ciphersuite, 1) -} +// func BenchmarkServerVOPRFEvalP384_1(b *testing.B) { +// benchServerEval(b, gg.OPRF_P384_SHA512, 1) +// } -func BenchmarkServerOPRFEvalP521_5(b *testing.B) { - benchServerEval(b, validOPRFP521Ciphersuite, 5) -} +// func BenchmarkServerVOPRFEvalP384_5(b *testing.B) { +// benchServerEval(b, gg.OPRF_P384_SHA512, 5) +// } -func BenchmarkServerOPRFEvalP521_10(b *testing.B) { - benchServerEval(b, validOPRFP521Ciphersuite, 10) -} +// func BenchmarkServerVOPRFEvalP384_10(b *testing.B) { +// benchServerEval(b, gg.OPRF_P384_SHA512, 10) +// } -func BenchmarkServerOPRFEvalP521_25(b *testing.B) { - benchServerEval(b, validOPRFP521Ciphersuite, 25) -} +// func BenchmarkServerVOPRFEvalP384_25(b *testing.B) { +// benchServerEval(b, gg.OPRF_P384_SHA512, 25) +// } -func BenchmarkServerOPRFEvalP521_50(b *testing.B) { - benchServerEval(b, validOPRFP521Ciphersuite, 50) -} +// func BenchmarkServerVOPRFEvalP384_50(b *testing.B) { +// benchServerEval(b, gg.OPRF_P384_SHA512, 50) +// } -func BenchmarkServerOPRFEvalP521_100(b *testing.B) { - benchServerEval(b, validOPRFP521Ciphersuite, 100) -} - -func BenchmarkServerVOPRFEvalP521_1(b *testing.B) { - benchServerEval(b, validVOPRFP521Ciphersuite, 1) -} - -func BenchmarkServerVOPRFEvalP521_5(b *testing.B) { - benchServerEval(b, validVOPRFP521Ciphersuite, 5) -} - -func BenchmarkServerVOPRFEvalP521_10(b *testing.B) { - benchServerEval(b, validVOPRFP521Ciphersuite, 10) -} - -func BenchmarkServerVOPRFEvalP521_25(b *testing.B) { - benchServerEval(b, validVOPRFP521Ciphersuite, 25) -} - -func BenchmarkServerVOPRFEvalP521_50(b *testing.B) { - benchServerEval(b, validVOPRFP521Ciphersuite, 50) -} - -func BenchmarkServerVOPRFEvalP521_100(b *testing.B) { - benchServerEval(b, validVOPRFP521Ciphersuite, 100) -} - -func BenchmarkServerOPRFEvalC448_1(b *testing.B) { - benchServerEval(b, validOPRFC448Ciphersuite, 1) -} - -func BenchmarkServerOPRFEvalC448_5(b *testing.B) { - benchServerEval(b, validOPRFC448Ciphersuite, 5) -} - -func BenchmarkServerOPRFEvalC448_10(b *testing.B) { - benchServerEval(b, validOPRFC448Ciphersuite, 10) -} - -func BenchmarkServerOPRFEvalC448_25(b *testing.B) { - benchServerEval(b, validOPRFC448Ciphersuite, 25) -} - -func BenchmarkServerOPRFEvalC448_50(b *testing.B) { - benchServerEval(b, validOPRFC448Ciphersuite, 50) -} - -func BenchmarkServerOPRFEvalC448_100(b *testing.B) { - benchServerEval(b, validOPRFC448Ciphersuite, 100) -} - -func BenchmarkServerVOPRFEvalC448_1(b *testing.B) { - benchServerEval(b, validVOPRFC448Ciphersuite, 1) -} - -func BenchmarkServerVOPRFEvalC448_5(b *testing.B) { - benchServerEval(b, validVOPRFC448Ciphersuite, 5) -} - -func BenchmarkServerVOPRFEvalC448_10(b *testing.B) { - benchServerEval(b, validVOPRFC448Ciphersuite, 10) -} - -func BenchmarkServerVOPRFEvalC448_25(b *testing.B) { - benchServerEval(b, validVOPRFC448Ciphersuite, 25) -} - -func BenchmarkServerVOPRFEvalC448_50(b *testing.B) { - benchServerEval(b, validVOPRFC448Ciphersuite, 50) -} - -func BenchmarkServerVOPRFEvalC448_100(b *testing.B) { - benchServerEval(b, validVOPRFC448Ciphersuite, 100) -} - -func benchServerEval(b *testing.B, validCiphersuite string, n int) { - s, _, eles, err := setupServerEval(validCiphersuite, n) - if err != nil { - b.Fatal(err) - } - - // benchmark - for i := 0; i < b.N; i++ { - _, err := s.BatchEvaluate(eles) - if err != nil { - b.Fatal(err) - } - } -} - -func BenchmarkClientBlindP384(b *testing.B) { - benchClientBlind(b, validOPRFP384Ciphersuite) -} - -func BenchmarkClientBlindP521(b *testing.B) { - benchClientBlind(b, validOPRFP521Ciphersuite) -} - -func benchClientBlind(b *testing.B, validCiphersuite string) { - c, err := clientSetup(validCiphersuite) - if err != nil { - b.Fatal(err) - } - pog := c.Ciphersuite().POG() - x := make([]byte, pog.ByteLength()) - rand.Read(x) - - // benchmark - for i := 0; i < b.N; i++ { - _, _, err := c.Blind(x) - if err != nil { - b.Fatal(err) - } - } -} - -func BenchmarkClientOPRFUnblindP384_1(b *testing.B) { - benchClientUnblind(b, validOPRFP384Ciphersuite, 1) -} - -func BenchmarkClientOPRFUnblindP384_5(b *testing.B) { - benchClientUnblind(b, validOPRFP384Ciphersuite, 5) -} - -func BenchmarkClientOPRFUnblindP384_10(b *testing.B) { - benchClientUnblind(b, validOPRFP384Ciphersuite, 10) -} - -func BenchmarkClientOPRFUnblindP384_25(b *testing.B) { - benchClientUnblind(b, validOPRFP384Ciphersuite, 25) -} - -func BenchmarkClientOPRFUnblindP384_50(b *testing.B) { - benchClientUnblind(b, validOPRFP384Ciphersuite, 50) -} - -func BenchmarkClientOPRFUnblindP384_100(b *testing.B) { - benchClientUnblind(b, validOPRFP384Ciphersuite, 100) -} - -func BenchmarkClientVOPRFUnblindP384_1(b *testing.B) { - benchClientUnblind(b, validVOPRFP384Ciphersuite, 1) -} - -func BenchmarkClientVOPRFUnblindP384_5(b *testing.B) { - benchClientUnblind(b, validVOPRFP384Ciphersuite, 5) -} - -func BenchmarkClientVOPRFUnblindP384_10(b *testing.B) { - benchClientUnblind(b, validVOPRFP384Ciphersuite, 10) -} - -func BenchmarkClientVOPRFUnblindP384_25(b *testing.B) { - benchClientUnblind(b, validVOPRFP384Ciphersuite, 25) -} - -func BenchmarkClientVOPRFUnblindP384_50(b *testing.B) { - benchClientUnblind(b, validVOPRFP384Ciphersuite, 50) -} - -func BenchmarkClientVOPRFUnblindP384_100(b *testing.B) { - benchClientUnblind(b, validVOPRFP384Ciphersuite, 100) -} - -func BenchmarkClientOPRFUnblindP521_1(b *testing.B) { - benchClientUnblind(b, validOPRFP521Ciphersuite, 1) -} - -func BenchmarkClientOPRFUnblindP521_5(b *testing.B) { - benchClientUnblind(b, validOPRFP521Ciphersuite, 5) -} - -func BenchmarkClientOPRFUnblindP521_10(b *testing.B) { - benchClientUnblind(b, validOPRFP521Ciphersuite, 10) -} - -func BenchmarkClientOPRFUnblindP521_25(b *testing.B) { - benchClientUnblind(b, validOPRFP521Ciphersuite, 25) -} - -func BenchmarkClientOPRFUnblindP521_50(b *testing.B) { - benchClientUnblind(b, validOPRFP521Ciphersuite, 50) -} - -func BenchmarkClientOPRFUnblindP521_100(b *testing.B) { - benchClientUnblind(b, validOPRFP521Ciphersuite, 100) -} - -func BenchmarkClientVOPRFUnblindP521_1(b *testing.B) { - benchClientUnblind(b, validVOPRFP521Ciphersuite, 1) -} - -func BenchmarkClientVOPRFUnblindP521_5(b *testing.B) { - benchClientUnblind(b, validVOPRFP521Ciphersuite, 5) -} - -func BenchmarkClientVOPRFUnblindP521_10(b *testing.B) { - benchClientUnblind(b, validVOPRFP521Ciphersuite, 10) -} - -func BenchmarkClientVOPRFUnblindP521_25(b *testing.B) { - benchClientUnblind(b, validVOPRFP521Ciphersuite, 25) -} - -func BenchmarkClientVOPRFUnblindP521_50(b *testing.B) { - benchClientUnblind(b, validVOPRFP521Ciphersuite, 50) -} - -func BenchmarkClientVOPRFUnblindP521_100(b *testing.B) { - benchClientUnblind(b, validVOPRFP521Ciphersuite, 100) -} - -func BenchmarkClientOPRFUnblindC448_1(b *testing.B) { - benchClientUnblind(b, validOPRFC448Ciphersuite, 1) -} - -func BenchmarkClientOPRFUnblindC448_5(b *testing.B) { - benchClientUnblind(b, validOPRFC448Ciphersuite, 5) -} - -func BenchmarkClientOPRFUnblindC448_10(b *testing.B) { - benchClientUnblind(b, validOPRFC448Ciphersuite, 10) -} - -func BenchmarkClientOPRFUnblindC448_25(b *testing.B) { - benchClientUnblind(b, validOPRFC448Ciphersuite, 25) -} - -func BenchmarkClientOPRFUnblindC448_50(b *testing.B) { - benchClientUnblind(b, validOPRFC448Ciphersuite, 50) -} - -func BenchmarkClientOPRFUnblindC448_100(b *testing.B) { - benchClientUnblind(b, validOPRFC448Ciphersuite, 100) -} - -func BenchmarkClientVOPRFUnblindC448_1(b *testing.B) { - benchClientUnblind(b, validVOPRFC448Ciphersuite, 1) -} - -func BenchmarkClientVOPRFUnblindC448_5(b *testing.B) { - benchClientUnblind(b, validVOPRFC448Ciphersuite, 5) -} - -func BenchmarkClientVOPRFUnblindC448_10(b *testing.B) { - benchClientUnblind(b, validVOPRFC448Ciphersuite, 10) -} - -func BenchmarkClientVOPRFUnblindC448_25(b *testing.B) { - benchClientUnblind(b, validVOPRFC448Ciphersuite, 25) -} - -func BenchmarkClientVOPRFUnblindC448_50(b *testing.B) { - benchClientUnblind(b, validVOPRFC448Ciphersuite, 50) -} - -func BenchmarkClientVOPRFUnblindC448_100(b *testing.B) { - benchClientUnblind(b, validVOPRFC448Ciphersuite, 100) -} - -func benchClientUnblind(b *testing.B, validCiphersuite string, n int) { - c, eval, tokens, blindTokens, _, err := clientSetupUnblind(validCiphersuite, n) - if err != nil { - b.Fatal(err) - } - - // benchmark - for i := 0; i < b.N; i++ { - _, err := c.BatchUnblind(eval, tokens, blindTokens) - if err != nil { - b.Fatal(err) - } - } -} - -func BenchmarkClientFinalizeP384(b *testing.B) { - benchClientFinalize(b, validOPRFP384Ciphersuite) -} - -func BenchmarkClientFinalizeP521(b *testing.B) { - benchClientFinalize(b, validOPRFP521Ciphersuite) -} - -func BenchmarkClientFinalizeC448(b *testing.B) { - benchClientFinalize(b, validOPRFC448Ciphersuite) -} - -func benchClientFinalize(b *testing.B, validCiphersuite string) { - c, err := clientSetup(validCiphersuite) - if err != nil { - b.Fatal(err) - } - pog := c.Ciphersuite().POG() - input := make([]byte, pog.ByteLength()) - rand.Read(input) - info := []byte{6, 7, 8, 9, 10} - unblindedToken, err := pog.HashToGroup(input) - if err != nil { - b.Fatal(err) - } - token := &Token{Data: input} - - // benchmark - for i := 0; i < b.N; i++ { - _, err := c.Finalize(token, unblindedToken, info) - if err != nil { - b.Fatal(err) - } - } -} +// func BenchmarkServerVOPRFEvalP384_100(b *testing.B) { +// benchServerEval(b, gg.OPRF_P384_SHA512, 100) +// } + +// func BenchmarkServerOPRFEvalP521_1(b *testing.B) { +// benchServerEval(b, gg.OPRF_P521_SHA512, 1) +// } + +// func BenchmarkServerOPRFEvalP521_5(b *testing.B) { +// benchServerEval(b, gg.OPRF_P521_SHA512, 5) +// } + +// func BenchmarkServerOPRFEvalP521_10(b *testing.B) { +// benchServerEval(b, gg.OPRF_P521_SHA512, 10) +// } + +// func BenchmarkServerOPRFEvalP521_25(b *testing.B) { +// benchServerEval(b, gg.OPRF_P521_SHA512, 25) +// } + +// func BenchmarkServerOPRFEvalP521_50(b *testing.B) { +// benchServerEval(b, gg.OPRF_P521_SHA512, 50) +// } + +// func BenchmarkServerOPRFEvalP521_100(b *testing.B) { +// benchServerEval(b, gg.OPRF_P521_SHA512, 100) +// } + +// func BenchmarkServerVOPRFEvalP521_1(b *testing.B) { +// benchServerEval(b, gg.OPRF_P521_SHA512, 1) +// } + +// func BenchmarkServerVOPRFEvalP521_5(b *testing.B) { +// benchServerEval(b, gg.OPRF_P521_SHA512, 5) +// } + +// func BenchmarkServerVOPRFEvalP521_10(b *testing.B) { +// benchServerEval(b, gg.OPRF_P521_SHA512, 10) +// } + +// func BenchmarkServerVOPRFEvalP521_25(b *testing.B) { +// benchServerEval(b, gg.OPRF_P521_SHA512, 25) +// } + +// func BenchmarkServerVOPRFEvalP521_50(b *testing.B) { +// benchServerEval(b, gg.OPRF_P521_SHA512, 50) +// } + +// func BenchmarkServerVOPRFEvalP521_100(b *testing.B) { +// benchServerEval(b, gg.OPRF_P521_SHA512, 100) +// } + +// func BenchmarkServerOPRFEvalC448_1(b *testing.B) { +// benchServerEval(b, gg.OPRF_CURVE448_SHA512, 1) +// } + +// func BenchmarkServerOPRFEvalC448_5(b *testing.B) { +// benchServerEval(b, gg.OPRF_CURVE448_SHA512, 5) +// } + +// func BenchmarkServerOPRFEvalC448_10(b *testing.B) { +// benchServerEval(b, gg.OPRF_CURVE448_SHA512, 10) +// } + +// func BenchmarkServerOPRFEvalC448_25(b *testing.B) { +// benchServerEval(b, gg.OPRF_CURVE448_SHA512, 25) +// } + +// func BenchmarkServerOPRFEvalC448_50(b *testing.B) { +// benchServerEval(b, gg.OPRF_CURVE448_SHA512, 50) +// } + +// func BenchmarkServerOPRFEvalC448_100(b *testing.B) { +// benchServerEval(b, gg.OPRF_CURVE448_SHA512, 100) +// } + +// func BenchmarkServerVOPRFEvalC448_1(b *testing.B) { +// benchServerEval(b, gg.OPRF_CURVE448_SHA512, 1) +// } + +// func BenchmarkServerVOPRFEvalC448_5(b *testing.B) { +// benchServerEval(b, gg.OPRF_CURVE448_SHA512, 5) +// } + +// func BenchmarkServerVOPRFEvalC448_10(b *testing.B) { +// benchServerEval(b, gg.OPRF_CURVE448_SHA512, 10) +// } + +// func BenchmarkServerVOPRFEvalC448_25(b *testing.B) { +// benchServerEval(b, gg.OPRF_CURVE448_SHA512, 25) +// } + +// func BenchmarkServerVOPRFEvalC448_50(b *testing.B) { +// benchServerEval(b, gg.OPRF_CURVE448_SHA512, 50) +// } + +// func BenchmarkServerVOPRFEvalC448_100(b *testing.B) { +// benchServerEval(b, gg.OPRF_CURVE448_SHA512, 100) +// } + +// func benchServerEval(b *testing.B, validCiphersuite int, n int) { +// s, _, eles, err := setupServerEval(validCiphersuite, n) +// if err != nil { +// b.Fatal(err) +// } + +// // benchmark +// for i := 0; i < b.N; i++ { +// _, err := s.BatchEvaluate(eles) +// if err != nil { +// b.Fatal(err) +// } +// } +// } + +// func BenchmarkClientBlindP384(b *testing.B) { +// benchClientBlind(b, gg.OPRF_P384_SHA512) +// } + +// func BenchmarkClientBlindP521(b *testing.B) { +// benchClientBlind(b, gg.OPRF_P521_SHA512) +// } + +// func benchClientBlind(b *testing.B, validCiphersuite int) { +// c, err := clientSetup(validCiphersuite) +// if err != nil { +// b.Fatal(err) +// } +// pog := c.Ciphersuite().POG() +// x := make([]byte, pog.ByteLength()) +// rand.Read(x) + +// // benchmark +// for i := 0; i < b.N; i++ { +// _, _, err := c.Blind(x) +// if err != nil { +// b.Fatal(err) +// } +// } +// } + +// func BenchmarkClientOPRFUnblindP384_1(b *testing.B) { +// benchClientUnblind(b, gg.OPRF_P384_SHA512, 1) +// } + +// func BenchmarkClientOPRFUnblindP384_5(b *testing.B) { +// benchClientUnblind(b, gg.OPRF_P384_SHA512, 5) +// } + +// func BenchmarkClientOPRFUnblindP384_10(b *testing.B) { +// benchClientUnblind(b, gg.OPRF_P384_SHA512, 10) +// } + +// func BenchmarkClientOPRFUnblindP384_25(b *testing.B) { +// benchClientUnblind(b, gg.OPRF_P384_SHA512, 25) +// } + +// func BenchmarkClientOPRFUnblindP384_50(b *testing.B) { +// benchClientUnblind(b, gg.OPRF_P384_SHA512, 50) +// } + +// func BenchmarkClientOPRFUnblindP384_100(b *testing.B) { +// benchClientUnblind(b, gg.OPRF_P384_SHA512, 100) +// } + +// func BenchmarkClientVOPRFUnblindP384_1(b *testing.B) { +// benchClientUnblind(b, gg.OPRF_P384_SHA512, 1) +// } + +// func BenchmarkClientVOPRFUnblindP384_5(b *testing.B) { +// benchClientUnblind(b, gg.OPRF_P384_SHA512, 5) +// } + +// func BenchmarkClientVOPRFUnblindP384_10(b *testing.B) { +// benchClientUnblind(b, gg.OPRF_P384_SHA512, 10) +// } + +// func BenchmarkClientVOPRFUnblindP384_25(b *testing.B) { +// benchClientUnblind(b, gg.OPRF_P384_SHA512, 25) +// } + +// func BenchmarkClientVOPRFUnblindP384_50(b *testing.B) { +// benchClientUnblind(b, gg.OPRF_P384_SHA512, 50) +// } + +// func BenchmarkClientVOPRFUnblindP384_100(b *testing.B) { +// benchClientUnblind(b, gg.OPRF_P384_SHA512, 100) +// } + +// func BenchmarkClientOPRFUnblindP521_1(b *testing.B) { +// benchClientUnblind(b, gg.OPRF_P521_SHA512, 1) +// } + +// func BenchmarkClientOPRFUnblindP521_5(b *testing.B) { +// benchClientUnblind(b, gg.OPRF_P521_SHA512, 5) +// } + +// func BenchmarkClientOPRFUnblindP521_10(b *testing.B) { +// benchClientUnblind(b, gg.OPRF_P521_SHA512, 10) +// } + +// func BenchmarkClientOPRFUnblindP521_25(b *testing.B) { +// benchClientUnblind(b, gg.OPRF_P521_SHA512, 25) +// } + +// func BenchmarkClientOPRFUnblindP521_50(b *testing.B) { +// benchClientUnblind(b, gg.OPRF_P521_SHA512, 50) +// } + +// func BenchmarkClientOPRFUnblindP521_100(b *testing.B) { +// benchClientUnblind(b, gg.OPRF_P521_SHA512, 100) +// } + +// func BenchmarkClientVOPRFUnblindP521_1(b *testing.B) { +// benchClientUnblind(b, gg.OPRF_P521_SHA512, 1) +// } + +// func BenchmarkClientVOPRFUnblindP521_5(b *testing.B) { +// benchClientUnblind(b, gg.OPRF_P521_SHA512, 5) +// } + +// func BenchmarkClientVOPRFUnblindP521_10(b *testing.B) { +// benchClientUnblind(b, gg.OPRF_P521_SHA512, 10) +// } + +// func BenchmarkClientVOPRFUnblindP521_25(b *testing.B) { +// benchClientUnblind(b, gg.OPRF_P521_SHA512, 25) +// } + +// func BenchmarkClientVOPRFUnblindP521_50(b *testing.B) { +// benchClientUnblind(b, gg.OPRF_P521_SHA512, 50) +// } + +// func BenchmarkClientVOPRFUnblindP521_100(b *testing.B) { +// benchClientUnblind(b, gg.OPRF_P521_SHA512, 100) +// } + +// func BenchmarkClientOPRFUnblindC448_1(b *testing.B) { +// benchClientUnblind(b, gg.OPRF_CURVE448_SHA512, 1) +// } + +// func BenchmarkClientOPRFUnblindC448_5(b *testing.B) { +// benchClientUnblind(b, gg.OPRF_CURVE448_SHA512, 5) +// } + +// func BenchmarkClientOPRFUnblindC448_10(b *testing.B) { +// benchClientUnblind(b, gg.OPRF_CURVE448_SHA512, 10) +// } + +// func BenchmarkClientOPRFUnblindC448_25(b *testing.B) { +// benchClientUnblind(b, gg.OPRF_CURVE448_SHA512, 25) +// } + +// func BenchmarkClientOPRFUnblindC448_50(b *testing.B) { +// benchClientUnblind(b, gg.OPRF_CURVE448_SHA512, 50) +// } + +// func BenchmarkClientOPRFUnblindC448_100(b *testing.B) { +// benchClientUnblind(b, gg.OPRF_CURVE448_SHA512, 100) +// } + +// func BenchmarkClientVOPRFUnblindC448_1(b *testing.B) { +// benchClientUnblind(b, gg.OPRF_CURVE448_SHA512, 1) +// } + +// func BenchmarkClientVOPRFUnblindC448_5(b *testing.B) { +// benchClientUnblind(b, gg.OPRF_CURVE448_SHA512, 5) +// } + +// func BenchmarkClientVOPRFUnblindC448_10(b *testing.B) { +// benchClientUnblind(b, gg.OPRF_CURVE448_SHA512, 10) +// } + +// func BenchmarkClientVOPRFUnblindC448_25(b *testing.B) { +// benchClientUnblind(b, gg.OPRF_CURVE448_SHA512, 25) +// } + +// func BenchmarkClientVOPRFUnblindC448_50(b *testing.B) { +// benchClientUnblind(b, gg.OPRF_CURVE448_SHA512, 50) +// } + +// func BenchmarkClientVOPRFUnblindC448_100(b *testing.B) { +// benchClientUnblind(b, gg.OPRF_CURVE448_SHA512, 100) +// } + +// func benchClientUnblind(b *testing.B, validCiphersuite int, n int) { +// c, eval, tokens, blindTokens, _, err := clientSetupUnblind(validCiphersuite, n) +// if err != nil { +// b.Fatal(err) +// } + +// // benchmark +// for i := 0; i < b.N; i++ { +// _, err := c.BatchUnblind(eval, tokens, blindTokens) +// if err != nil { +// b.Fatal(err) +// } +// } +// } + +// func BenchmarkClientFinalizeP384(b *testing.B) { +// benchClientFinalize(b, gg.OPRF_P384_SHA512) +// } + +// func BenchmarkClientFinalizeP521(b *testing.B) { +// benchClientFinalize(b, gg.OPRF_P521_SHA512) +// } + +// func BenchmarkClientFinalizeC448(b *testing.B) { +// benchClientFinalize(b, gg.OPRF_CURVE448_SHA512) +// } + +// func benchClientFinalize(b *testing.B, validCiphersuite int) { +// c, err := clientSetup(validCiphersuite) +// if err != nil { +// b.Fatal(err) +// } +// pog := c.Ciphersuite().POG() +// input := make([]byte, pog.ByteLength()) +// rand.Read(input) +// info := []byte{6, 7, 8, 9, 10} +// unblindedToken, err := pog.HashToGroup(input) +// if err != nil { +// b.Fatal(err) +// } +// token := &Token{Data: input} + +// // benchmark +// for i := 0; i < b.N; i++ { +// _, err := c.Finalize(token, unblindedToken, info) +// if err != nil { +// b.Fatal(err) +// } +// } +// } diff --git a/go/oprf/utils/conversion.go b/go/oprf/utils/conversion.go index 12cc8a9..7c9fe4c 100644 --- a/go/oprf/utils/conversion.go +++ b/go/oprf/utils/conversion.go @@ -35,8 +35,6 @@ type serializer interface { func ByteSliceLengthPrefixed(vals ...interface{}) ([]byte, error) { result := make([]byte, 0) - fmt.Printf("vals %v\n", vals) - var raw, prefix []byte var err error for _, val := range vals { diff --git a/go/server/server.go b/go/server/server.go index c38a502..f2c7857 100644 --- a/go/server/server.go +++ b/go/server/server.go @@ -31,7 +31,7 @@ type Config struct { } // CreateConfig returns a HTTP Server object -func CreateConfig(ciphersuite string, pogInit gg.PrimeOrderGroup, max int, tls bool, testIndex int) (*Config, error) { +func CreateConfig(ciphersuite int, pogInit gg.PrimeOrderGroup, max int, tls bool, testIndex int) (*Config, error) { ptpnt, err := oprf.Server{}.Setup(ciphersuite, pogInit) if err != nil { return nil, err @@ -59,7 +59,7 @@ func CreateConfig(ciphersuite string, pogInit gg.PrimeOrderGroup, max int, tls b // when running in test mode we use fixed test vectors if test { - bytes, err := ioutil.ReadFile(fmt.Sprintf("../test-vectors/%s.json", ciphersuite)) + bytes, err := ioutil.ReadFile(fmt.Sprintf("../test-vectors/%v.json", ciphersuite)) if err != nil { return nil, err } @@ -139,7 +139,7 @@ func (cfg *Config) processJSONRPCRequest(jsonReq *jsonrpc.Request) (map[string][ params := jsonReq.Params // if the ciphersuite is empty then just attempt to evaluate ciph := params.Ciphersuite - if ciph != cfg.osrv.Ciphersuite().Name() { + if ciph != cfg.osrv.Ciphersuite().ID() { fmt.Println(ciph) fmt.Println(cfg.osrv.Ciphersuite().Name()) return nil, oerr.ErrJSONRPCInvalidMethodParams @@ -208,7 +208,7 @@ func (cfg *Config) processEval(params []string) (map[string][][]byte, error) { } // print out DLEQ scalar - if osrv.Ciphersuite().Verifiable() { + if osrv.Verifiable() { k := osrv.SecretKey().K c := eval.Proof.C s := eval.Proof.S @@ -228,7 +228,7 @@ func (cfg *Config) processEval(params []string) (map[string][][]byte, error) { // serialize proof object if the ciphersuite indicates verifiability serializedProof := make([][]byte, 2) - if cfg.osrv.Ciphersuite().Verifiable() { + if cfg.osrv.Verifiable() { serializedProof = eval.Proof.Serialize() } diff --git a/go/server/server_test.go b/go/server/server_test.go index 6612c0c..0898072 100644 --- a/go/server/server_test.go +++ b/go/server/server_test.go @@ -13,26 +13,20 @@ import ( "github.com/stretchr/testify/assert" ) -var ( - validOPRFP384Ciphersuite = "OPRF-P384-HKDF-SHA512-SSWU-RO" - validOPRFP521Ciphersuite = "OPRF-P521-HKDF-SHA512-SSWU-RO" - validOPRFC448Ciphersuite = "OPRF-curve448-HKDF-SHA512-ELL2-RO" -) - func TestProcessEvalP384(t *testing.T) { - processOPRFEval(t, validOPRFP384Ciphersuite, 5) + processOPRFEval(t, gg.OPRF_P384_SHA512, 5) } func TestProcessEvalP521(t *testing.T) { - processOPRFEval(t, validOPRFP521Ciphersuite, 5) + processOPRFEval(t, gg.OPRF_P521_SHA512, 5) } func TestProcessEvalC448(t *testing.T) { - processOPRFEval(t, validOPRFC448Ciphersuite, 5) + processOPRFEval(t, gg.OPRF_CURVE448_SHA512, 5) } func TestProcessEvalMaxError(t *testing.T) { - cfg, err := CreateConfig(validOPRFP384Ciphersuite, ecgroup.GroupCurve{}, 3, false, -1) + cfg, err := CreateConfig(gg.OPRF_P384_SHA512, ecgroup.GroupCurve{}, 3, false, -1) if err != nil { t.Fatal(err) } @@ -58,7 +52,7 @@ func TestProcessEvalMaxError(t *testing.T) { } func TestCreateConfigP384(t *testing.T) { - cfg, err := CreateConfig(validOPRFP384Ciphersuite, ecgroup.GroupCurve{}, 5, false, -1) + cfg, err := CreateConfig(gg.OPRF_P384_SHA512, ecgroup.GroupCurve{}, 5, false, -1) if err != nil { t.Fatal(err) } @@ -66,7 +60,7 @@ func TestCreateConfigP384(t *testing.T) { } func TestCreateConfigP521(t *testing.T) { - cfg, err := CreateConfig(validOPRFP521Ciphersuite, ecgroup.GroupCurve{}, 5, false, -1) + cfg, err := CreateConfig(gg.OPRF_P521_SHA512, ecgroup.GroupCurve{}, 5, false, -1) if err != nil { t.Fatal(err) } @@ -74,7 +68,7 @@ func TestCreateConfigP521(t *testing.T) { } func TestCreateConfigC448(t *testing.T) { - cfg, err := CreateConfig(validOPRFC448Ciphersuite, ecgroup.GroupCurve{}, 5, false, -1) + cfg, err := CreateConfig(gg.OPRF_CURVE448_SHA512, ecgroup.GroupCurve{}, 5, false, -1) if err != nil { t.Fatal(err) } @@ -82,14 +76,14 @@ func TestCreateConfigC448(t *testing.T) { } func TestCreateConfigBadCiph(t *testing.T) { - _, err := CreateConfig("OPRF-P521-HKDF-SHA256-SSWU-RO", ecgroup.GroupCurve{}, 5, false, -1) - if !errors.Is(err, oerr.ErrUnsupportedHash) { - t.Fatal("Error should have occurred (bad hash in ciphersuite)") + _, err := CreateConfig(gg.OPRF_INVALID_CIPHERSUITE, ecgroup.GroupCurve{}, 5, false, -1) + if !errors.Is(err, oerr.ErrUnsupportedCiphersuite) { + t.Fatal("Error should have occurred (bad ciphersuite)") } } func TestProcessValidJSONRPCRequest(t *testing.T) { - cfg, err := CreateConfig(validOPRFP384Ciphersuite, ecgroup.GroupCurve{}, 5, false, -1) + cfg, err := CreateConfig(gg.OPRF_P384_SHA512, ecgroup.GroupCurve{}, 5, false, -1) if err != nil { t.Fatal(err) } @@ -105,7 +99,7 @@ func TestProcessValidJSONRPCRequest(t *testing.T) { jsonrpcReq := &jsonrpc.Request{ Version: version2, Method: "eval", - Params: jsonrpc.RequestParams{Data: []string{hex.EncodeToString(buf)}, Ciphersuite: validOPRFP384Ciphersuite}, + Params: jsonrpc.RequestParams{Data: []string{hex.EncodeToString(buf)}, Ciphersuite: gg.OPRF_P384_SHA512}, ID: 1, } // actual value checks are done in other tests @@ -120,7 +114,7 @@ func TestProcessValidJSONRPCRequest(t *testing.T) { } func TestInvalidJSONRPCRequestMethod(t *testing.T) { - cfg, err := CreateConfig(validOPRFP384Ciphersuite, ecgroup.GroupCurve{}, 5, false, -1) + cfg, err := CreateConfig(gg.OPRF_P384_SHA512, ecgroup.GroupCurve{}, 5, false, -1) if err != nil { t.Fatal(err) } @@ -135,7 +129,7 @@ func TestInvalidJSONRPCRequestMethod(t *testing.T) { jsonrpcReq := &jsonrpc.Request{ Version: version2, Method: "bad_method", - Params: jsonrpc.RequestParams{Data: []string{hex.EncodeToString(buf)}, Ciphersuite: validOPRFP384Ciphersuite}, + Params: jsonrpc.RequestParams{Data: []string{hex.EncodeToString(buf)}, Ciphersuite: gg.OPRF_P384_SHA512}, ID: 1, } // actual value checks are done in other tests @@ -146,7 +140,7 @@ func TestInvalidJSONRPCRequestMethod(t *testing.T) { } func TestInvalidJSONRPCRequestVersion(t *testing.T) { - cfg, err := CreateConfig(validOPRFP384Ciphersuite, ecgroup.GroupCurve{}, 5, false, -1) + cfg, err := CreateConfig(gg.OPRF_P384_SHA512, ecgroup.GroupCurve{}, 5, false, -1) if err != nil { t.Fatal(err) } @@ -172,7 +166,7 @@ func TestInvalidJSONRPCRequestVersion(t *testing.T) { } func TestInvalidJSONRPCRequestEmptyParams(t *testing.T) { - cfg, err := CreateConfig(validOPRFP384Ciphersuite, ecgroup.GroupCurve{}, 5, false, -1) + cfg, err := CreateConfig(gg.OPRF_P384_SHA512, ecgroup.GroupCurve{}, 5, false, -1) if err != nil { t.Fatal(err) } @@ -190,7 +184,7 @@ func TestInvalidJSONRPCRequestEmptyParams(t *testing.T) { } func TestInvalidJSONRPCRequestNoCiphersuite(t *testing.T) { - cfg, err := CreateConfig(validOPRFP384Ciphersuite, ecgroup.GroupCurve{}, 5, false, -1) + cfg, err := CreateConfig(gg.OPRF_P384_SHA512, ecgroup.GroupCurve{}, 5, false, -1) if err != nil { t.Fatal(err) } @@ -218,7 +212,7 @@ func TestInvalidJSONRPCRequestNoCiphersuite(t *testing.T) { } func TestInvalidJSONRPCRequestInvalidCiphersuite(t *testing.T) { - cfg, err := CreateConfig(validOPRFP384Ciphersuite, ecgroup.GroupCurve{}, 5, false, -1) + cfg, err := CreateConfig(gg.OPRF_P384_SHA512, ecgroup.GroupCurve{}, 5, false, -1) if err != nil { t.Fatal(err) } @@ -234,7 +228,7 @@ func TestInvalidJSONRPCRequestInvalidCiphersuite(t *testing.T) { jsonrpcReq := &jsonrpc.Request{ Version: version2, Method: "eval", - Params: jsonrpc.RequestParams{Data: []string{hex.EncodeToString(buf)}, Ciphersuite: validOPRFP521Ciphersuite}, + Params: jsonrpc.RequestParams{Data: []string{hex.EncodeToString(buf)}, Ciphersuite: gg.OPRF_P521_SHA512}, ID: 1, } // actual value checks are done in other tests @@ -246,7 +240,7 @@ func TestInvalidJSONRPCRequestInvalidCiphersuite(t *testing.T) { } func TestInvalidJSONRPCRequestBadlyEncodedParam(t *testing.T) { - cfg, err := CreateConfig(validOPRFP384Ciphersuite, ecgroup.GroupCurve{}, 5, false, -1) + cfg, err := CreateConfig(gg.OPRF_P384_SHA512, ecgroup.GroupCurve{}, 5, false, -1) if err != nil { t.Fatal(err) } @@ -265,14 +259,14 @@ func TestInvalidJSONRPCRequestBadlyEncodedParam(t *testing.T) { } func TestInvalidJSONRPCRequestBadParams(t *testing.T) { - cfg, err := CreateConfig(validOPRFP384Ciphersuite, ecgroup.GroupCurve{}, 5, false, -1) + cfg, err := CreateConfig(gg.OPRF_P384_SHA512, ecgroup.GroupCurve{}, 5, false, -1) if err != nil { t.Fatal(err) } jsonrpcReq := &jsonrpc.Request{ Version: version2, Method: "eval", - Params: jsonrpc.RequestParams{Data: []string{hex.EncodeToString([]byte("bad_byte_string"))}, Ciphersuite: validOPRFP384Ciphersuite}, + Params: jsonrpc.RequestParams{Data: []string{hex.EncodeToString([]byte("bad_byte_string"))}, Ciphersuite: gg.OPRF_P384_SHA512}, ID: 1, } // actual value checks are done in other tests @@ -283,7 +277,7 @@ func TestInvalidJSONRPCRequestBadParams(t *testing.T) { } } -func processOPRFEval(t *testing.T, validCiphersuite string, n int) { +func processOPRFEval(t *testing.T, validCiphersuite int, n int) { cfg, err := CreateConfig(validCiphersuite, ecgroup.GroupCurve{}, n, false, -1) if err != nil { t.Fatal(err) diff --git a/go/vectors/allVectors.json b/go/vectors/allVectors.json new file mode 100644 index 0000000..c8d9664 --- /dev/null +++ b/go/vectors/allVectors.json @@ -0,0 +1,260 @@ +{ + "BaseOPRF-P256-HKDF-SHA512-SSWU-RO": { + "info": "test information", + "skS": "0xa4bc754ee3d4fc7d183216738fe034fc2c7169dc589dde348bd6e83a63d2fdd7", + "suite": "OPRF-P256-HKDF-SHA512-SSWU-RO", + "vectors": [ + { + "BlindedElement": "0x03b7fad21bb9fa3bed116474907f8620c1d19b4c0943879d3ae4ebf930106fe98a", + "ClientInput": "0x00", + "ClientOutput": "0x02135c2e9bbf7dde0954e89687ccb04da133a2e33b30df5172ed2212096a83ab9a91e900c9afb38db2ecf54f9ee7e6465836e23d39ac23f46c26813b12b64eb2", + "Evaluation": { + "EvaluatedElement": "0x024ff4d1e71558cb6421070352f72de89fd9680c1df93804a7617135a378bde4c4" + }, + "SignedElement": "0x0207578f8fe20ddab08ae8f3f2e0965cd74b323bf2bc8af5bc22da36c675cf7c90", + "UnblindedElement": "0x0262b3647f9b8755747c037a0cbd97bf842ad3b5f8333341bc688c2da81bede239" + }, + { + "BlindedElement": "0x021d50949a4bf9fcc6054c38e5ef541529411b58871f6374f44380cb5025277efd", + "ClientInput": "0x01", + "ClientOutput": "0x675b03fb12f24198ceb3d9ff6f611102191e33a456a53a06b3b47fc2d19c4a3a777ada1cdcdd919fee0c861460aec73fc06859bcafb28e4401b6ca2624cdbd0e", + "Evaluation": { + "EvaluatedElement": "0x0265772dfde2b13d696f0c0ad00a7f3c2e6e784df14469e3ed5115f3adb01766d8" + }, + "SignedElement": "0x0352426487657b28e89b26d2c35119ee04b1ffba905f7ad3f8c05acbb28dc39811", + "UnblindedElement": "0x0300ca6c0edf6be1aba43feb6c7ecf5f7a70c0895020556841c31f29b888f3e21f" + }, + { + "BlindedElement": "0x03c6a5771e5948a945d9c2a3a6fcf67f0d731b6703f1deaea6f033ccb3b7510294", + "ClientInput": "0x02", + "ClientOutput": "0x17a93ebaad76cd3d2a7adaf38a893abd684911a736100f6faa0e45383e814acb35668a6b8395d431cf639cc2c89345c6fc3e607a84fd857be3af31418397f2b3", + "Evaluation": { + "EvaluatedElement": "0x0200e761ed9a0799aad6a22ba7012e6312b45cdd74d1fa3739eea91f79d135b75c" + }, + "SignedElement": "0x035988e25b8e3f7d4b49030bc1d862fa244b0e0b05cccecebfb985b7038cf363d5", + "UnblindedElement": "0x037e107ad4a33543e6e16a5a8006e63195cd83e821412abad4fb7d6d27ac68cafb" + } + ] + }, + "BaseOPRF-P384-HKDF-SHA512-SSWU-RO": { + "info": "test information", + "skS": "0xe42ec5a853c34d43547202d4acc6bbb2e6466e33b783ac23a3834eebdf113c6d532c03847864c13337fc30ead4180a34", + "suite": "OPRF-P384-HKDF-SHA512-SSWU-RO", + "vectors": [ + { + "BlindedElement": "0x0355b00aadfec96dec1c1b9188134e7164672eddd177e98b6638105ae5074800aefa5997f9aa56c226186893990d5306a0", + "ClientInput": "0x00", + "ClientOutput": "0x1eaef2b086b509ea0a1360eb14e347310a5f35dcb93e97b756125f3844bcfe509d77f10e5c3b86771dde950573fe7ef386edd9809d88bc739ac8f2152d84f39a", + "Evaluation": { + "EvaluatedElement": "0x02c09be4a30b048b1f7165a5592760b92adb729c8c3ce5b6adf06f1a3591d05d98eb1bed7e0d358847c3ede307210814e9" + }, + "SignedElement": "0x03dfed0d602b7329c432c0409468fdb5a8879439f9d0b012bc4aa791a9f251bfd0a38333673344be235513d36cdb1e330d", + "UnblindedElement": "0x0258a6e0d75ea8a8aaf2560dbdf7a1e6a292cb0511c89accee19e4ecf90b0d0786e36a3f9cee55bac33b76882165ed5bde" + }, + { + "BlindedElement": "0x02d1d8f032c801d371288d8eb0621a638393b90648e6b163f31903b8d1e4c7fdec4e4324ef51bcacdc9ab9b4600745db4a", + "ClientInput": "0x01", + "ClientOutput": "0xa55fe7a879292adef1d147fd1d20e03934c42540bbe547fd7dfc1adb13b547a2bd09436f4efb1ee7977cd308ef86ec5179b5a8d7002be40634f7c9a7c58886bd", + "Evaluation": { + "EvaluatedElement": "0x02e7c93d48669d37a08e96d2766a2dc91a18b09a58301879f41a8a8a4ce2cc46429496c95251b1617ac4ea303c879ec420" + }, + "SignedElement": "0x0381746432fcac75e57b0bfab7930de2431b7e8ea40cc2e6ead75358c9294b0a29fc829288e30880360f30eb5c44cb741a", + "UnblindedElement": "0x03d61e1c567d2cf1ada1fc29783557b518cd83c6eb94de1b28089f2d7d93480a27e6fd04cd0eb788b7a66cb3e69edcd330" + }, + { + "BlindedElement": "0x0331a28b0d7ac2c33ad5bcf9def538b33c31b15e642d0e9608f58e40b2debb120ab4cd644023d85460f8609d3e3ecaad67", + "ClientInput": "0x02", + "ClientOutput": "0x73251414f317183fc19fd5eb904585ebff5dde15335914b2a0a6a386eb7eebb2e8a8f2ac544c2b4ca1a2ae3315740e7c6588438f03a21e8b0eec5f09cc9569d7", + "Evaluation": { + "EvaluatedElement": "0x0299d47039f06ed642d3da7afeb581f7597dc645a1b94d0c1a4648840a3bf96dac22296b85d899317889adcd47d7497cf8" + }, + "SignedElement": "0x03c5a3f08040f230debe9d36105d72b15b2208ba6c0b4762e930d9cc7ff0f6321cc8169c94f82159342f6a19b3172409c5", + "UnblindedElement": "0x03632f598b61fb27e9c9df77066e770eff6493c38956b02024e85ee52321f404e7f428d9e931429263ff4deac1f7f335eb" + } + ] + }, + "BaseOPRF-P521-HKDF-SHA512-SSWU-RO": { + "info": "test information", + "skS": "0x1125387ae7faebb5be1c2e50e8d83b1756cffe9d5731557454350eeab5debf2b7b1af36f74c8340baa364eb15fbcca00a231dc683264121f2c50faae65bdc6e7753", + "suite": "OPRF-P521-HKDF-SHA512-SSWU-RO", + "vectors": [ + { + "BlindedElement": "0x0201729cae0406581307747cb393e375bd0ffb76731030c55215cd4b20bd92587bfe437493e7c9e9148096ddc5bf26a7a3a8021371e0a97322634309f66fca3fc12e36", + "ClientInput": "0x00", + "ClientOutput": "0x5ac18d3d2247b5d462921fafb51e4bb41e35a435f6bd0dd0ca2879608afb271ecc1f37a4af7ccd41ee6d765086f116abacdfa57f4ad7f3c880a31656fb43e661", + "Evaluation": { + "EvaluatedElement": "0x03016fd54429ace73fb82042c50224a3d269b372c8f20d83f54e74c9f63de7667f29794a3e264daffb5812a1747c9b953a46f38d639a333fa6546d5d21b410d09c7344" + }, + "SignedElement": "0x020012003358f309fd1b8e55fe51f44b542aa1b8924909e857e3b158817d67e454b5f3bee5cc6b467aa717f87cb902fd7c68a32fdef85016f56c6319ead5a2e9975a28", + "UnblindedElement": "0x02019f954d0c04455356a64297b6e42e10d5c116a26c29bc9b0030fb2e0704a3ad3352c5760741496ea978b721098bc40b73db853722006d4a7a02208ede8534eaa734" + }, + { + "BlindedElement": "0x0201023510200772d6ef42dd5468aff64caa460e1259762c03714809688f573041668cad76fe2cf4dc749f64c6808331745684b216b444759d56ac8ea9df445a4f5fcc", + "ClientInput": "0x01", + "ClientOutput": "0x2eb67d35cfbc10ff007c38ccddefdc2f111ecd01218df4a195f3d982d303a18bb42caf8bbc2c05a9b5ec9be26388c04ca5da36476c5f2f4a376926dbd0d8f653", + "Evaluation": { + "EvaluatedElement": "0x02004300a12057da73b48cd6d1e52ec023736213940b9664066301f60c2f5f8f3cc8693997a38df7c310471628d3739f06f0a3840797686a265dcd1b9d95b131e97196" + }, + "SignedElement": "0x02011df1d4e580a156272f39dd08f1e3014d04978795fc655ef85c8f3907b959715ed17b3bdaa640bf246a27edaed589f4679a6ef0343dd042e9f5f40ac86cf2937d63", + "UnblindedElement": "0x02004dd7eeac040cf1137a04c783d8f4ca292b9543e8256248d45f1f0377f90bd6329c9e7b57401306faabadb4a49edff5bb1add095f597b4a222508a1df570c4dde0c" + }, + { + "BlindedElement": "0x020090fdeb6f2d114d76f19d1f3391f081974e4ebad5ca435fab6af5dc0e622bc99f5172196a4343ae9b8af56074ac3144417a6e590849e1ccefd3b436a3ca492e2db0", + "ClientInput": "0x02", + "ClientOutput": "0xe56e6d95285f24aa0cf7693fa08b93d045cd788362d7b82b2d9b3b1d18b7199e7649e547de0599b005512f0f213d0f74eea8eb904b227110f9b5d3c68634a2a7", + "Evaluation": { + "EvaluatedElement": "0x0301f12f0c2f90d454859a7a24e55c044e7b3c330322d1d66fbec30e48fe2dcbbe934e7c94a5e986fba812d6b4b758e0357249b50930de2f5c565919d7644916d09a29" + }, + "SignedElement": "0x0301054e37bb35fa5ea5c0e8e57ccbe5f91da798ac00c1fc3f0a7b300a10d1bbdeb224099e8d0f4b3fccd75df13c7ed7fc2734ac0a02ba00567a6436f2fba4c7b6c523", + "UnblindedElement": "0x0300a5d42ebdadd14f9e7fcf0f137d78c1ae596d8090d6833b72e9a4defb36427b87f8b292ee4b91e3d9e113f9581560c835ca94324178606e37e1ea2602c0bc2247b4" + } + ] + }, + "VerifiableOPRF-P256-HKDF-SHA512-SSWU-RO": { + "info": "test information", + "skS": "0xc8b58df3499811162a2bb8de951fb39ec1978c1ba0230be42b1c5a9c23232256", + "suite": "OPRF-P256-HKDF-SHA512-SSWU-RO", + "vectors": [ + { + "BlindedElement": "0x03f00a653b01c0ac7750e70e32a473aafe4264cbdbe4a8327a10d839bbf28f2190", + "ClientInput": "0x00", + "ClientOutput": "0xcde95ccaa9415223acb371da92c03b5a159361cef21479cf1046783deea68057f56495adef798ab7ac6418f9c9e83174230c70594e4933fbb3e7a0d9e6ac3ee2", + "Evaluation": { + "EvaluatedElement": "0x02dbbbf1b6a87ad0ee9a8fa295a24948cb905a5bd41e5d98c7b7e2ab220956e6d8", + "proof": { + "c": "0xffb943847874fe082922e5191896ca14e0e2019cf02bc970171453e20a33e42a", + "s": "0x98ec4c2ca20a52bb4451d3abf15edd7109f7db213721aa20e34686ee44b83c3a" + } + }, + "SignedElement": "0x02fcdded3a6fbffe7c455c6dd8c18b513bf3e0d2a5a92105c4321ca459be547ce4", + "UnblindedElement": "0x037cb37779f3973106511a45abd1f90e73a699580a1c3dbac1bdbc75a2c77b3d35" + }, + { + "BlindedElement": "0x0258034c9f5fcc0f1b029224771effed00c4414eba7cae8ef8268ac2135423d014", + "ClientInput": "0x01", + "ClientOutput": "0x1fbe7f078f6356143b3844c73b010057b6a6d6ddb5114785b751963c8275312fdb4795fa2550b374b60a35254a737dc855c42e71dd79b603c237c908b88056c9", + "Evaluation": { + "EvaluatedElement": "0x02302609884133f06c494839d5fba8891b02e9e1cb823c62ec74cc19aaf237c14a", + "proof": { + "c": "0x5217347755e121df3a3a3e610b629f3718e0d79b57f931cc81fcf1affedf7ac3", + "s": "0xc78c36beac5d58809f61be729cde75a914e8d7fd50fa5ea3cbed9882fcdc97b2" + } + }, + "SignedElement": "0x03ccc95aab1ea4b2498dcf2c5a0edb615557757875b573907125d3bf663e365fce", + "UnblindedElement": "0x02caa05b5e4ccaf57483b450bea15df404d6e482bb48e7ce35675057ffe4e2316e" + }, + { + "BlindedElement": "0x0384a8c29f5713038554c8b34b82671230444b2270bbf787eb1a955a524ad03cdf", + "ClientInput": "0x02", + "ClientOutput": "0xfb0e9d52e4587998cf50ab665d9e1ed87ec24a9853d0e12386741dc2aa53cd8ce7443db3bc5c5b72411818b852d2db008600f509ec0aba6748b16be2da3bef48", + "Evaluation": { + "EvaluatedElement": "0x02e87fc27b7bd06f64cd1dc2bb7620fdb3cd6eeeed18e369ee37be8ecf14ed9097", + "proof": { + "c": "0xeef53c7c3687361e0e8054b289c3116b0c275a89af9f6ffc2125b0d01a2ba40f", + "s": "0xf02288a3eb98654ad30e604f63f155e581869f6b49ef4a4173a5270ea0b330f" + } + }, + "SignedElement": "0x0396f295e41c0a2e3823b7220a59f838ef30e61f1c3c8bb294367bfffff71dac9f", + "UnblindedElement": "0x028bb6ea9fee6805ce8e1935ae3f76cdfac77552725a470a5715abc53fc480d4fb" + } + ] + }, + "VerifiableOPRF-P384-HKDF-SHA512-SSWU-RO": { + "info": "test information", + "skS": "0x47c9418d54a0f112afd1cd3dfd16e5ebb3560075f71e619d58f5286b96a1c1b07b87513803c28b351302bf20fb69ef90", + "suite": "OPRF-P384-HKDF-SHA512-SSWU-RO", + "vectors": [ + { + "BlindedElement": "0x037d35310b79ee0bf55dd335faaf5176eb5c395fbfb1562bfbc7c0795f6f408c5cefa68e3da46ac377effc8fc4fda8212a", + "ClientInput": "0x00", + "ClientOutput": "0x615349facf607d795bf3877db50b61d04133fd5812e185437a407698ca8beb436e5be4ae455953ad3f3ba2ff01f58683fbd29e70c4e3795935580da276c49682", + "Evaluation": { + "EvaluatedElement": "0x0326cca193c02c722f0cad4c64a8458801125679086d4e71a2c587ffab752f0d43db1a26d000be7c42957337f5cc677596", + "proof": { + "c": "0x32cca69d512d34011cd8dcc3c5e5913fae9bb96072334722741683b08d7b7412d42f8c058a1334a5ffbe66ee9f0f80c", + "s": "0xaeb6ca6051ce6ccc0b4a11b66e3546854e072c3f499dd9bd5926806ec7579894883a8ca65f5bebd36d0a6c7d0ab50413" + } + }, + "SignedElement": "0x03816542dd9b52e637e3ea5e373ee2542df13773c4c38c164b6ab5122fb80d83f926d39d8a8dd396ce2a7d9e7d91e2780b", + "UnblindedElement": "0x02483e7dba4b628a480f11352e4da402eb624c897fe18b2ae6b6435fc647df65ddc73875bf999c19082e7bcbbe898c39ce" + }, + { + "BlindedElement": "0x0286247c507834cc7e9f68f4cfb573b76bb3dd2d97c9ffedb32bdb4b982daacafa4c35d8cf4bf6c149d2d0e2d6583da7be", + "ClientInput": "0x01", + "ClientOutput": "0xf114c381963e9a9e8f2d5b400e7f3028b6071dd05ade364b76116473f35b3d6c35dabf126ba9b94bb0ca4656ef75c41ed0e223366b847f8c8ec3b704f0def99b", + "Evaluation": { + "EvaluatedElement": "0x02199940fecf823addce4d3a918d9b8ce577207277e495e9a549836d28828d8717c5b4331bb50cc075bdbee852eb4cf08b", + "proof": { + "c": "0x4e95b2f636b228cf41b97a4e28c1357ea6871fbea5a3bab3827bb7cd07d9758db62fa04836b5b3da2ee3993f1af9ac1d", + "s": "0x8de04e130817224edace43f7d1b02780b236f09bfca7ac6cc572d8dac1bb9dfe321e69bb2d073710cb43838d14498d4c" + } + }, + "SignedElement": "0x028459ed6bdd7adf30f2db8e43241d95d4533d40decde886ca14ed7c196c951310eb751037aab9a0cbaa3db7a4f8f5633e", + "UnblindedElement": "0x0306332d1a27a12bcd32238f47305061161d501fdc58e3ba02ad6528dd3261746be681d482f19a65620937590e27ae3d72" + }, + { + "BlindedElement": "0x031b309bd30c2ac89371af2e643eb71da1b4584870052c71b57abb832c9ddcab98818e1852ec67ee3993f642cb192fdd8a", + "ClientInput": "0x02", + "ClientOutput": "0x870dcc0870bb8abab0a1cd6ad78daedbf0862c291e9278a41ccef925e1d60ff420cea3294370a7f750efecae679daf88477ed901500db849f7eadd58d7603338", + "Evaluation": { + "EvaluatedElement": "0x02113503abcd72c7f66c6ad533cf0126f51e3b1074f50188371b3135236126a55293e15f961fea58e2c082b8e210637bae", + "proof": { + "c": "0x374d4d4f00b3388b523570a315abb20139afc12c75dfa8f263a41a7f1d1cfe3eeb6344eaf135b8f9bc7691dba82aa060", + "s": "0x52436e958ff7519a239ac02df4a3923d31e1490c6aadee20c02f37594bc59440534d136caa1f0fbe9c5162250f55e4da" + } + }, + "SignedElement": "0x0365ec2e8836649e5e6cbf359698e739863816458a47203e60aa3e9659b46392e486987b1cd76bd5fd58eabcc88b6579dd", + "UnblindedElement": "0x038bbd87d629d9c6a7abc69ef0ec911cc21a1984d4f75933c08298bed2cf6074899f5c92ca076424fb285bac2c1807bb14" + } + ] + }, + "VerifiableOPRF-P521-HKDF-SHA512-SSWU-RO": { + "info": "test information", + "skS": "0x192883db55a1bd0b5ee523f3fad82b747af2dd3691042fce21e3a37a1526eb1636fae6d31d0b1fd519bce1c3d1271d847ce297c8b00d2b1a984a1b9d778a516f051", + "suite": "OPRF-P521-HKDF-SHA512-SSWU-RO", + "vectors": [ + { + "BlindedElement": "0x0301fe40e793f0f454a642455b413987a51ceddc7a70e1fd53ba4111cee1aa0a151896c7f5aa4b708185b9b7c56e904493600f696f5ff95370ad364f117b55781f02b1", + "ClientInput": "0x00", + "ClientOutput": "0x9cdf2a4f8070d7effdb76380443d7a496e45afd0dc850716a34c72ec4fa2f9dffc465a3cfe89da781eefdb589f847985f6205a9ba4f6e7b25a0dcc67f81db690", + "Evaluation": { + "EvaluatedElement": "0x02010d6e7d3dbc9830c97821fbe66980548313d21a835eee8b4308ae0736deb4507d78f5e9ed17c4a268fef36527477235c5e4c6015cf85f8cde0f351a71bfbfcc538f", + "proof": { + "c": "0x1c49dc28bc5bf08425faa7289462cfe76ae4ccbc54c91bf99e48bd6b3c9078f59b6f9fea37b8f4c243df441680f0332e3c36efc75b726166c24f8684284ba0b5889", + "s": "0x6f5ae9c377e7a15415df08d772a2900326520fcd9157f2cfa50d7ef87288f3b4ae0ba646de27d89a53e111d83902da90f50fd98a36c7aa9c22c5c4fcfb6514d596" + } + }, + "SignedElement": "0x030078b4eac2c1da703a1af048dc60a5de912e9c1b92fd1a25d80a0282c25f88cf8a6a60c1e897203993c183db177d3ad3bf2135f4be6bb4e36b8d9818b7b2b2b8b9d7", + "UnblindedElement": "0x0300f2306ec1aa6cbdc922c5ae99218cab1d304966ac89391c12c3c090ca16b6fc445c96d09e276eb73082607a8f2f58e5791990068cee556b012bf192cab01715e8ea" + }, + { + "BlindedElement": "0x03019383fb042c542b2c20f203370ba6d3297d8ecfe843fa15a730d939531e1d285341a103c59c11f07b0a8c951b1c296924b69ce5d52b96e8641d5036a54026cf2d2a", + "ClientInput": "0x01", + "ClientOutput": "0x6e70190ebe34246354a2dcbc388f768e2c70309d4b9bd981c36106ad4817435a1238d0d50b645c7567f7212aee2075161f1460a50462fd1ae9bc3c048313df14", + "Evaluation": { + "EvaluatedElement": "0x0300511a90c9c8e69cef7de850aa2bff9e34503a5c11e4087b8ab7ab0ea4aee3a835474ba20c238ea4fd385e5627e4859cb560e72d92ff19460f543b0778e94a0ed799", + "proof": { + "c": "0xde184f0ae226db2ea5a7309b7964b5908305c11acdea9798a86bd601a9b3fe24d944ae14b9730239d5b943fa499bde2cf8346cec4799dd3a3f759044963239943d", + "s": "0x1d1b438019774fe6c7bcec19cc13471c1b5dc0804520dcd2a87915d179c0c479eab736792fc0fbf7cc250f27c952a4b884f6abdec1565e755ea26ed6f2d1614d7de" + } + }, + "SignedElement": "0x03001052d29d76d18c878e8772b0bebaa200a71cee5864ac162afb3ab98ae9974e57fb672dc89966a8b9e37d841979306f8fdad491c4a5860f76a261267aef4a03998f", + "UnblindedElement": "0x0301e181da86e1c8c1c9788df4504c7eed5e6d895e9edbe559ece08c2bfcb73ba99b3bbbfd9a1cc67628d6d695ea21c26063404b08c825bc23cc66f7aa3a72a6b811a1" + }, + { + "BlindedElement": "0x0201e47d33e09df79c84105da42d34635cb00772e79470ced67ffef32babd732d87058b19dc0682505dda33611d96e40da2b0b25df406431d94d0506b023d20bf7f08e", + "ClientInput": "0x02", + "ClientOutput": "0x63b31a552db82873861629df63485ccab8d53590f4a27a83b7a9c1967c654ee1511b1b13ae88c5c7a049a78c8314ecc95c491119c7c6bfaa7584f6cda415efd3", + "Evaluation": { + "EvaluatedElement": "0x0301851f82c44311e7213c93dc185540264ed9242324f28583118f95966e2913b1237753e70bb570774b3d3d45adfbb42748d81d94e8c6987dadd993797b5c292d78db", + "proof": { + "c": "0x65fd98aaa3b0e6bff1f2d34bde9a0d183faf5ec05e50fc0c8cdd1cc28eb6b06a85543dd0a47c05570c98197041e97fc63c411fce4b02e4a731e255f1d3dc1ed491", + "s": "0x151e1b75b5066784b15d5eaf4e9eef15ba5873e554146c94b1c0fbd2d932bf2c1e1a1b55ec737c01c632e82f1ef03b533b32d2079f5672b7f90398aa6a32d160e7b" + } + }, + "SignedElement": "0x03006b49114d9fc819e0ff7fa066ecf8dddb92887f15793ac79534ce08cfe8d4588787f47eb61f294d58a8e6559b06bab178dff9b600d886f64680ce4b64d44e5d24c1", + "UnblindedElement": "0x0301f347bffbbde9c16016e2060c4d939a6e672e8b4dc88b9fa25f2a0afebd44a5b5dd500316e475d6040ec23a84f7aa3fe00ebc5211cf02d44ce3c93caf0eb4bf8b81" + } + ] + } +} diff --git a/go/vendor/github.com/armfazh/h2c-go-ref/suites.go b/go/vendor/github.com/armfazh/h2c-go-ref/suites.go index 3b2f5ea..aaceb65 100644 --- a/go/vendor/github.com/armfazh/h2c-go-ref/suites.go +++ b/go/vendor/github.com/armfazh/h2c-go-ref/suites.go @@ -55,7 +55,7 @@ func (id SuiteID) Get(dst []byte) (HashToPoint, error) { L: s.L, }, // TATIANA: what should name be here? - ScalarField: field.NewFp("", E.Field().P()), + ScalarField: field.NewFp(fmt.Sprintf("%v", E.Field().P()), E.Field().P()), Mapping: m, } if s.RO {