1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
|
Internet Research Task Force (IRTF) A. Davidson
Request for Comments: 9497 Brave Software
Category: Informational A. Faz-Hernandez
ISSN: 2070-1721 N. Sullivan
C. A. Wood
Cloudflare, Inc.
December 2023
Oblivious Pseudorandom Functions (OPRFs) Using Prime-Order Groups
Abstract
An Oblivious Pseudorandom Function (OPRF) is a two-party protocol
between a client and a server for computing the output of a
Pseudorandom Function (PRF). The server provides the PRF private
key, and the client provides the PRF input. At the end of the
protocol, the client learns the PRF output without learning anything
about the PRF private key, and the server learns neither the PRF
input nor output. An OPRF can also satisfy a notion of
'verifiability', called a VOPRF. A VOPRF ensures clients can verify
that the server used a specific private key during the execution of
the protocol. A VOPRF can also be partially oblivious, called a
POPRF. A POPRF allows clients and servers to provide public input to
the PRF computation. This document specifies an OPRF, VOPRF, and
POPRF instantiated within standard prime-order groups, including
elliptic curves. This document is a product of the Crypto Forum
Research Group (CFRG) in the IRTF.
Status of This Memo
This document is not an Internet Standards Track specification; it is
published for informational purposes.
This document is a product of the Internet Research Task Force
(IRTF). The IRTF publishes the results of Internet-related research
and development activities. These results might not be suitable for
deployment. This RFC represents the consensus of the Crypto Forum
Research Group of the Internet Research Task Force (IRTF). Documents
approved for publication by the IRSG are not candidates for any level
of Internet Standard; see Section 2 of RFC 7841.
Information about the current status of this document, any errata,
and how to provide feedback on it may be obtained at
https://www.rfc-editor.org/info/rfc9497.
Copyright Notice
Copyright (c) 2023 IETF Trust and the persons identified as the
document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal
Provisions Relating to IETF Documents
(https://trustee.ietf.org/license-info) in effect on the date of
publication of this document. Please review these documents
carefully, as they describe your rights and restrictions with respect
to this document.
Table of Contents
1. Introduction
1.1. Requirements Language
1.2. Notation and Terminology
2. Preliminaries
2.1. Prime-Order Group
2.2. Discrete Logarithm Equivalence Proofs
2.2.1. Proof Generation
2.2.2. Proof Verification
3. Protocol
3.1. Configuration
3.2. Key Generation and Context Setup
3.2.1. Deterministic Key Generation
3.3. Online Protocol
3.3.1. OPRF Protocol
3.3.2. VOPRF Protocol
3.3.3. POPRF Protocol
4. Ciphersuites
4.1. OPRF(ristretto255, SHA-512)
4.2. OPRF(decaf448, SHAKE-256)
4.3. OPRF(P-256, SHA-256)
4.4. OPRF(P-384, SHA-384)
4.5. OPRF(P-521, SHA-512)
4.6. Future Ciphersuites
4.7. Random Scalar Generation
4.7.1. Rejection Sampling
4.7.2. Random Number Generation Using Extra Random Bits
5. Application Considerations
5.1. Input Limits
5.2. External Interface Recommendations
5.3. Error Considerations
5.4. POPRF Public Input
6. IANA Considerations
7. Security Considerations
7.1. Security Properties
7.2. Security Assumptions
7.2.1. OPRF and VOPRF Assumptions
7.2.2. POPRF Assumptions
7.2.3. Static Diffie-Hellman Attack and Security Limits
7.3. Domain Separation
7.4. Timing Leaks
8. References
8.1. Normative References
8.2. Informative References
Appendix A. Test Vectors
A.1. ristretto255-SHA512
A.1.1. OPRF Mode
A.1.2. VOPRF Mode
A.1.3. POPRF Mode
A.2. decaf448-SHAKE256
A.2.1. OPRF Mode
A.2.2. VOPRF Mode
A.2.3. POPRF Mode
A.3. P256-SHA256
A.3.1. OPRF Mode
A.3.2. VOPRF Mode
A.3.3. POPRF Mode
A.4. P384-SHA384
A.4.1. OPRF Mode
A.4.2. VOPRF Mode
A.4.3. POPRF Mode
A.5. P521-SHA512
A.5.1. OPRF Mode
A.5.2. VOPRF Mode
A.5.3. POPRF Mode
Acknowledgements
Authors' Addresses
1. Introduction
A Pseudorandom Function (PRF) F(k, x) is an efficiently computable
function taking a private key k and a value x as input. This
function is pseudorandom if the keyed function K(_) = F(k, _) is
indistinguishable from a randomly sampled function acting on the same
domain and range as K(). An Oblivious PRF (OPRF) is a two-party
protocol between a server and a client, wherein the server holds a
PRF key k and the client holds some input x. The protocol allows
both parties to cooperate in computing F(k, x), such that the client
learns F(k, x) without learning anything about k and the server does
not learn anything about x or F(k, x). A Verifiable OPRF (VOPRF) is
an OPRF, wherein the server also proves to the client that F(k, x)
was produced by the key k corresponding to the server's public key,
which the client knows. A Partially Oblivious PRF (POPRF) is a
variant of a VOPRF, where the client and server interact in computing
F(k, x, y), for some PRF F with server-provided key k, client-
provided input x, and public input y, and the client receives proof
that F(k, x, y) was computed using k corresponding to the public key
that the client knows. A POPRF with fixed input y is functionally
equivalent to a VOPRF.
OPRFs have a variety of applications, including password-protected
secret sharing schemes [JKKX16], privacy-preserving password stores
[SJKS17], and password-authenticated key exchange (PAKE) [OPAQUE].
Verifiable OPRFs are necessary in some applications, such as Privacy
Pass [PRIVACY-PASS]. Verifiable OPRFs have also been used for
password-protected secret sharing schemes, such as that of [JKK14].
This document specifies OPRF, VOPRF, and POPRF protocols built upon
prime-order groups. The document describes each protocol variant,
along with application considerations, and their security properties.
This document represents the consensus of the Crypto Forum Research
Group (CFRG). It is not an IETF product and is not a standard.
1.1. Requirements Language
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and
"OPTIONAL" in this document are to be interpreted as described in
BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all
capitals, as shown here.
1.2. Notation and Terminology
The following functions and notation are used throughout the
document.
* For any object x, we write len(x) to denote its length in bytes.
* For two-byte arrays x and y, write x || y to denote their
concatenation.
* I2OSP(x, xLen) converts a nonnegative integer x into a byte array
of specified length xLen, as described in [RFC8017]. Note that
this function returns a byte array in big-endian byte order.
* The notation T U[N] refers to an array called U, containing N
items of type T. The type opaque means one single byte of
uninterpreted data. Items of the array are zero-indexed and
referred to as U[j], such that 0 <= j < N.
All algorithms and procedures described in this document are laid out
in a Python-like pseudocode. Each function takes a set of inputs and
parameters and produces a set of output values. Parameters become
constant values once the protocol variant and the ciphersuite are
fixed.
The PrivateInput data type refers to inputs that are known only to
the client in the protocol, whereas the PublicInput data type refers
to inputs that are known to both the client and server in the
protocol. Both PrivateInput and PublicInput are opaque byte strings
of arbitrary length no larger than 2^16 - 1 bytes. This length
restriction exists because PublicInput and PrivateInput values are
length-prefixed with two bytes before use throughout the protocol.
String values, such as "DeriveKeyPair", "Seed-", and "Finalize", are
ASCII string literals.
The following terms are used throughout this document.
PRF: Pseudorandom Function
OPRF: Oblivious Pseudorandom Function
VOPRF: Verifiable Oblivious Pseudorandom Function
POPRF: Partially Oblivious Pseudorandom Function
Client: Protocol initiator. Learns PRF evaluation as the output of
the protocol.
Server: Computes the PRF using a private key. Learns nothing about
the client's input or output.
2. Preliminaries
The protocols in this document have two primary dependencies:
Group: A prime-order group implementing the API described below in
Section 2.1. See Section 4 for specific instances of groups.
Hash: A cryptographic hash function whose output length is Nh bytes.
Section 4 specifies ciphersuites as combinations of Group and Hash.
2.1. Prime-Order Group
In this document, we assume the construction of an additive, prime-
order group, denoted Group, for performing all mathematical
operations. In prime-order groups, any element (other than the
identity) can generate the other elements of the group. Usually, one
element is fixed and defined as the group generator. Such groups are
uniquely determined by the choice of the prime p that defines the
order of the group. (However, different representations of the group
for a single p may exist. Section 4 lists specific groups that
indicate both the order and representation.)
The fundamental group operation is addition + with identity element
I. For any elements A and B of the group, A + B = B + A is also a
member of the group. Also, for any A in the group, there exists an
element -A, such that A + (-A) = (-A) + A = I. Scalar multiplication
by r is equivalent to the repeated application of the group operation
on an element A with itself r - 1 times; this is denoted as r * A = A
+ ... + A. For any element A, p * A = I. The case when the scalar
multiplication is performed on the group generator is denoted as
ScalarMultGen(r). Given two elements A and B, the discrete logarithm
problem is to find an integer k, such that B = k * A. Thus, k is the
discrete logarithm of B with respect to the base A. The set of
scalars corresponds to GF(p), a prime field of order p, and is
represented as the set of integers defined by {0, 1, ..., p - 1}.
This document uses types Element and Scalar to denote elements of the
group and its set of scalars, respectively.
We now detail a number of member functions that can be invoked on a
prime-order group.
Order(): Outputs the order of the group (i.e., p).
Identity(): Outputs the identity element of the group (i.e., I).
Generator(): Outputs the generator element of the group.
HashToGroup(x): Deterministically maps an array of bytes x to an
element of Group. The map must ensure that, for any adversary
receiving R = HashToGroup(x), it is computationally difficult to
reverse the mapping. This function is optionally parameterized by
a domain separation tag (DST); see Section 4. Security properties
of this function are described in [RFC9380].
HashToScalar(x): Deterministically maps an array of bytes x to an
element in GF(p). This function is optionally parameterized by a
DST; see Section 4. Security properties of this function are
described in [RFC9380], Section 10.5.
RandomScalar(): Chooses at random a nonzero element in GF(p).
ScalarInverse(s): Returns the inverse of input Scalar s on GF(p).
SerializeElement(A): Maps an Element A to a canonical byte array buf
of fixed-length Ne.
DeserializeElement(buf): Attempts to map a byte array buf to an
Element A and fails if the input is not the valid canonical byte
representation of an element of the group. This function can
raise a DeserializeError if deserialization fails or A is the
identity element of the group; see Section 4 for group-specific
input validation steps.
SerializeScalar(s): Maps Scalar s to a canonical byte array buf of
fixed-length Ns.
DeserializeScalar(buf): Attempts to map a byte array buf to Scalar
s. This function can raise a DeserializeError if deserialization
fails; see Section 4 for group-specific input validation steps.
Section 4 contains details for the implementation of this interface
for different prime-order groups instantiated over elliptic curves.
In particular, for some choices of elliptic curves, e.g., those
detailed in [RFC7748], which require accounting for cofactors,
Section 4 describes required steps necessary to ensure the resulting
group is of prime order.
2.2. Discrete Logarithm Equivalence Proofs
A proof of knowledge allows a prover to convince a verifier that some
statement is true. If the prover can generate a proof without
interaction with the verifier, the proof is noninteractive. If the
verifier learns nothing other than whether the statement claimed by
the prover is true or false, the proof is zero-knowledge.
This section describes a noninteractive, zero-knowledge proof for
discrete logarithm equivalence (DLEQ), which is used in the
construction of VOPRF and POPRF. A DLEQ proof demonstrates that two
pairs of group elements have the same discrete logarithm without
revealing the discrete logarithm.
The DLEQ proof resembles the Chaum-Pedersen [ChaumPedersen] proof,
which is shown to be zero-knowledge by Jarecki, et al. [JKK14] and is
noninteractive after applying the Fiat-Shamir transform [FS00].
Furthermore, Davidson, et al. [DGSTV18] showed a proof system for
batching DLEQ proofs that has constant-size proofs with respect to
the number of inputs. The specific DLEQ proof system presented below
follows this latter construction with two modifications: (1) the
transcript used to generate the seed includes more context
information and (2) the individual challenges for each element in the
proof is derived from a seed-prefixed hash-to-scalar invocation,
rather than being sampled from a seeded Pseudorandom Number Generator
(PRNG). The description is split into two subsections: one for
generating the proof, which is done by servers in the verifiable
protocols, and another for verifying the proof, which is done by
clients in the protocol.
2.2.1. Proof Generation
Generating a proof is done with the GenerateProof function, as
defined below. Given Element values A and B, two non-empty lists of
Element values C and D of length m, and Scalar k, this function
produces a proof that k * A == B and k * C[i] == D[i] for each i in
[0, ..., m - 1]. The output is a value of type Proof, which is a
tuple of two Scalar values. We use the notation proof[0] and
proof[1] to denote the first and second elements in this tuple,
respectively.
GenerateProof accepts lists of inputs to amortize the cost of proof
generation. Applications can take advantage of this functionality to
produce a single, constant-sized proof for m DLEQ inputs, rather than
m proofs for m DLEQ inputs.
Input:
Scalar k
Element A
Element B
Element C[m]
Element D[m]
Output:
Proof proof
Parameters:
Group G
def GenerateProof(k, A, B, C, D):
(M, Z) = ComputeCompositesFast(k, B, C, D)
r = G.RandomScalar()
t2 = r * A
t3 = r * M
Bm = G.SerializeElement(B)
a0 = G.SerializeElement(M)
a1 = G.SerializeElement(Z)
a2 = G.SerializeElement(t2)
a3 = G.SerializeElement(t3)
challengeTranscript =
I2OSP(len(Bm), 2) || Bm ||
I2OSP(len(a0), 2) || a0 ||
I2OSP(len(a1), 2) || a1 ||
I2OSP(len(a2), 2) || a2 ||
I2OSP(len(a3), 2) || a3 ||
"Challenge"
c = G.HashToScalar(challengeTranscript)
s = r - c * k
return [c, s]
The helper function ComputeCompositesFast is as defined below and is
an optimization of the ComputeComposites function for servers since
they have knowledge of the private key.
Input:
Scalar k
Element B
Element C[m]
Element D[m]
Output:
Element M
Element Z
Parameters:
Group G
PublicInput contextString
def ComputeCompositesFast(k, B, C, D):
Bm = G.SerializeElement(B)
seedDST = "Seed-" || contextString
seedTranscript =
I2OSP(len(Bm), 2) || Bm ||
I2OSP(len(seedDST), 2) || seedDST
seed = Hash(seedTranscript)
M = G.Identity()
for i in range(m):
Ci = G.SerializeElement(C[i])
Di = G.SerializeElement(D[i])
compositeTranscript =
I2OSP(len(seed), 2) || seed || I2OSP(i, 2) ||
I2OSP(len(Ci), 2) || Ci ||
I2OSP(len(Di), 2) || Di ||
"Composite"
di = G.HashToScalar(compositeTranscript)
M = di * C[i] + M
Z = k * M
return (M, Z)
When used in the protocol described in Section 3, the parameter
contextString is as defined in Section 3.2.
2.2.2. Proof Verification
Verifying a proof is done with the VerifyProof function, as defined
below. This function takes Element values A and B, two non-empty
lists of Element values C and D of length m, and a Proof value output
from GenerateProof. It outputs a single boolean value indicating
whether or not the proof is valid for the given DLEQ inputs. Note
this function can verify proofs on lists of inputs whenever the proof
was generated as a batched DLEQ proof with the same inputs.
Input:
Element A
Element B
Element C[m]
Element D[m]
Proof proof
Output:
boolean verified
Parameters:
Group G
def VerifyProof(A, B, C, D, proof):
(M, Z) = ComputeComposites(B, C, D)
c = proof[0]
s = proof[1]
t2 = ((s * A) + (c * B))
t3 = ((s * M) + (c * Z))
Bm = G.SerializeElement(B)
a0 = G.SerializeElement(M)
a1 = G.SerializeElement(Z)
a2 = G.SerializeElement(t2)
a3 = G.SerializeElement(t3)
challengeTranscript =
I2OSP(len(Bm), 2) || Bm ||
I2OSP(len(a0), 2) || a0 ||
I2OSP(len(a1), 2) || a1 ||
I2OSP(len(a2), 2) || a2 ||
I2OSP(len(a3), 2) || a3 ||
"Challenge"
expectedC = G.HashToScalar(challengeTranscript)
verified = (expectedC == c)
return verified
The definition of ComputeComposites is given below.
Input:
Element B
Element C[m]
Element D[m]
Output:
Element M
Element Z
Parameters:
Group G
PublicInput contextString
def ComputeComposites(B, C, D):
Bm = G.SerializeElement(B)
seedDST = "Seed-" || contextString
seedTranscript =
I2OSP(len(Bm), 2) || Bm ||
I2OSP(len(seedDST), 2) || seedDST
seed = Hash(seedTranscript)
M = G.Identity()
Z = G.Identity()
for i in range(m):
Ci = G.SerializeElement(C[i])
Di = G.SerializeElement(D[i])
compositeTranscript =
I2OSP(len(seed), 2) || seed || I2OSP(i, 2) ||
I2OSP(len(Ci), 2) || Ci ||
I2OSP(len(Di), 2) || Di ||
"Composite"
di = G.HashToScalar(compositeTranscript)
M = di * C[i] + M
Z = di * D[i] + Z
return (M, Z)
When used in the protocol described in Section 3, the parameter
contextString is as defined in Section 3.2.
3. Protocol
In this section, we define and describe three protocol variants
referred to as the OPRF, VOPRF, and POPRF modes. Each of these
variants involves two messages between the client and server, but
they differ slightly in terms of the security properties; see
Section 7.1 for more information. A high-level description of the
functionality of each mode follows.
In the OPRF mode, a client and server interact to compute output =
F(skS, input), where input is the client's private input, skS is the
server's private key, and output is the OPRF output. After the
execution of the protocol, the client learns the output and the
server learns nothing. This interaction is shown below.
Client(input) Server(skS)
-------------------------------------------------------------------
blind, blindedElement = Blind(input)
blindedElement
---------->
evaluatedElement = BlindEvaluate(skS, blindedElement)
evaluatedElement
<----------
output = Finalize(input, blind, evaluatedElement)
Figure 1: OPRF Protocol Overview
In the VOPRF mode, the client additionally receives proof that the
server used skS in computing the function. To achieve verifiability,
as in [JKK14], the server provides a zero-knowledge proof that the
key provided as input by the server in the BlindEvaluate function is
the same key as is used to produce the server's public key, pkS,
which the client receives as input to the protocol. This proof does
not reveal the server's private key to the client. This interaction
is shown below.
Client(input, pkS) <---- pkS ------ Server(skS, pkS)
-------------------------------------------------------------------
blind, blindedElement = Blind(input)
blindedElement
---------->
evaluatedElement, proof = BlindEvaluate(skS, pkS,
blindedElement)
evaluatedElement, proof
<----------
output = Finalize(input, blind, evaluatedElement,
blindedElement, pkS, proof)
Figure 2: VOPRF Protocol Overview with Additional Proof
The POPRF mode extends the VOPRF mode such that the client and server
can additionally provide the public input info, which is used in
computing the PRF. That is, the client and server interact to
compute output = F(skS, input, info), as is shown below.
Client(input, pkS, info) <---- pkS ------ Server(skS, pkS, info)
-------------------------------------------------------------------
blind, blindedElement, tweakedKey = Blind(input, info, pkS)
blindedElement
---------->
evaluatedElement, proof = BlindEvaluate(skS, blindedElement,
info)
evaluatedElement, proof
<----------
output = Finalize(input, blind, evaluatedElement,
blindedElement, proof, info, tweakedKey)
Figure 3: POPRF Protocol Overview with Additional Public Input
Each protocol consists of an offline setup phase and an online phase,
as described in Sections 3.2 and 3.3, respectively. Configuration
details for the offline phase are described in Section 3.1.
3.1. Configuration
Each of the three protocol variants are identified with a one-byte
value (in hexadecimal):
+===========+=======+
| Mode | Value |
+===========+=======+
| modeOPRF | 0x00 |
+-----------+-------+
| modeVOPRF | 0x01 |
+-----------+-------+
| modePOPRF | 0x02 |
+-----------+-------+
Table 1: Identifiers
for Protocol Variants
Additionally, each protocol variant is instantiated with a
ciphersuite or suite. Each ciphersuite is identified with an ASCII
string identifier, referred to as identifier; see Section 4 for the
set of initial ciphersuite values.
The mode and ciphersuite identifier values are combined to create a
"context string" used throughout the protocol with the following
function:
def CreateContextString(mode, identifier):
return "OPRFV1-" || I2OSP(mode, 1) || "-" || identifier
3.2. Key Generation and Context Setup
In the offline setup phase, the server generates a fresh, random key
pair (skS, pkS). There are two ways to generate this key pair. The
first of which is using the GenerateKeyPair function described below.
Input: None
Output:
Scalar skS
Element pkS
Parameters:
Group G
def GenerateKeyPair():
skS = G.RandomScalar()
pkS = G.ScalarMultGen(skS)
return skS, pkS
The second way to generate the key pair is via the deterministic key
generation function DeriveKeyPair, as described in Section 3.2.1.
Applications and implementations can use either method in practice.
Also during the offline setup phase, both the client and server
create a context used for executing the online phase of the protocol
after agreeing on a mode and ciphersuite identifier. The context,
such as OPRFServerContext, is an implementation-specific data
structure that stores a context string and the relevant key material
for each party.
The OPRF variant server and client contexts are created as follows:
def SetupOPRFServer(identifier, skS):
contextString = CreateContextString(modeOPRF, identifier)
return OPRFServerContext(contextString, skS)
def SetupOPRFClient(identifier):
contextString = CreateContextString(modeOPRF, identifier)
return OPRFClientContext(contextString)
The VOPRF variant server and client contexts are created as follows:
def SetupVOPRFServer(identifier, skS):
contextString = CreateContextString(modeVOPRF, identifier)
return VOPRFServerContext(contextString, skS)
def SetupVOPRFClient(identifier, pkS):
contextString = CreateContextString(modeVOPRF, identifier)
return VOPRFClientContext(contextString, pkS)
The POPRF variant server and client contexts are created as follows:
def SetupPOPRFServer(identifier, skS):
contextString = CreateContextString(modePOPRF, identifier)
return POPRFServerContext(contextString, skS)
def SetupPOPRFClient(identifier, pkS):
contextString = CreateContextString(modePOPRF, identifier)
return POPRFClientContext(contextString, pkS)
3.2.1. Deterministic Key Generation
This section describes a deterministic key generation function,
DeriveKeyPair. It accepts a seed of 32 bytes generated from a
cryptographically secure random number generator and an optional
(possibly empty) info string. Note that, by design, knowledge of
seed and info is necessary to compute this function, which means that
the secrecy of the output private key (skS) depends on the secrecy of
seed (since the info string is public).
Input:
opaque seed[32]
PublicInput info
Output:
Scalar skS
Element pkS
Parameters:
Group G
PublicInput contextString
Errors: DeriveKeyPairError
def DeriveKeyPair(seed, info):
deriveInput = seed || I2OSP(len(info), 2) || info
counter = 0
skS = 0
while skS == 0:
if counter > 255:
raise DeriveKeyPairError
skS = G.HashToScalar(deriveInput || I2OSP(counter, 1),
DST = "DeriveKeyPair" || contextString)
counter = counter + 1
pkS = G.ScalarMultGen(skS)
return skS, pkS
3.3. Online Protocol
In the online phase, the client and server engage in a two-message
protocol to compute the protocol output. This section describes the
protocol details for each protocol variant. Throughout each
description, the following parameters are assumed to exist:
G: a prime-order group implementing the API described in Section 2.1
contextString: a PublicInput domain separation tag constructed
during context setup, as created in Section 3.1
skS and pkS: a Scalar and Element representing the private and
public keys configured for the client and server in Section 3.2
Applications serialize protocol messages between the client and
server for transmission. Element values and Scalar values are
serialized to byte arrays, and values of type Proof are serialized as
the concatenation of two serialized Scalar values. Deserializing
these values can fail; in which case, the application MUST abort the
protocol, raising a DeserializeError failure.
Applications MUST check that input Element values received over the
wire are not the group identity element. This check is handled after
deserializing Element values; see Section 4 for more information and
requirements on input validation for each ciphersuite.
3.3.1. OPRF Protocol
The OPRF protocol begins with the client blinding its input, as
described by the Blind function below. Note that this function can
fail with an InvalidInputError error for certain inputs that map to
the group identity element. Dealing with this failure is an
application-specific decision; see Section 5.3.
Input:
PrivateInput input
Output:
Scalar blind
Element blindedElement
Parameters:
Group G
Errors: InvalidInputError
def Blind(input):
blind = G.RandomScalar()
inputElement = G.HashToGroup(input)
if inputElement == G.Identity():
raise InvalidInputError
blindedElement = blind * inputElement
return blind, blindedElement
Clients store blind locally and send blindedElement to the server for
evaluation. Upon receipt, servers process blindedElement using the
BlindEvaluate function described below.
Input:
Scalar skS
Element blindedElement
Output:
Element evaluatedElement
def BlindEvaluate(skS, blindedElement):
evaluatedElement = skS * blindedElement
return evaluatedElement
Servers send the output evaluatedElement to clients for processing.
Recall that servers may process multiple client inputs by applying
the BlindEvaluate function to each blindedElement received and
returning an array with the corresponding evaluatedElement values.
Upon receipt of evaluatedElement, clients process it to complete the
OPRF evaluation with the Finalize function described below.
Input:
PrivateInput input
Scalar blind
Element evaluatedElement
Output:
opaque output[Nh]
Parameters:
Group G
def Finalize(input, blind, evaluatedElement):
N = G.ScalarInverse(blind) * evaluatedElement
unblindedElement = G.SerializeElement(N)
hashInput = I2OSP(len(input), 2) || input ||
I2OSP(len(unblindedElement), 2) || unblindedElement ||
"Finalize"
return Hash(hashInput)
An entity that knows both the private key and the input can compute
the PRF result using the following Evaluate function.
Input:
Scalar skS
PrivateInput input
Output:
opaque output[Nh]
Parameters:
Group G
Errors: InvalidInputError
def Evaluate(skS, input):
inputElement = G.HashToGroup(input)
if inputElement == G.Identity():
raise InvalidInputError
evaluatedElement = skS * inputElement
issuedElement = G.SerializeElement(evaluatedElement)
hashInput = I2OSP(len(input), 2) || input ||
I2OSP(len(issuedElement), 2) || issuedElement ||
"Finalize"
return Hash(hashInput)
3.3.2. VOPRF Protocol
The VOPRF protocol begins with the client blinding its input, using
the same Blind function as in Section 3.3.1. Clients store the
output blind locally and send blindedElement to the server for
evaluation. Upon receipt, servers process blindedElement to compute
an evaluated element and a DLEQ proof using the following
BlindEvaluate function.
Input:
Scalar skS
Element pkS
Element blindedElement
Output:
Element evaluatedElement
Proof proof
Parameters:
Group G
def BlindEvaluate(skS, pkS, blindedElement):
evaluatedElement = skS * blindedElement
blindedElements = [blindedElement] // list of length 1
evaluatedElements = [evaluatedElement] // list of length 1
proof = GenerateProof(skS, G.Generator(), pkS,
blindedElements, evaluatedElements)
return evaluatedElement, proof
In the description above, inputs to GenerateProof are one-item lists.
Using larger lists allows servers to batch the evaluation of multiple
elements while producing a single batched DLEQ proof for them.
The server sends both evaluatedElement and proof back to the client.
Upon receipt, the client processes both values to complete the VOPRF
computation using the Finalize function below.
Input:
PrivateInput input
Scalar blind
Element evaluatedElement
Element blindedElement
Element pkS
Proof proof
Output:
opaque output[Nh]
Parameters:
Group G
Errors: VerifyError
def Finalize(input, blind, evaluatedElement,
blindedElement, pkS, proof):
blindedElements = [blindedElement] // list of length 1
evaluatedElements = [evaluatedElement] // list of length 1
if VerifyProof(G.Generator(), pkS, blindedElements,
evaluatedElements, proof) == false:
raise VerifyError
N = G.ScalarInverse(blind) * evaluatedElement
unblindedElement = G.SerializeElement(N)
hashInput = I2OSP(len(input), 2) || input ||
I2OSP(len(unblindedElement), 2) || unblindedElement ||
"Finalize"
return Hash(hashInput)
As in BlindEvaluate, inputs to VerifyProof are one-item lists.
Clients can verify multiple inputs at once whenever the server
produced a batched DLEQ proof for them.
Finally, an entity that knows both the private key and the input can
compute the PRF result using the Evaluate function described in
Section 3.3.1.
3.3.3. POPRF Protocol
The POPRF protocol begins with the client blinding its input, using
the following modified Blind function. In this step, the client also
binds a public info value, which produces an additional tweakedKey to
be used later in the protocol. Note that this function can fail with
an InvalidInputError error for certain private inputs that map to the
group identity element, as well as certain public inputs that, if not
detected at this point, will cause server evaluation to fail.
Dealing with either failure is an application-specific decision; see
Section 5.3.
Input:
PrivateInput input
PublicInput info
Element pkS
Output:
Scalar blind
Element blindedElement
Element tweakedKey
Parameters:
Group G
Errors: InvalidInputError
def Blind(input, info, pkS):
framedInfo = "Info" || I2OSP(len(info), 2) || info
m = G.HashToScalar(framedInfo)
T = G.ScalarMultGen(m)
tweakedKey = T + pkS
if tweakedKey == G.Identity():
raise InvalidInputError
blind = G.RandomScalar()
inputElement = G.HashToGroup(input)
if inputElement == G.Identity():
raise InvalidInputError
blindedElement = blind * inputElement
return blind, blindedElement, tweakedKey
Clients store the outputs blind and tweakedKey locally and send
blindedElement to the server for evaluation. Upon receipt, servers
process blindedElement to compute an evaluated element and a DLEQ
proof using the following BlindEvaluate function.
Input:
Scalar skS
Element blindedElement
PublicInput info
Output:
Element evaluatedElement
Proof proof
Parameters:
Group G
Errors: InverseError
def BlindEvaluate(skS, blindedElement, info):
framedInfo = "Info" || I2OSP(len(info), 2) || info
m = G.HashToScalar(framedInfo)
t = skS + m
if t == 0:
raise InverseError
evaluatedElement = G.ScalarInverse(t) * blindedElement
tweakedKey = G.ScalarMultGen(t)
evaluatedElements = [evaluatedElement] // list of length 1
blindedElements = [blindedElement] // list of length 1
proof = GenerateProof(t, G.Generator(), tweakedKey,
evaluatedElements, blindedElements)
return evaluatedElement, proof
In the description above, inputs to GenerateProof are one-item lists.
Using larger lists allows servers to batch the evaluation of multiple
elements while producing a single batched DLEQ proof for them.
BlindEvaluate triggers InverseError when the function is about to
calculate the inverse of a zero scalar, which does not exist and
therefore yields a failure in the protocol. This only occurs for
info values that map to the private key of the server. Thus, clients
that cause this error should be assumed to know the server private
key. Hence, this error can be a signal for the server to replace its
private key.
The server sends both evaluatedElement and proof back to the client.
Upon receipt, the client processes both values to complete the POPRF
computation using the Finalize function below.
Input:
PrivateInput input
Scalar blind
Element evaluatedElement
Element blindedElement
Proof proof
PublicInput info
Element tweakedKey
Output:
opaque output[Nh]
Parameters:
Group G
Errors: VerifyError
def Finalize(input, blind, evaluatedElement, blindedElement,
proof, info, tweakedKey):
evaluatedElements = [evaluatedElement] // list of length 1
blindedElements = [blindedElement] // list of length 1
if VerifyProof(G.Generator(), tweakedKey, evaluatedElements,
blindedElements, proof) == false:
raise VerifyError
N = G.ScalarInverse(blind) * evaluatedElement
unblindedElement = G.SerializeElement(N)
hashInput = I2OSP(len(input), 2) || input ||
I2OSP(len(info), 2) || info ||
I2OSP(len(unblindedElement), 2) || unblindedElement ||
"Finalize"
return Hash(hashInput)
As in BlindEvaluate, inputs to VerifyProof are one-item lists.
Clients can verify multiple inputs at once whenever the server
produced a batched DLEQ proof for them.
Finally, an entity that knows both the private key and the input can
compute the PRF result using the Evaluate function described below.
Input:
Scalar skS
PrivateInput input
PublicInput info
Output:
opaque output[Nh]
Parameters:
Group G
Errors: InvalidInputError, InverseError
def Evaluate(skS, input, info):
inputElement = G.HashToGroup(input)
if inputElement == G.Identity():
raise InvalidInputError
framedInfo = "Info" || I2OSP(len(info), 2) || info
m = G.HashToScalar(framedInfo)
t = skS + m
if t == 0:
raise InverseError
evaluatedElement = G.ScalarInverse(t) * inputElement
issuedElement = G.SerializeElement(evaluatedElement)
hashInput = I2OSP(len(input), 2) || input ||
I2OSP(len(info), 2) || info ||
I2OSP(len(issuedElement), 2) || issuedElement ||
"Finalize"
return Hash(hashInput)
4. Ciphersuites
A ciphersuite (also referred to as 'suite' in this document) for the
protocol wraps the functionality required for the protocol to take
place. The ciphersuite should be available to both the client and
server, and agreement on the specific instantiation is assumed
throughout.
A ciphersuite contains instantiations of the following
functionalities:
Group: A prime-order group exposing the API detailed in Section 2.1,
with the generator element defined in the corresponding reference
for each group. Each group also specifies HashToGroup,
HashToScalar, and serialization functionalities. For HashToGroup,
the domain separation tag (DST) is constructed in accordance with
the recommendations in [RFC9380], Section 3.1. For HashToScalar,
each group specifies an integer order that is used in reducing
integer values to a member of the corresponding scalar field.
Hash: A cryptographic hash function whose output length is Nh bytes
long.
This section includes an initial set of ciphersuites with supported
groups and hash functions. It also includes implementation details
for each ciphersuite, focusing on input validation. Future documents
can specify additional ciphersuites as needed, provided they meet the
requirements in Section 4.6.
For each ciphersuite, contextString is that which is computed in the
Setup functions. Applications should take caution in using
ciphersuites targeting P-256 and ristretto255. See Section 7.2 for
related discussion.
4.1. OPRF(ristretto255, SHA-512)
This ciphersuite uses ristretto255 [RFC9496] for the Group and
SHA-512 for the hash function. The value of the ciphersuite
identifier is "ristretto255-SHA512".
Group: ristretto255 [RFC9496]
Order(): Return 2^252 + 27742317777372353535851937790883648493
(see [RFC9496]).
Identity(): As defined in [RFC9496].
Generator(): As defined in [RFC9496].
HashToGroup(): Use hash_to_ristretto255 [RFC9380] with DST =
"HashToGroup-" || contextString and expand_message =
expand_message_xmd using SHA-512.
HashToScalar(): Compute uniform_bytes using expand_message =
expand_message_xmd, DST = "HashToScalar-" || contextString, and
an output length of 64 bytes, interpret uniform_bytes as a
512-bit integer in little-endian order, and reduce the integer
modulo Group.Order().
ScalarInverse(s): Returns the multiplicative inverse of input
Scalar s mod Group.Order().
RandomScalar(): Implemented by returning a uniformly random
Scalar in the range [0, G.Order() - 1]. Refer to Section 4.7
for implementation guidance.
SerializeElement(A): Implemented using the Encode function from
Section 4.3.2 of [RFC9496]; Ne = 32.
DeserializeElement(buf): Implemented using the Decode function
from Section 4.3.1 of [RFC9496]. Additionally, this function
validates that the resulting element is not the group identity
element. If these checks fail, deserialization returns an
InputValidationError error.
SerializeScalar(s): Implemented by outputting the little-endian,
32-byte encoding of the Scalar value with the top three bits
set to zero; Ns = 32.
DeserializeScalar(buf): Implemented by attempting to deserialize
a Scalar from a little-endian, 32-byte string. This function
can fail if the input does not represent a Scalar in the range
[0, G.Order() - 1]. Note that this means the top three bits of
the input MUST be zero.
Hash: SHA-512; Nh = 64.
4.2. OPRF(decaf448, SHAKE-256)
This ciphersuite uses decaf448 [RFC9496] for the Group and SHAKE-256
for the hash function. The value of the ciphersuite identifier is
"decaf448-SHAKE256".
Group: decaf448 [RFC9496]
Order(): Return 2^446 - 13818066809895115352007386748515426880336
692474882178609894547503885.
Identity(): As defined in [RFC9496].
Generator(): As defined in [RFC9496].
RandomScalar(): Implemented by returning a uniformly random
Scalar in the range [0, G.Order() - 1]. Refer to Section 4.7
for implementation guidance.
HashToGroup(): Use hash_to_decaf448 [RFC9380] with DST =
"HashToGroup-" || contextString and expand_message =
expand_message_xof using SHAKE-256.
HashToScalar(): Compute uniform_bytes using expand_message =
expand_message_xof, DST = "HashToScalar-" || contextString, and
output length 64, interpret uniform_bytes as a 512-bit integer
in little-endian order, and reduce the integer modulo
Group.Order().
ScalarInverse(s): Returns the multiplicative inverse of input
Scalar s mod Group.Order().
SerializeElement(A): Implemented using the Encode function from
Section 5.3.2 of [RFC9496]; Ne = 56.
DeserializeElement(buf): Implemented using the Decode function
from Section 5.3.1 of [RFC9496]. Additionally, this function
validates that the resulting element is not the group identity
element. If these checks fail, deserialization returns an
InputValidationError error.
SerializeScalar(s): Implemented by outputting the little-endian,
56-byte encoding of the Scalar value; Ns = 56.
DeserializeScalar(buf): Implemented by attempting to deserialize
a Scalar from a little-endian, 56-byte string. This function
can fail if the input does not represent a Scalar in the range
[0, G.Order() - 1].
Hash: SHAKE-256; Nh = 64.
4.3. OPRF(P-256, SHA-256)
This ciphersuite uses P-256 [NISTCurves] for the Group and SHA-256
for the hash function. The value of the ciphersuite identifier is
"P256-SHA256".
Group: P-256 (secp256r1) [NISTCurves]
Order(): Return 0xffffffff00000000ffffffffffffffffbce6faada7179e8
4f3b9cac2fc632551.
Identity(): As defined in [NISTCurves].
Generator(): As defined in [NISTCurves].
RandomScalar(): Implemented by returning a uniformly random
Scalar in the range [0, G.Order() - 1]. Refer to Section 4.7
for implementation guidance.
HashToGroup(): Use hash_to_curve with suite P256_XMD:SHA-
256_SSWU_RO_ [RFC9380] and DST = "HashToGroup-" ||
contextString.
HashToScalar(): Use hash_to_field from [RFC9380] using L = 48,
expand_message_xmd with SHA-256, DST = "HashToScalar-" ||
contextString, and a prime modulus equal to Group.Order().
ScalarInverse(s): Returns the multiplicative inverse of input
Scalar s mod Group.Order().
SerializeElement(A): Implemented using the compressed Elliptic-
Curve-Point-to-Octet-String method according to [SEC1]; Ne =
33.
DeserializeElement(buf): Implemented by attempting to deserialize
a 33-byte input string to a public key using the compressed
Octet-String-to-Elliptic-Curve-Point method according to [SEC1]
and then performing partial public-key validation, as defined
in Section 5.6.2.3.4 of [KEYAGREEMENT]. This includes checking
that the coordinates of the resulting point are in the correct
range, that the point is on the curve, and that the point is
not the group identity element. If these checks fail,
deserialization returns an InputValidationError error.
SerializeScalar(s): Implemented using the Field-Element-to-Octet-
String conversion according to [SEC1]; Ns = 32.
DeserializeScalar(buf): Implemented by attempting to deserialize
a Scalar from a 32-byte string using Octet-String-to-Field-
Element from [SEC1]. This function can fail if the input does
not represent a Scalar in the range [0, G.Order() - 1].
Hash: SHA-256; Nh = 32.
4.4. OPRF(P-384, SHA-384)
This ciphersuite uses P-384 [NISTCurves] for the Group and SHA-384
for the hash function. The value of the ciphersuite identifier is
"P384-SHA384".
Group: P-384 (secp384r1) [NISTCurves]
Order(): Return 0xfffffffffffffffffffffffffffffffffffffffffffffff
fc7634d81f4372ddf581a0db248b0a77aecec196accc52973.
Identity(): As defined in [NISTCurves].
Generator(): As defined in [NISTCurves].
RandomScalar(): Implemented by returning a uniformly random
Scalar in the range [0, G.Order() - 1]. Refer to Section 4.7
for implementation guidance.
HashToGroup(): Use hash_to_curve with suite P384_XMD:SHA-
384_SSWU_RO_ [RFC9380] and DST = "HashToGroup-" ||
contextString.
HashToScalar(): Use hash_to_field from [RFC9380] using L = 72,
expand_message_xmd with SHA-384, DST = "HashToScalar-" ||
contextString, and a prime modulus equal to Group.Order().
ScalarInverse(s): Returns the multiplicative inverse of input
Scalar s mod Group.Order().
SerializeElement(A): Implemented using the compressed Elliptic-
Curve-Point-to-Octet-String method according to [SEC1]; Ne =
49.
DeserializeElement(buf): Implemented by attempting to deserialize
a 49-byte array to a public key using the compressed Octet-
String-to-Elliptic-Curve-Point method according to [SEC1] and
then performing partial public-key validation, as defined in
Section 5.6.2.3.4 of [KEYAGREEMENT]. This includes checking
that the coordinates of the resulting point are in the correct
range, that the point is on the curve, and that the point is
not the point at infinity. Additionally, this function
validates that the resulting element is not the group identity
element. If these checks fail, deserialization returns an
InputValidationError error.
SerializeScalar(s): Implemented using the Field-Element-to-Octet-
String conversion according to [SEC1]; Ns = 48.
DeserializeScalar(buf): Implemented by attempting to deserialize
a Scalar from a 48-byte string using Octet-String-to-Field-
Element from [SEC1]. This function can fail if the input does
not represent a Scalar in the range [0, G.Order() - 1].
Hash: SHA-384; Nh = 48.
4.5. OPRF(P-521, SHA-512)
This ciphersuite uses P-521 [NISTCurves] for the Group and SHA-512
for the hash function. The value of the ciphersuite identifier is
"P521-SHA512".
Group: P-521 (secp521r1) [NISTCurves]
Order(): Return 0x01fffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b889
9c47aebb6fb71e91386409.
Identity(): As defined in [NISTCurves].
Generator(): As defined in [NISTCurves].
RandomScalar(): Implemented by returning a uniformly random
Scalar in the range [0, G.Order() - 1]. Refer to Section 4.7
for implementation guidance.
HashToGroup(): Use hash_to_curve with suite P521_XMD:SHA-
512_SSWU_RO_ [RFC9380] and DST = "HashToGroup-" ||
contextString.
HashToScalar(): Use hash_to_field from [RFC9380] using L = 98,
expand_message_xmd with SHA-512, DST = "HashToScalar-" ||
contextString, and a prime modulus equal to Group.Order().
ScalarInverse(s): Returns the multiplicative inverse of input
Scalar s mod Group.Order().
SerializeElement(A): Implemented using the compressed Elliptic-
Curve-Point-to-Octet-String method according to [SEC1]; Ne =
67.
DeserializeElement(buf): Implemented by attempting to deserialize
a 67-byte input string to a public key using the compressed
Octet-String-to-Elliptic-Curve-Point method according to [SEC1]
and then performing partial public-key validation, as defined
in Section 5.6.2.3.4 of [KEYAGREEMENT]. This includes checking
that the coordinates of the resulting point are in the correct
range, that the point is on the curve, and that the point is
not the point at infinity. Additionally, this function
validates that the resulting element is not the group identity
element. If these checks fail, deserialization returns an
InputValidationError error.
SerializeScalar(s): Implemented using the Field-Element-to-Octet-
String conversion according to [SEC1]; Ns = 66.
DeserializeScalar(buf): Implemented by attempting to deserialize
a Scalar from a 66-byte string using Octet-String-to-Field-
Element from [SEC1]. This function can fail if the input does
not represent a Scalar in the range [0, G.Order() - 1].
Hash: SHA-512; Nh = 64.
4.6. Future Ciphersuites
A critical requirement of implementing the prime-order group using
elliptic curves is a method to instantiate the function HashToGroup,
which maps inputs to group elements. In the elliptic curve setting,
this deterministically maps inputs (as byte arrays) to uniformly
chosen points on the curve.
In the security proof of the construction, Hash is modeled as a
random oracle. This implies that any instantiation of HashToGroup
must be pre-image and collision resistant. In Section 4, we give
instantiations of this functionality based on the functions described
in [RFC9380]. Consequently, any OPRF implementation must adhere to
the implementation and security considerations discussed in [RFC9380]
when instantiating the function.
The DeserializeElement and DeserializeScalar functions instantiated
for a particular prime-order group corresponding to a ciphersuite
MUST adhere to the description in Section 2.1. Future ciphersuites
MUST describe how input validation is done for DeserializeElement and
DeserializeScalar.
Additionally, future ciphersuites must take care when choosing the
security level of the group. See Section 7.2.3 for additional
details.
4.7. Random Scalar Generation
Two popular algorithms for generating a random integer uniformly
distributed in the range [0, G.Order() - 1] are described in the
following subsections.
4.7.1. Rejection Sampling
Generate a random byte array with Ns bytes and attempt to map to a
Scalar by calling DeserializeScalar in constant time. If it
succeeds, return the result. If it fails, try again with another
random byte array until the procedure succeeds. Failure to implement
DeserializeScalar in constant time can leak information about the
underlying corresponding Scalar.
As an optimization, if the group order is very close to a power of 2,
it is acceptable to omit the rejection test completely. In
particular, if the group order is p and there is an integer b such
that |p - 2^b| is less than 2^(b/2), then RandomScalar can simply
return a uniformly random integer of at most b bits.
4.7.2. Random Number Generation Using Extra Random Bits
Generate a random byte array with L = ceil(((3 *
ceil(log2(G.Order()))) / 2) / 8) bytes, and interpret it as an
integer; reduce the integer modulo G.Order(), and return the result.
See [RFC9380], Section 5 for the underlying derivation of L.
5. Application Considerations
This section describes considerations for applications, including
external interface recommendations, explicit error treatment, and
public input representation for the POPRF protocol variant.
5.1. Input Limits
Application inputs, expressed as PrivateInput or PublicInput values,
MUST be smaller than 2^16 - 1 bytes in length. Applications that
require longer inputs can use a cryptographic hash function to map
these longer inputs to a fixed-length input that fits within the
PublicInput or PrivateInput length bounds. Note that some
cryptographic hash functions have input length restrictions
themselves, but these limits are often large enough to not be a
concern in practice. For example, SHA-256 has an input limit of 2^61
bytes.
5.2. External Interface Recommendations
In Section 3.3, the interface of the protocol functions allows that
some inputs (and outputs) to be group Element and Scalar values.
However, implementations can instead operate over Element and Scalar
values internally and only expose interfaces that operate with an
application-specific format of messages.
5.3. Error Considerations
Some OPRF variants specified in this document have fallible
operations. For example, Finalize and BlindEvaluate can fail if any
element received from the peer fails input validation. The explicit
errors generated throughout this specification, along with the
conditions that lead to each error, are as follows:
VerifyError: Verifiable OPRF proof verification failed (Sections
3.3.2 and 3.3.3).
DeserializeError: Group Element or Scalar deserialization failure
(Sections 2.1 and 3.3).
InputValidationError: Validation of byte array inputs failed
(Section 4).
There are other explicit errors generated in this specification;
however, they occur with negligible probability in practice. We note
them here for completeness.
InvalidInputError: OPRF Blind input produces an invalid output
element (Sections 3.3.1 and 3.3.3).
InverseError: A tweaked private key is invalid, i.e., has no
multiplicative inverse (Sections 2.1 and 3.3).
In general, the errors in this document are meant as a guide to
implementors. They are not an exhaustive list of all the errors an
implementation might emit. For example, implementations might run
out of memory and return a corresponding error.
5.4. POPRF Public Input
Functionally, the VOPRF and POPRF variants differ in that the POPRF
variant admits public input, whereas the VOPRF variant does not.
Public input allows clients and servers to cryptographically bind
additional data to the POPRF output. A POPRF with fixed public input
is functionally equivalent to a VOPRF. However, there are
differences in the underlying security assumptions made about each
variant; see Section 7.2 for more details.
This public input is known to both parties at the start of the
protocol. It is RECOMMENDED that this public input be constructed
with some type of higher-level domain separation to avoid cross
protocol attacks or related issues. For example, protocols using
this construction might ensure that the public input uses a unique,
prefix-free encoding. See [RFC9380], Section 10.4 for further
discussion on constructing domain separation values.
Implementations of the POPRF may choose to not let applications
control info in cases where this value is fixed or otherwise not
useful to the application. In this case, the resulting protocol is
functionally equivalent to the VOPRF, which does not admit public
input.
6. IANA Considerations
This document has no IANA actions.
7. Security Considerations
This section discusses the security of the protocols defined in this
specification, along with some suggestions and trade-offs that arise
from the implementation of the protocol variants in this document.
Note that the syntax of the POPRF variant is different from that of
the OPRF and VOPRF variants since it admits an additional public
input, but the same security considerations apply.
7.1. Security Properties
The security properties of an OPRF protocol with functionality y =
F(k, x) include those of a standard PRF. Specifically:
Pseudorandomness: For a random sampling of k, F is pseudorandom if
the output y = F(k, x) on any input x is indistinguishable from
uniformly sampling any element in F's range.
In other words, consider an adversary that picks inputs x from the
domain of F and evaluates F on (k, x) (without knowledge of randomly
sampled k). Then, the output distribution F(k, x) is
indistinguishable from the output distribution of a randomly chosen
function with the same domain and range.
A consequence of showing that a function is pseudorandom is that it
is necessarily nonmalleable (i.e., we cannot compute a new evaluation
of F from an existing evaluation). A genuinely random function will
be nonmalleable with high probability, so a pseudorandom function
must be nonmalleable to maintain indistinguishability.
Unconditional input secrecy: The server does not learn anything
about the client input x, even with unbounded computation.
In other words, an attacker with infinite computing power cannot
recover any information about the client's private input x from an
invocation of the protocol.
Essentially, input secrecy is the property that, even if the server
learns the client's private input x at some point in the future, the
server cannot link any particular PRF evaluation to x. This property
is also known as unlinkability [DGSTV18].
Beyond client input secrecy, in the OPRF protocol, the server learns
nothing about the output y of the function, nor does the client learn
anything about the server's private key k.
For the VOPRF and POPRF protocol variants, there is an additional
security property:
Verifiable: The client must only complete execution of the protocol
if it can successfully assert that the output it computes is
correct. This is taken with respect to the private key held by
the server.
Any VOPRF or POPRF that satisfies the 'verifiable' security property
is known as 'verifiable'. In practice, the notion of verifiability
requires that the server commits to the key before the actual
protocol execution takes place. Then, the client verifies that the
server has used the key in the protocol using this commitment. In
the following, we may also refer to this commitment as a public key.
Finally, the POPRF variant also has the following security property:
Partial obliviousness: The client and server must be able to perform
the PRF on the client's private and public input. Both the client
and server know the public input, but similar to the OPRF and
VOPRF protocols, the server learns nothing about the client's
private input or the output of the function, and the client learns
nothing about the server's private key.
This property becomes useful when dealing with key management
operations, such as the rotation of the server's keys. Note that
partial obliviousness only applies to the POPRF variant because
neither the OPRF nor VOPRF variants accept public input to the
protocol.
Since the POPRF variant has a different syntax than the OPRF and
VOPRF variants, i.e., y = F(k, x, info), the pseudorandomness
property is generalized:
Pseudorandomness: For a random sampling of k, F is pseudorandom if
the output y = F(k, x, info) on any input pairs (x, info) is
indistinguishable from uniformly sampling any element in F's
range.
7.2. Security Assumptions
Below, we discuss the cryptographic security of each protocol variant
from Section 3, relative to the necessary cryptographic assumptions
that need to be made.
7.2.1. OPRF and VOPRF Assumptions
The OPRF and VOPRF protocol variants in this document are based on
[JKK14]. In particular, the VOPRF construction is similar to the
[JKK14] construction with the following distinguishing properties:
1. This document does not use session identifiers to differentiate
different instances of the protocol.
2. This document supports batching so that multiple evaluations can
happen at once whilst only constructing one DLEQ proof object.
This is enabled using an established batching technique
[DGSTV18].
The pseudorandomness and input secrecy (and verifiability) of the
OPRF (and VOPRF) protocols in [JKK14] are based on the One-More Gap
Computational Diffie-Hellman assumption that is computationally
difficult to solve in the corresponding prime-order group. In
[JKK14], these properties are proven for one instance (i.e., one key)
of the VOPRF protocol and without batching. There is currently no
security analysis available for the VOPRF protocol described in this
document in a setting with multiple server keys or batching.
7.2.2. POPRF Assumptions
The POPRF construction in this document is based on the construction
known as 3HashSDHI, given by [TCRSTW21]. The construction is
identical to 3HashSDHI, except that this design can optionally
perform multiple POPRF evaluations in one batch, whilst only
constructing one DLEQ proof object. This is enabled using an
established batching technique [DGSTV18].
Pseudorandomness, input secrecy, verifiability, and partial
obliviousness of the POPRF variant is based on the assumption that
the One-More Gap Strong Diffie-Hellman Inversion (SDHI) assumption
from [TCRSTW21] is computationally difficult to solve in the
corresponding prime-order group. Tyagi et al. [TCRSTW21] show that
both the One-More Gap Computational Diffie-Hellman assumption and the
One-More Gap SDHI assumption reduce to the q-DL (Discrete Log)
assumption in the algebraic group model for some q number of
BlindEvaluate queries. (The One-More Gap Computational Diffie-
Hellman assumption was the hardness assumption used to evaluate the
OPRF and VOPRF designs based on [JKK14], which is a predecessor to
the POPRF variant in Section 3.3.3.)
7.2.3. Static Diffie-Hellman Attack and Security Limits
A side effect of the OPRF protocol variants in this document is that
they allow instantiation of an oracle for constructing static Diffie-
Hellman (DH) samples; see [BG04] and [Cheon06]. These attacks are
meant to recover (bits of) the server private key. Best-known
attacks reduce the security of the prime-order group instantiation by
log_2(Q) / 2 bits, where Q is the number of BlindEvaluate calls made
by the attacker.
As a result of this class of attacks, choosing prime-order groups
with a 128-bit security level instantiates an OPRF with a reduced
security level of 128 - (log_2(Q) / 2) bits of security. Moreover,
such attacks are only possible for those certain applications where
the adversary can query the OPRF directly. Applications can mitigate
against this problem in a variety of ways, e.g., by rate-limiting
client queries to BlindEvaluate or by rotating private keys. In
applications where such an oracle is not made available, this
security loss does not apply.
In most cases, it would require an informed and persistent attacker
to launch a highly expensive attack to reduce security to anything
much below 100 bits of security. Applications that admit the
aforementioned oracle functionality and that cannot tolerate discrete
logarithm security of lower than 128 bits are RECOMMENDED to choose
groups that target a higher security level, such as decaf448 (used by
ciphersuite decaf448-SHAKE256), P-384 (used by ciphersuite
P384-SHA384), or P-521 (used by ciphersuite P521-SHA512).
7.3. Domain Separation
Applications SHOULD construct input to the protocol to provide domain
separation. Any system that has multiple OPRF applications should
distinguish client inputs to ensure the OPRF results are separate.
Guidance for constructing info can be found in [RFC9380],
Section 3.1.
7.4. Timing Leaks
To ensure no information is leaked during protocol execution, all
operations that use secret data MUST run in constant time. This
includes all prime-order group operations and proof-specific
operations that operate on secret data, including GenerateProof and
BlindEvaluate.
8. References
8.1. Normative References
[KEYAGREEMENT]
Barker, E., Chen, L., Roginsky, A., Vassilev, A., and R.
Davis, "Recommendation for pair-wise key-establishment
schemes using discrete logarithm cryptography", NIST
SP 800-56A (Rev. 3), DOI 10.6028/nist.sp.800-56ar3, April
2018, <https://doi.org/10.6028/nist.sp.800-56ar3>.
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119,
DOI 10.17487/RFC2119, March 1997,
<https://www.rfc-editor.org/info/rfc2119>.
[RFC8017] Moriarty, K., Ed., Kaliski, B., Jonsson, J., and A. Rusch,
"PKCS #1: RSA Cryptography Specifications Version 2.2",
RFC 8017, DOI 10.17487/RFC8017, November 2016,
<https://www.rfc-editor.org/info/rfc8017>.
[RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC
2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174,
May 2017, <https://www.rfc-editor.org/info/rfc8174>.
[RFC9380] Faz-Hernandez, A., Scott, S., Sullivan, N., Wahby, R. S.,
and C. A. Wood, "Hashing to Elliptic Curves", RFC 9380,
DOI 10.17487/RFC9380, August 2023,
<https://www.rfc-editor.org/info/rfc9380>.
[RFC9496] de Valence, H., Grigg, J., Hamburg, M., Lovecruft, I.,
Tankersley, G., and F. Valsorda, "The ristretto255 and
decaf448 Groups", RFC 9496, DOI 10.17487/RFC9496, December
2023, <https://www.rfc-editor.org/info/rfc9496>.
8.2. Informative References
[BG04] Brown, D. and R. Gallant, "The Static Diffie-Hellman
Problem", November 2004,
<https://eprint.iacr.org/2004/306>.
[ChaumPedersen]
Chaum, D. and T. Pedersen, "Wallet Databases with
Observers", Advances in Cryptology - CRYPTO' 92, pp.
89-105, DOI 10.1007/3-540-48071-4_7, August 1992,
<https://doi.org/10.1007/3-540-48071-4_7>.
[Cheon06] Cheon, J., "Security Analysis of the Strong Diffie-Hellman
Problem", Advances in Cryptology - EUROCRYPT 2006, pp.
1-11, DOI 10.1007/11761679_1, 2006,
<https://doi.org/10.1007/11761679_1>.
[DGSTV18] Davidson, A., Goldberg, I., Sullivan, N., Tankersley, G.,
and F. Valsorda, "Privacy Pass: Bypassing Internet
Challenges Anonymously", Proceedings on Privacy Enhancing
Technologies, vol. 2018, no. 3, pp. 164-180, DOI
10.1515/popets-2018-0026, April 2018,
<https://doi.org/10.1515/popets-2018-0026>.
[FS00] Fiat, A. and A. Shamir, "How To Prove Yourself: Practical
Solutions to Identification and Signature Problems",
Advances in Cryptology - CRYPTO' 86, pp. 186-194,
DOI 10.1007/3-540-47721-7_12, 1986,
<https://doi.org/10.1007/3-540-47721-7_12>.
[JKK14] Jarecki, S., Kiayias, A., and H. Krawczyk, "Round-Optimal
Password-Protected Secret Sharing and T-PAKE in the
Password-Only Model", Lecture Notes in Computer Science,
pp. 233-253, DOI 10.1007/978-3-662-45608-8_13, 2014,
<https://doi.org/10.1007/978-3-662-45608-8_13>.
[JKKX16] Jarecki, S., Kiayias, A., Krawczyk, H., and J. Xu,
"Highly-Efficient and Composable Password-Protected Secret
Sharing (Or: How to Protect Your Bitcoin Wallet Online)",
2016 IEEE European Symposium on Security and Privacy
(EuroS&P), DOI 10.1109/eurosp.2016.30, March 2016,
<https://doi.org/10.1109/eurosp.2016.30>.
[NISTCurves]
National Institute of Standards and Technology (NIST),
"Digital Signature Standard (DSS)", FIPS PUB 186-5,
DOI 10.6028/NIST.FIPS.186-5, February 2023,
<https://doi.org/10.6028/NIST.FIPS.186-5>.
[OPAQUE] Bourdrez, D., Krawczyk, H., Lewi, K., and C. A. Wood, "The
OPAQUE Asymmetric PAKE Protocol", Work in Progress,
Internet-Draft, draft-irtf-cfrg-opaque-13, 18 December
2023, <https://datatracker.ietf.org/doc/html/draft-irtf-
cfrg-opaque-13>.
[PRIVACY-PASS]
Celi, S., Davidson, A., Valdez, S., and C. A. Wood,
"Privacy Pass Issuance Protocol", Work in Progress,
Internet-Draft, draft-ietf-privacypass-protocol-16, 3
October 2023, <https://datatracker.ietf.org/doc/html/
draft-ietf-privacypass-protocol-16>.
[PrivacyPass]
"Privacy Pass", commit 085380a, March 2018,
<https://github.com/privacypass/team>.
[RFC7748] Langley, A., Hamburg, M., and S. Turner, "Elliptic Curves
for Security", RFC 7748, DOI 10.17487/RFC7748, January
2016, <https://www.rfc-editor.org/info/rfc7748>.
[SEC1] Standards for Efficient Cryptography Group (SECG), "SEC 1:
Elliptic Curve Cryptography", May 2009,
<https://www.secg.org/sec1-v2.pdf>.
[SJKS17] Shirvanian, M., Jarecki, S., Krawczyk, H., and N. Saxena,
"SPHINX: A Password Store that Perfectly Hides Passwords
from Itself", 2017 IEEE 37th International Conference on
Distributed Computing Systems (ICDCS),
DOI 10.1109/ICDCS.2017.64, June 2017,
<https://doi.org/10.1109/ICDCS.2017.64>.
[TCRSTW21] Tyagi, N., Celi, S., Ristenpart, T., Sullivan, N.,
Tessaro, S., and C. A. Wood, "A Fast and Simple Partially
Oblivious PRF, with Applications", Advances in Cryptology
- EUROCRYPT 2022 pp. 674-705,
DOI 10.1007/978-3-031-07085-3_23, May 2022,
<https://doi.org/10.1007/978-3-031-07085-3_23>.
Appendix A. Test Vectors
This section includes test vectors for the protocol variants
specified in this document. For each ciphersuite specified in
Section 4, there is a set of test vectors for the protocol when
running the OPRF, VOPRF, and POPRF modes. Each test vector lists the
batch size for the evaluation. Each test vector value is encoded as
a hexadecimal byte string. The fields of each test vector are
described below.
"Input": The private client input, an opaque byte string.
"Info": The public info, an opaque byte string. Only present for
POPRF test vectors.
"Blind": The blind value output by Blind(), a serialized Scalar of
Ns bytes long.
"BlindedElement": The blinded value output by Blind(), a serialized
Element of Ne bytes long.
"EvaluatedElement": The evaluated element output by BlindEvaluate(),
a serialized Element of Ne bytes long.
"Proof": The serialized Proof output from GenerateProof() composed
of two serialized Scalar values, each Ns bytes long. Only present
for VOPRF and POPRF test vectors.
"ProofRandomScalar": The random Scalar r computed in
GenerateProof(), a serialized Scalar of Ns bytes long. Only
present for VOPRF and POPRF test vectors.
"Output": The protocol output, an opaque byte string of Nh bytes
long.
Test vectors with batch size B > 1 have inputs separated by a comma
",". Applicable test vectors will have B different values for the
"Input", "Blind", "BlindedElement", "EvaluationElement", and "Output"
fields.
The server key material, pkSm and skSm, are listed under the mode for
each ciphersuite. Both pkSm and skSm are the serialized values of
pkS and skS, respectively, as used in the protocol. Each key pair is
derived from a seed, denoted Seed, and info string, denoted KeyInfo,
which are listed as well, using the DeriveKeyPair function from
Section 3.2.
A.1. ristretto255-SHA512
A.1.1. OPRF Mode
Seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a
3a3
KeyInfo = 74657374206b6579
skSm = 5ebcea5ee37023ccb9fc2d2019f9d7737be85591ae8652ffa9ef0f4d37063
b0e
A.1.1.1. Test Vector 1, Batch Size 1
Input = 00
Blind = 64d37aed22a27f5191de1c1d69fadb899d8862b58eb4220029e036ec4c1f
6706
BlindedElement = 609a0ae68c15a3cf6903766461307e5c8bb2f95e7e6550e1ffa
2dc99e412803c
EvaluationElement = 7ec6578ae5120958eb2db1745758ff379e77cb64fe77b0b2
d8cc917ea0869c7e
Output = 527759c3d9366f277d8c6020418d96bb393ba2afb20ff90df23fb770826
4e2f3ab9135e3bd69955851de4b1f9fe8a0973396719b7912ba9ee8aa7d0b5e24bcf
6
A.1.1.2. Test Vector 2, Batch Size 1
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
Blind = 64d37aed22a27f5191de1c1d69fadb899d8862b58eb4220029e036ec4c1f
6706
BlindedElement = da27ef466870f5f15296299850aa088629945a17d1f5b7f5ff0
43f76b3c06418
EvaluationElement = b4cbf5a4f1eeda5a63ce7b77c7d23f461db3fcab0dd28e4e
17cecb5c90d02c25
Output = f4a74c9c592497375e796aa837e907b1a045d34306a749db9f34221f7e7
50cb4f2a6413a6bf6fa5e19ba6348eb673934a722a7ede2e7621306d18951e7cf2c7
3
A.1.2. VOPRF Mode
Seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a
3a3
KeyInfo = 74657374206b6579
skSm = e6f73f344b79b379f1a0dd37e07ff62e38d9f71345ce62ae3a9bc60b04ccd
909
pkSm = c803e2cc6b05fc15064549b5920659ca4a77b2cca6f04f6b357009335476a
d4e
A.1.2.1. Test Vector 1, Batch Size 1
Input = 00
Blind = 64d37aed22a27f5191de1c1d69fadb899d8862b58eb4220029e036ec4c1f
6706
BlindedElement = 863f330cc1a1259ed5a5998a23acfd37fb4351a793a5b3c090b
642ddc439b945
EvaluationElement = aa8fa048764d5623868679402ff6108d2521884fa138cd7f
9c7669a9a014267e
Proof = ddef93772692e535d1a53903db24367355cc2cc78de93b3be5a8ffcc6985
dd066d4346421d17bf5117a2a1ff0fcb2a759f58a539dfbe857a40bce4cf49ec600d
ProofRandomScalar = 222a5e897cf59db8145db8d16e597e8facb80ae7d4e26d98
81aa6f61d645fc0e
Output = b58cfbe118e0cb94d79b5fd6a6dafb98764dff49c14e1770b566e42402d
a1a7da4d8527693914139caee5bd03903af43a491351d23b430948dd50cde10d32b3
c
A.1.2.2. Test Vector 2, Batch Size 1
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
Blind = 64d37aed22a27f5191de1c1d69fadb899d8862b58eb4220029e036ec4c1f
6706
BlindedElement = cc0b2a350101881d8a4cba4c80241d74fb7dcbfde4a61fde2f9
1443c2bf9ef0c
EvaluationElement = 60a59a57208d48aca71e9e850d22674b611f752bed48b36f
7a91b372bd7ad468
Proof = 401a0da6264f8cf45bb2f5264bc31e109155600babb3cd4e5af7d181a2c9
dc0a67154fabf031fd936051dec80b0b6ae29c9503493dde7393b722eafdf5a50b02
ProofRandomScalar = 222a5e897cf59db8145db8d16e597e8facb80ae7d4e26d98
81aa6f61d645fc0e
Output = 8a9a2f3c7f085b65933594309041fc1898d42d0858e59f90814ae90571a
6df60356f4610bf816f27afdd84f47719e480906d27ecd994985890e5f539e7ea74b
6
A.1.2.3. Test Vector 3, Batch Size 2
Input = 00,5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
Blind = 64d37aed22a27f5191de1c1d69fadb899d8862b58eb4220029e036ec4c1f
6706,222a5e897cf59db8145db8d16e597e8facb80ae7d4e26d9881aa6f61d645fc0
e
BlindedElement = 863f330cc1a1259ed5a5998a23acfd37fb4351a793a5b3c090b
642ddc439b945,90a0145ea9da29254c3a56be4fe185465ebb3bf2a1801f7124bbba
dac751e654
EvaluationElement = aa8fa048764d5623868679402ff6108d2521884fa138cd7f
9c7669a9a014267e,cc5ac221950a49ceaa73c8db41b82c20372a4c8d63e5dded2db
920b7eee36a2a
Proof = cc203910175d786927eeb44ea847328047892ddf8590e723c37205cb7460
0b0a5ab5337c8eb4ceae0494c2cf89529dcf94572ed267473d567aeed6ab873dee08
ProofRandomScalar = 419c4f4f5052c53c45f3da494d2b67b220d02118e0857cdb
cf037f9ea84bbe0c
Output = b58cfbe118e0cb94d79b5fd6a6dafb98764dff49c14e1770b566e42402d
a1a7da4d8527693914139caee5bd03903af43a491351d23b430948dd50cde10d32b3
c,8a9a2f3c7f085b65933594309041fc1898d42d0858e59f90814ae90571a6df6035
6f4610bf816f27afdd84f47719e480906d27ecd994985890e5f539e7ea74b6
A.1.3. POPRF Mode
Seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a
3a3
KeyInfo = 74657374206b6579
skSm = 145c79c108538421ac164ecbe131942136d5570b16d8bf41a24d4337da981
e07
pkSm = c647bef38497bc6ec077c22af65b696efa43bff3b4a1975a3e8e0a1c5a79d
631
A.1.3.1. Test Vector 1, Batch Size 1
Input = 00
Info = 7465737420696e666f
Blind = 64d37aed22a27f5191de1c1d69fadb899d8862b58eb4220029e036ec4c1f
6706
BlindedElement = c8713aa89241d6989ac142f22dba30596db635c772cbf25021f
dd8f3d461f715
EvaluationElement = 1a4b860d808ff19624731e67b5eff20ceb2df3c3c03b906f
5693e2078450d874
Proof = 41ad1a291aa02c80b0915fbfbb0c0afa15a57e2970067a602ddb9e8fd6b7
100de32e1ecff943a36f0b10e3dae6bd266cdeb8adf825d86ef27dbc6c0e30c52206
ProofRandomScalar = 222a5e897cf59db8145db8d16e597e8facb80ae7d4e26d98
81aa6f61d645fc0e
Output = ca688351e88afb1d841fde4401c79efebb2eb75e7998fa9737bd5a82a15
2406d38bd29f680504e54fd4587eddcf2f37a2617ac2fbd2993f7bdf45442ace7d22
1
A.1.3.2. Test Vector 2, Batch Size 1
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
Info = 7465737420696e666f
Blind = 64d37aed22a27f5191de1c1d69fadb899d8862b58eb4220029e036ec4c1f
6706
BlindedElement = f0f0b209dd4d5f1844dac679acc7761b91a2e704879656cb7c2
01e82a99ab07d
EvaluationElement = 8c3c9d064c334c6991e99f286ea2301d1bde170b54003fb9
c44c6d7bd6fc1540
Proof = 4c39992d55ffba38232cdac88fe583af8a85441fefd7d1d4a8d0394cd1de
77018bf135c174f20281b3341ab1f453fe72b0293a7398703384bed822bfdeec8908
ProofRandomScalar = 222a5e897cf59db8145db8d16e597e8facb80ae7d4e26d98
81aa6f61d645fc0e
Output = 7c6557b276a137922a0bcfc2aa2b35dd78322bd500235eb6d6b6f91bc5b
56a52de2d65612d503236b321f5d0bebcbc52b64b92e426f29c9b8b69f52de98ae50
7
A.1.3.3. Test Vector 3, Batch Size 2
Input = 00,5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
Info = 7465737420696e666f
Blind = 64d37aed22a27f5191de1c1d69fadb899d8862b58eb4220029e036ec4c1f
6706,222a5e897cf59db8145db8d16e597e8facb80ae7d4e26d9881aa6f61d645fc0
e
BlindedElement = c8713aa89241d6989ac142f22dba30596db635c772cbf25021f
dd8f3d461f715,423a01c072e06eb1cce96d23acce06e1ea64a609d7ec9e9023f304
9f2d64e50c
EvaluationElement = 1a4b860d808ff19624731e67b5eff20ceb2df3c3c03b906f
5693e2078450d874,aa1f16e903841036e38075da8a46655c94fc92341887eb5819f
46312adfc0504
Proof = 43fdb53be399cbd3561186ae480320caa2b9f36cca0e5b160c4a677b8bbf
4301b28f12c36aa8e11e5a7ef551da0781e863a6dc8c0b2bf5a149c9e00621f02006
ProofRandomScalar = 419c4f4f5052c53c45f3da494d2b67b220d02118e0857cdb
cf037f9ea84bbe0c
Output = ca688351e88afb1d841fde4401c79efebb2eb75e7998fa9737bd5a82a15
2406d38bd29f680504e54fd4587eddcf2f37a2617ac2fbd2993f7bdf45442ace7d22
1,7c6557b276a137922a0bcfc2aa2b35dd78322bd500235eb6d6b6f91bc5b56a52de
2d65612d503236b321f5d0bebcbc52b64b92e426f29c9b8b69f52de98ae507
A.2. decaf448-SHAKE256
A.2.1. OPRF Mode
Seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a
3a3
KeyInfo = 74657374206b6579
skSm = e8b1375371fd11ebeb224f832dcc16d371b4188951c438f751425699ed29e
cc80c6c13e558ccd67634fd82eac94aa8d1f0d7fee990695d1e
A.2.1.1. Test Vector 1, Batch Size 1
Input = 00
Blind = 64d37aed22a27f5191de1c1d69fadb899d8862b58eb4220029e036ec65fa
3833a26e9388336361686ff1f83df55046504dfecad8549ba112
BlindedElement = e0ae01c4095f08e03b19baf47ffdc19cb7d98e583160522a3c7
d6a0b2111cd93a126a46b7b41b730cd7fc943d4e28e590ed33ae475885f6c
EvaluationElement = 50ce4e60eed006e22e7027454b5a4b8319eb2bc8ced609eb
19eb3ad42fb19e06ba12d382cbe7ae342a0cad6ead0ef8f91f00bb7f0cd9c0a2
Output = 37d3f7922d9388a15b561de5829bbf654c4089ede89c0ce0f3f85bcdba0
9e382ce0ab3507e021f9e79706a1798ffeac68ebd5cf62e5eb9838c7068351d97ae3
7
A.2.1.2. Test Vector 2, Batch Size 1
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
Blind = 64d37aed22a27f5191de1c1d69fadb899d8862b58eb4220029e036ec65fa
3833a26e9388336361686ff1f83df55046504dfecad8549ba112
BlindedElement = 86a88dc5c6331ecfcb1d9aacb50a68213803c462e377577cacc
00af28e15f0ddbc2e3d716f2f39ef95f3ec1314a2c64d940a9f295d8f13bb
EvaluationElement = 162e9fa6e9d527c3cd734a31bf122a34dbd5bcb7bb23651f
1768a7a9274cc116c03b58afa6f0dede3994a60066c76370e7328e7062fd5819
Output = a2a652290055cb0f6f8637a249ee45e32ef4667db0b4c80c0a70d2a6416
4d01525cfdad5d870a694ec77972b9b6ec5d2596a5223e5336913f945101f0137f55
e
A.2.2. VOPRF Mode
Seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a
3a3
KeyInfo = 74657374206b6579
skSm = e3c01519a076a326a0eb566343e9b21c115fa18e6e85577ddbe890b33104f
cc2835ddfb14a928dc3f5d79b936e17c76b99e0bf6a1680930e
pkSm = 945fc518c47695cf65217ace04b86ac5e4cbe26ca649d52854bb16c494ce0
9069d6add96b20d4b0ae311a87c9a73e3a146b525763ab2f955
A.2.2.1. Test Vector 1, Batch Size 1
Input = 00
Blind = 64d37aed22a27f5191de1c1d69fadb899d8862b58eb4220029e036ec65fa
3833a26e9388336361686ff1f83df55046504dfecad8549ba112
BlindedElement = 7261bbc335c664ba788f1b1a1a4cd5190cc30e787ef277665ac
1d314f8861e3ec11854ce3ddd42035d9e0f5cddde324c332d8c880abc00eb
EvaluationElement = ca1491a526c28d880806cf0fb0122222392cf495657be6e4
c9d203bceffa46c86406caf8217859d3fb259077af68e5d41b3699410781f467
Proof = f84bbeee47aedf43558dae4b95b3853635a9fc1a9ea7eac9b454c64c66c4
f49cd1c72711c7ac2e06c681e16ea693d5500bbd7b56455df52f69e00b76b4126961
e1562fdbaaac40b7701065cbeece3febbfe09e00160f81775d36daed99d8a2a10be0
759e01b7ee81217203416c9db208
ProofRandomScalar = b1b748135d405ce48c6973401d9455bb8ccd18b01d0295c0
627f67661200dbf9569f73fbb3925daa043a070e5f953d80bb464ea369e5522b
Output = e2ac40b634f36cccd8262b285adff7c9dcc19cd308564a5f4e581d1a853
5773b86fa4fc9f2203c370763695c5093aea4a7aedec4488b1340ba3bf663a23098c
1
A.2.2.2. Test Vector 2, Batch Size 1
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
Blind = 64d37aed22a27f5191de1c1d69fadb899d8862b58eb4220029e036ec65fa
3833a26e9388336361686ff1f83df55046504dfecad8549ba112
BlindedElement = 88287e553939090b888ddc15913e1807dc4757215555e1c3a79
488ef311594729c7fa74c772a732b78440b7d66d0aa35f3bb316f1d93e1b2
EvaluationElement = c00978c73e8e4ee1d447ab0d3ad1754055e72cc85c08e3a0
db170909a9c61cbff1f1e7015f289e3038b0f341faea5d7780c130106065c231
Proof = 7a2831a6b237e11ac1657d440df93bc5ce00f552e6020a99d5c956ffc4d0
7b5ade3e82ecdc257fd53d76239e733e0a1313e84ce16cc0d82734806092a693d7e8
d3c420c2cb6ccd5d0ca32514fb78e9ad0973ebdcb52eba438fc73948d76339ee7101
21d83e2fe6f001cfdf551aff9f36
ProofRandomScalar = b1b748135d405ce48c6973401d9455bb8ccd18b01d0295c0
627f67661200dbf9569f73fbb3925daa043a070e5f953d80bb464ea369e5522b
Output = 862952380e07ec840d9f6e6f909c5a25d16c3dacb586d89a181b4aa7380
c959baa8c480fe8e6c64e089d68ea7aeeb5817bd524d7577905b5bab487690048c94
1
A.2.2.3. Test Vector 3, Batch Size 2
Input = 00,5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
Blind = 64d37aed22a27f5191de1c1d69fadb899d8862b58eb4220029e036ec65fa
3833a26e9388336361686ff1f83df55046504dfecad8549ba112,b1b748135d405ce
48c6973401d9455bb8ccd18b01d0295c0627f67661200dbf9569f73fbb3925daa043
a070e5f953d80bb464ea369e5522b
BlindedElement = 7261bbc335c664ba788f1b1a1a4cd5190cc30e787ef277665ac
1d314f8861e3ec11854ce3ddd42035d9e0f5cddde324c332d8c880abc00eb,2e15f3
93c035492a1573627a3606e528c6294c767c8d43b8c691ef70a52cc7dc7d1b53fe45
8350a270abb7c231b87ba58266f89164f714d9
EvaluationElement = ca1491a526c28d880806cf0fb0122222392cf495657be6e4
c9d203bceffa46c86406caf8217859d3fb259077af68e5d41b3699410781f467,8ec
68e9871b296e81c55647ce64a04fe75d19932f1400544cd601468c60f998408bbb54
6601d4a636e8be279e558d70b95c8d4a4f61892be
Proof = 167d922f0a6ffa845eed07f8aa97b6ac746d902ecbeb18f49c009adc0521
eab1e4d275b74a2dc266b7a194c854e85e7eb54a9a36376dfc04ec7f3bd55fc9618c
3970cb548e064f8a2f06183a5702933dbc3e4c25a73438f2108ee1981c306181003c
7ea92fce963ec7b4ba4f270e6d38
ProofRandomScalar = 63798726803c9451ba405f00ef3acb633ddf0c420574a2ec
6cbf28f840800e355c9fbaac10699686de2724ed22e797a00f3bd93d105a7f23
Output = e2ac40b634f36cccd8262b285adff7c9dcc19cd308564a5f4e581d1a853
5773b86fa4fc9f2203c370763695c5093aea4a7aedec4488b1340ba3bf663a23098c
1,862952380e07ec840d9f6e6f909c5a25d16c3dacb586d89a181b4aa7380c959baa
8c480fe8e6c64e089d68ea7aeeb5817bd524d7577905b5bab487690048c941
A.2.3. POPRF Mode
Seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a
3a3
KeyInfo = 74657374206b6579
skSm = 792a10dcbd3ba4a52a054f6f39186623208695301e7adb9634b74709ab22d
e402990eb143fd7c67ac66be75e0609705ecea800992aac8e19
pkSm = 6c9d12723a5bbcf305522cc04b4a34d9ced2e12831826018ea7b5dcf54526
47ad262113059bf0f6e4354319951b9d513c74f29cb0eec38c1
A.2.3.1. Test Vector 1, Batch Size 1
Input = 00
Info = 7465737420696e666f
Blind = 64d37aed22a27f5191de1c1d69fadb899d8862b58eb4220029e036ec65fa
3833a26e9388336361686ff1f83df55046504dfecad8549ba112
BlindedElement = 161183c13c6cb33b0e4f9b7365f8c5c12d13c72f8b62d276ca0
9368d093dce9b42198276b9e9d870ac392dda53efd28d1b7e6e8c060cdc42
EvaluationElement = 06ec89dfde25bb2a6f0145ac84b91ac277b35de39ad1d6f4
02a8e46414952ce0d9ea1311a4ece283e2b01558c7078b040cfaa40dd63b3e6c
Proof = 66caee75bf2460429f620f6ad3e811d524cb8ddd848a435fc5d89af48877
abf6506ee341a0b6f67c2d76cd021e5f3d1c9abe5aa9f0dce016da746135fedba2af
41ed1d01659bfd6180d96bc1b7f320c0cb6926011ce392ecca748662564892bae665
16acaac6ca39aadf6fcca95af406
ProofRandomScalar = b1b748135d405ce48c6973401d9455bb8ccd18b01d0295c0
627f67661200dbf9569f73fbb3925daa043a070e5f953d80bb464ea369e5522b
Output = 4423f6dcc1740688ea201de57d76824d59cd6b859e1f9884b7eebc49b0b
971358cf9cb075df1536a8ea31bcf55c3e31c2ba9cfa8efe54448d17091daeb9924e
d
A.2.3.2. Test Vector 2, Batch Size 1
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
Info = 7465737420696e666f
Blind = 64d37aed22a27f5191de1c1d69fadb899d8862b58eb4220029e036ec65fa
3833a26e9388336361686ff1f83df55046504dfecad8549ba112
BlindedElement = 12082b6a381c6c51e85d00f2a3d828cdeab3f5cb19a10b9c014
c33826764ab7e7cfb8b4ff6f411bddb2d64e62a472af1cd816e5b712790c6
EvaluationElement = f2919b7eedc05ab807c221fce2b12c4ae9e19e6909c47845
64b690d1972d2994ca623f273afc67444d84ea40cbc58fcdab7945f321a52848
Proof = a295677c54d1bc4286330907fc2490a7de163da26f9ce03a462a452fea42
2b19ade296ba031359b3b6841e48455d20519ad01b4ac4f0b92e76d3cf16fbef0a3f
72791a8401ef2d7081d361e502e96b2c60608b9fa566f43d4611c2f161d83aabef7f
8017332b26ed1daaf80440772022
ProofRandomScalar = b1b748135d405ce48c6973401d9455bb8ccd18b01d0295c0
627f67661200dbf9569f73fbb3925daa043a070e5f953d80bb464ea369e5522b
Output = 8691905500510843902c44bdd9730ab9dc3925aa58ff9dd42765a2baf63
3126de0c3adb93bef5652f38e5827b6396e87643960163a560fc4ac9738c8de4e4a8
d
A.2.3.3. Test Vector 3, Batch Size 2
Input = 00,5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
Info = 7465737420696e666f
Blind = 64d37aed22a27f5191de1c1d69fadb899d8862b58eb4220029e036ec65fa
3833a26e9388336361686ff1f83df55046504dfecad8549ba112,b1b748135d405ce
48c6973401d9455bb8ccd18b01d0295c0627f67661200dbf9569f73fbb3925daa043
a070e5f953d80bb464ea369e5522b
BlindedElement = 161183c13c6cb33b0e4f9b7365f8c5c12d13c72f8b62d276ca0
9368d093dce9b42198276b9e9d870ac392dda53efd28d1b7e6e8c060cdc42,fc8847
d43fb4cea4e408f585661a8f2867533fa91d22155d3127a22f18d3b007add480f7d3
00bca93fa47fe87ae06a57b7d0f0d4c30b12f0
EvaluationElement = 06ec89dfde25bb2a6f0145ac84b91ac277b35de39ad1d6f4
02a8e46414952ce0d9ea1311a4ece283e2b01558c7078b040cfaa40dd63b3e6c,2e7
4c626d07de49b1c8c21d87120fd78105f485e36816af9bde3e3efbeef76815326062
fd333925b66c5ce5a20f100bf01770c16609f990a
Proof = fd94db736f97ea4efe9d0d4ad2933072697a6bbeb32834057b23edf7c700
9f011dfa72157f05d2a507c2bbf0b54cad99ab99de05921c021fda7d70e65bcecdb0
5f9a30154127ace983c74d10fd910b554c5e95f6bd1565fd1f3dbbe3c523ece5c72d
57a559b7be1368c4786db4a3c910
ProofRandomScalar = 63798726803c9451ba405f00ef3acb633ddf0c420574a2ec
6cbf28f840800e355c9fbaac10699686de2724ed22e797a00f3bd93d105a7f23
Output = 4423f6dcc1740688ea201de57d76824d59cd6b859e1f9884b7eebc49b0b
971358cf9cb075df1536a8ea31bcf55c3e31c2ba9cfa8efe54448d17091daeb9924e
d,8691905500510843902c44bdd9730ab9dc3925aa58ff9dd42765a2baf633126de0
c3adb93bef5652f38e5827b6396e87643960163a560fc4ac9738c8de4e4a8d
A.3. P256-SHA256
A.3.1. OPRF Mode
Seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a
3a3
KeyInfo = 74657374206b6579
skSm = 159749d750713afe245d2d39ccfaae8381c53ce92d098a9375ee70739c7ac
0bf
A.3.1.1. Test Vector 1, Batch Size 1
Input = 00
Blind = 3338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7a
d364
BlindedElement = 03723a1e5c09b8b9c18d1dcbca29e8007e95f14f4732d9346d4
90ffc195110368d
EvaluationElement = 030de02ffec47a1fd53efcdd1c6faf5bdc270912b8749e78
3c7ca75bb412958832
Output = a0b34de5fa4c5b6da07e72af73cc507cceeb48981b97b7285fc375345fe
495dd
A.3.1.2. Test Vector 2, Batch Size 1
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
Blind = 3338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7a
d364
BlindedElement = 03cc1df781f1c2240a64d1c297b3f3d16262ef5d4cf10273488
2675c26231b0838
EvaluationElement = 03a0395fe3828f2476ffcd1f4fe540e5a8489322d398be3c
4e5a869db7fcb7c52c
Output = c748ca6dd327f0ce85f4ae3a8cd6d4d5390bbb804c9e12dcf94f853fece
3dcce
A.3.2. VOPRF Mode
Seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a
3a3
KeyInfo = 74657374206b6579
skSm = ca5d94c8807817669a51b196c34c1b7f8442fde4334a7121ae4736364312f
ca6
pkSm = 03e17e70604bcabe198882c0a1f27a92441e774224ed9c702e51dd17038b1
02462
A.3.2.1. Test Vector 1, Batch Size 1
Input = 00
Blind = 3338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7a
d364
BlindedElement = 02dd05901038bb31a6fae01828fd8d0e49e35a486b5c5d4b499
4013648c01277da
EvaluationElement = 0209f33cab60cf8fe69239b0afbcfcd261af4c1c5632624f
2e9ba29b90ae83e4a2
Proof = e7c2b3c5c954c035949f1f74e6bce2ed539a3be267d1481e9ddb178533df
4c2664f69d065c604a4fd953e100b856ad83804eb3845189babfa5a702090d6fc5fa
ProofRandomScalar = f9db001266677f62c095021db018cd8cbb55941d4073698c
e45c405d1348b7b1
Output = 0412e8f78b02c415ab3a288e228978376f99927767ff37c5718d420010a
645a1
A.3.2.2. Test Vector 2, Batch Size 1
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
Blind = 3338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7a
d364
BlindedElement = 03cd0f033e791c4d79dfa9c6ed750f2ac009ec46cd4195ca6fd
3800d1e9b887dbd
EvaluationElement = 030d2985865c693bf7af47ba4d3a3813176576383d19aff0
03ef7b0784a0d83cf1
Proof = 2787d729c57e3d9512d3aa9e8708ad226bc48e0f1750b0767aaff73482c4
4b8d2873d74ec88aebd3504961acea16790a05c542d9fbff4fe269a77510db00abab
ProofRandomScalar = f9db001266677f62c095021db018cd8cbb55941d4073698c
e45c405d1348b7b1
Output = 771e10dcd6bcd3664e23b8f2a710cfaaa8357747c4a8cbba03133967b5c
24f18
A.3.2.3. Test Vector 3, Batch Size 2
Input = 00,5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
Blind = 3338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7a
d364,f9db001266677f62c095021db018cd8cbb55941d4073698ce45c405d1348b7b
1
BlindedElement = 02dd05901038bb31a6fae01828fd8d0e49e35a486b5c5d4b499
4013648c01277da,03462e9ae64cae5b83ba98a6b360d942266389ac369b923eb3d5
57213b1922f8ab
EvaluationElement = 0209f33cab60cf8fe69239b0afbcfcd261af4c1c5632624f
2e9ba29b90ae83e4a2,02bb24f4d838414aef052a8f044a6771230ca69c0a5677540
fff738dd31bb69771
Proof = bdcc351707d02a72ce49511c7db990566d29d6153ad6f8982fad2b435d6c
e4d60da1e6b3fa740811bde34dd4fe0aa1b5fe6600d0440c9ddee95ea7fad7a60cf2
ProofRandomScalar = 350e8040f828bf6ceca27405420cdf3d63cb3aef005f40ba
51943c8026877963
Output = 0412e8f78b02c415ab3a288e228978376f99927767ff37c5718d420010a
645a1,771e10dcd6bcd3664e23b8f2a710cfaaa8357747c4a8cbba03133967b5c24f
18
A.3.3. POPRF Mode
Seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a
3a3
KeyInfo = 74657374206b6579
skSm = 6ad2173efa689ef2c27772566ad7ff6e2d59b3b196f00219451fb2c89ee4d
ae2
pkSm = 030d7ff077fddeec965db14b794f0cc1ba9019b04a2f4fcc1fa525dedf72e
2a3e3
A.3.3.1. Test Vector 1, Batch Size 1
Input = 00
Info = 7465737420696e666f
Blind = 3338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7a
d364
BlindedElement = 031563e127099a8f61ed51eeede05d747a8da2be329b40ba1f0
db0b2bd9dd4e2c0
EvaluationElement = 02c5e5300c2d9e6ba7f3f4ad60500ad93a0157e6288eb04b
67e125db024a2c74d2
Proof = f8a33690b87736c854eadfcaab58a59b8d9c03b569110b6f31f8bf7577f3
fbb85a8a0c38468ccde1ba942be501654adb106167c8eb178703ccb42bccffb9231a
ProofRandomScalar = f9db001266677f62c095021db018cd8cbb55941d4073698c
e45c405d1348b7b1
Output = 193a92520bd8fd1f37accb918040a57108daa110dc4f659abe212636d24
5c592
A.3.3.2. Test Vector 2, Batch Size 1
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
Info = 7465737420696e666f
Blind = 3338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7a
d364
BlindedElement = 021a440ace8ca667f261c10ac7686adc66a12be31e3520fca31
7643a1eee9dcd4d
EvaluationElement = 0208ca109cbae44f4774fc0bdd2783efdcb868cb4523d521
96f700210e777c5de3
Proof = 043a8fb7fc7fd31e35770cabda4753c5bf0ecc1e88c68d7d35a62bf2631e
875af4613641be2d1875c31d1319d191c4bbc0d04875f4fd03c31d3d17dd8e069b69
ProofRandomScalar = f9db001266677f62c095021db018cd8cbb55941d4073698c
e45c405d1348b7b1
Output = 1e6d164cfd835d88a31401623549bf6b9b306628ef03a7962921d62bc5f
fce8c
A.3.3.3. Test Vector 3, Batch Size 2
Input = 00,5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
Info = 7465737420696e666f
Blind = 3338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7a
d364,f9db001266677f62c095021db018cd8cbb55941d4073698ce45c405d1348b7b
1
BlindedElement = 031563e127099a8f61ed51eeede05d747a8da2be329b40ba1f0
db0b2bd9dd4e2c0,03ca4ff41c12fadd7a0bc92cf856732b21df652e01a3abdf0fa8
847da053db213c
EvaluationElement = 02c5e5300c2d9e6ba7f3f4ad60500ad93a0157e6288eb04b
67e125db024a2c74d2,02f0b6bcd467343a8d8555a99dc2eed0215c71898c5edb77a
3d97ddd0dbad478e8
Proof = 8fbd85a32c13aba79db4b42e762c00687d6dbf9c8cb97b2a225645ccb00d
9d7580b383c885cdfd07df448d55e06f50f6173405eee5506c0ed0851ff718d13e68
ProofRandomScalar = 350e8040f828bf6ceca27405420cdf3d63cb3aef005f40ba
51943c8026877963
Output = 193a92520bd8fd1f37accb918040a57108daa110dc4f659abe212636d24
5c592,1e6d164cfd835d88a31401623549bf6b9b306628ef03a7962921d62bc5ffce
8c
A.4. P384-SHA384
A.4.1. OPRF Mode
Seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a
3a3
KeyInfo = 74657374206b6579
skSm = dfe7ddc41a4646901184f2b432616c8ba6d452f9bcd0c4f75a5150ef2b2ed
02ef40b8b92f60ae591bcabd72a6518f188
A.4.1.1. Test Vector 1, Batch Size 1
Input = 00
Blind = 504650f53df8f16f6861633388936ea23338fa65ec36e0290022b48eb562
889d89dbfa691d1cde91517fa222ed7ad364
BlindedElement = 02a36bc90e6db34096346eaf8b7bc40ee1113582155ad379700
3ce614c835a874343701d3f2debbd80d97cbe45de6e5f1f
EvaluationElement = 03af2a4fc94770d7a7bf3187ca9cc4faf3732049eded2442
ee50fbddda58b70ae2999366f72498cdbc43e6f2fc184afe30
Output = ed84ad3f31a552f0456e58935fcc0a3039db42e7f356dcb32aa6d487b6b
815a07d5813641fb1398c03ddab5763874357
A.4.1.2. Test Vector 2, Batch Size 1
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
Blind = 504650f53df8f16f6861633388936ea23338fa65ec36e0290022b48eb562
889d89dbfa691d1cde91517fa222ed7ad364
BlindedElement = 02def6f418e3484f67a124a2ce1bfb19de7a4af568ede6a1ebb
2733882510ddd43d05f2b1ab5187936a55e50a847a8b900
EvaluationElement = 034e9b9a2960b536f2ef47d8608b21597ba400d5abfa1825
fd21c36b75f927f396bf3716c96129d1fa4a77fa1d479c8d7b
Output = dd4f29da869ab9355d60617b60da0991e22aaab243a3460601e48b07585
9d1c526d36597326f1b985778f781a1682e75
A.4.2. VOPRF Mode
Seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a
3a3
KeyInfo = 74657374206b6579
skSm = 051646b9e6e7a71ae27c1e1d0b87b4381db6d3595eeeb1adb41579adbf992
f4278f9016eafc944edaa2b43183581779d
pkSm = 031d689686c611991b55f1a1d8f4305ccd6cb719446f660a30db61b7aa87b
46acf59b7c0d4a9077b3da21c25dd482229a0
A.4.2.1. Test Vector 1, Batch Size 1
Input = 00
Blind = 504650f53df8f16f6861633388936ea23338fa65ec36e0290022b48eb562
889d89dbfa691d1cde91517fa222ed7ad364
BlindedElement = 02d338c05cbecb82de13d6700f09cb61190543a7b7e2c6cd4fc
a56887e564ea82653b27fdad383995ea6d02cf26d0e24d9
EvaluationElement = 02a7bba589b3e8672aa19e8fd258de2e6aae20101c8d7612
46de97a6b5ee9cf105febce4327a326255a3c604f63f600ef6
Proof = bfc6cf3859127f5fe25548859856d6b7fa1c7459f0ba5712a806fc091a30
00c42d8ba34ff45f32a52e40533efd2a03bc87f3bf4f9f58028297ccb9ccb18ae718
2bcd1ef239df77e3be65ef147f3acf8bc9cbfc5524b702263414f043e3b7ca2e
ProofRandomScalar = 803d955f0e073a04aa5d92b3fb739f56f9db001266677f62
c095021db018cd8cbb55941d4073698ce45c405d1348b7b1
Output = 3333230886b562ffb8329a8be08fea8025755372817ec969d114d1203d0
26b4a622beab60220bf19078bca35a529b35c
A.4.2.2. Test Vector 2, Batch Size 1
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
Blind = 504650f53df8f16f6861633388936ea23338fa65ec36e0290022b48eb562
889d89dbfa691d1cde91517fa222ed7ad364
BlindedElement = 02f27469e059886f221be5f2cca03d2bdc61e55221721c3b3e5
6fc012e36d31ae5f8dc058109591556a6dbd3a8c69c433b
EvaluationElement = 03f16f903947035400e96b7f531a38d4a07ac89a80f89d86
a1bf089c525a92c7f4733729ca30c56ce78b1ab4f7d92db8b4
Proof = d005d6daaad7571414c1e0c75f7e57f2113ca9f4604e84bc90f9be52da89
6fff3bee496dcde2a578ae9df315032585f801fb21c6080ac05672b291e575a40295
b306d967717b28e08fcc8ad1cab47845d16af73b3e643ddcc191208e71c64630
ProofRandomScalar = 803d955f0e073a04aa5d92b3fb739f56f9db001266677f62
c095021db018cd8cbb55941d4073698ce45c405d1348b7b1
Output = b91c70ea3d4d62ba922eb8a7d03809a441e1c3c7af915cbc2226f485213
e895942cd0f8580e6d99f82221e66c40d274f
A.4.2.3. Test Vector 3, Batch Size 2
Input = 00,5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
Blind = 504650f53df8f16f6861633388936ea23338fa65ec36e0290022b48eb562
889d89dbfa691d1cde91517fa222ed7ad364,803d955f0e073a04aa5d92b3fb739f5
6f9db001266677f62c095021db018cd8cbb55941d4073698ce45c405d1348b7b1
BlindedElement = 02d338c05cbecb82de13d6700f09cb61190543a7b7e2c6cd4fc
a56887e564ea82653b27fdad383995ea6d02cf26d0e24d9,02fa02470d7f151018b4
1e82223c32fad824de6ad4b5ce9f8e9f98083c9a726de9a1fc39d7a0cb6f4f188dd9
cea01474cd
EvaluationElement = 02a7bba589b3e8672aa19e8fd258de2e6aae20101c8d7612
46de97a6b5ee9cf105febce4327a326255a3c604f63f600ef6,028e9e115625ff4c2
f07bf87ce3fd73fc77994a7a0c1df03d2a630a3d845930e2e63a165b114d98fe34e6
1b68d23c0b50a
Proof = 6d8dcbd2fc95550a02211fb78afd013933f307d21e7d855b0b1ed0af7807
6d8137ad8b0a1bfa05676d325249c1dbb9a52bd81b1c2b7b0efc77cf7b278e1c947f
6283f1d4c513053fc0ad19e026fb0c30654b53d9cea4b87b037271b5d2e2d0ea
ProofRandomScalar = a097e722ed2427de86966910acba9f5c350e8040f828bf6c
eca27405420cdf3d63cb3aef005f40ba51943c8026877963
Output = 3333230886b562ffb8329a8be08fea8025755372817ec969d114d1203d0
26b4a622beab60220bf19078bca35a529b35c,b91c70ea3d4d62ba922eb8a7d03809
a441e1c3c7af915cbc2226f485213e895942cd0f8580e6d99f82221e66c40d274f
A.4.3. POPRF Mode
Seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a
3a3
KeyInfo = 74657374206b6579
skSm = 5b2690d6954b8fbb159f19935d64133f12770c00b68422559c65431942d72
1ff79d47d7a75906c30b7818ec0f38b7fb2
pkSm = 02f00f0f1de81e5d6cf18140d4926ffdc9b1898c48dc49657ae36eb1e45de
b8b951aaf1f10c82d2eaa6d02aafa3f10d2b6
A.4.3.1. Test Vector 1, Batch Size 1
Input = 00
Info = 7465737420696e666f
Blind = 504650f53df8f16f6861633388936ea23338fa65ec36e0290022b48eb562
889d89dbfa691d1cde91517fa222ed7ad364
BlindedElement = 03859b36b95e6564faa85cd3801175eda2949707f6aa0640ad0
93cbf8ad2f58e762f08b56b2a1b42a64953aaf49cbf1ae3
EvaluationElement = 0220710e2e00306453f5b4f574cb6a512453f35c45080d09
373e190c19ce5b185914fbf36582d7e0754bb7c8b683205b91
Proof = 82a17ef41c8b57f1e3122311b4d5cd39a63df0f67443ef18d961f9b659c1
601ced8d3c64b294f604319ca80230380d437a49c7af0d620e22116669c008ebb767
d90283d573b49cdb49e3725889620924c2c4b047a2a6225a3ba27e640ebddd33
ProofRandomScalar = 803d955f0e073a04aa5d92b3fb739f56f9db001266677f62
c095021db018cd8cbb55941d4073698ce45c405d1348b7b1
Output = 0188653cfec38119a6c7dd7948b0f0720460b4310e40824e048bf82a165
27303ed449a08caf84272c3bbc972ede797df
A.4.3.2. Test Vector 2, Batch Size 1
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
Info = 7465737420696e666f
Blind = 504650f53df8f16f6861633388936ea23338fa65ec36e0290022b48eb562
889d89dbfa691d1cde91517fa222ed7ad364
BlindedElement = 03f7efcb4aaf000263369d8a0621cb96b81b3206e99876de2a0
0699ed4c45acf3969cd6e2319215395955d3f8d8cc1c712
EvaluationElement = 034993c818369927e74b77c400376fd1ae29b6ac6c6ddb77
6cf10e4fbc487826531b3cf0b7c8ca4d92c7af90c9def85ce6
Proof = 693471b5dff0cd6a5c00ea34d7bf127b2795164e3bdb5f39a1e5edfbd13e
443bc516061cd5b8449a473c2ceeccada9f3e5b57302e3d7bc5e28d38d6e3a3056e1
e73b6cc030f5180f8a1ffa45aa923ee66d2ad0a07b500f2acc7fb99b5506465c
ProofRandomScalar = 803d955f0e073a04aa5d92b3fb739f56f9db001266677f62
c095021db018cd8cbb55941d4073698ce45c405d1348b7b1
Output = ff2a527a21cc43b251a567382677f078c6e356336aec069dea8ba369953
43ca3b33bb5d6cf15be4d31a7e6d75b30d3f5
A.4.3.3. Test Vector 3, Batch Size 2
Input = 00,5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
Info = 7465737420696e666f
Blind = 504650f53df8f16f6861633388936ea23338fa65ec36e0290022b48eb562
889d89dbfa691d1cde91517fa222ed7ad364,803d955f0e073a04aa5d92b3fb739f5
6f9db001266677f62c095021db018cd8cbb55941d4073698ce45c405d1348b7b1
BlindedElement = 03859b36b95e6564faa85cd3801175eda2949707f6aa0640ad0
93cbf8ad2f58e762f08b56b2a1b42a64953aaf49cbf1ae3,021a65d618d645f1a20b
c33b06deaa7e73d6d634c8a56a3d02b53a732b69a5c53c5a207ea33d5afdcde9a22d
59726bce51
EvaluationElement = 0220710e2e00306453f5b4f574cb6a512453f35c45080d09
373e190c19ce5b185914fbf36582d7e0754bb7c8b683205b91,02017657b315ec65e
f861505e596c8645d94685dd7602cdd092a8f1c1c0194a5d0485fe47d071d972ab51
4370174cc23f5
Proof = 4a0b2fe96d5b2a046a0447fe079b77859ef11a39a3520d6ff7c626aad9b4
73b724fb0cf188974ec961710a62162a83e97e0baa9eeada73397032d928b3e97b1e
a92ad9458208302be3681b8ba78bcc17745bac00f84e0fdc98a6a8cba009c080
ProofRandomScalar = a097e722ed2427de86966910acba9f5c350e8040f828bf6c
eca27405420cdf3d63cb3aef005f40ba51943c8026877963
Output = 0188653cfec38119a6c7dd7948b0f0720460b4310e40824e048bf82a165
27303ed449a08caf84272c3bbc972ede797df,ff2a527a21cc43b251a567382677f0
78c6e356336aec069dea8ba36995343ca3b33bb5d6cf15be4d31a7e6d75b30d3f5
A.5. P521-SHA512
A.5.1. OPRF Mode
Seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a
3a3
KeyInfo = 74657374206b6579
skSm = 0153441b8faedb0340439036d6aed06d1217b34c42f17f8db4c5cc610a4a9
55d698a688831b16d0dc7713a1aa3611ec60703bffc7dc9c84e3ed673b3dbe1d5fcc
ea6
A.5.1.1. Test Vector 1, Batch Size 1
Input = 00
Blind = 00d1dccf7a51bafaf75d4a866d53d8cafe4d504650f53df8f16f68616333
88936ea23338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7a
d364
BlindedElement = 0300e78bf846b0e1e1a3c320e353d758583cd876df56100a3a1
e62bacba470fa6e0991be1be80b721c50c5fd0c672ba764457acc18c6200704e9294
fbf28859d916351
EvaluationElement = 030166371cf827cb2fb9b581f97907121a16e2dc5d8b10ce
9f0ede7f7d76a0d047657735e8ad07bcda824907b3e5479bd72cdef6b839b967ba5c
58b118b84d26f2ba07
Output = 26232de6fff83f812adadadb6cc05d7bbeee5dca043dbb16b03488abb99
81d0a1ef4351fad52dbd7e759649af393348f7b9717566c19a6b8856284d69375c80
9
A.5.1.2. Test Vector 2, Batch Size 1
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
Blind = 00d1dccf7a51bafaf75d4a866d53d8cafe4d504650f53df8f16f68616333
88936ea23338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7a
d364
BlindedElement = 0300c28e57e74361d87e0c1874e5f7cc1cc796d61f9cad50427
cf54655cdb455613368d42b27f94bf66f59f53c816db3e95e68e1b113443d66a99b3
693bab88afb556b
EvaluationElement = 0301ad453607e12d0cc11a3359332a40c3a254eaa1afc642
96528d55bed07ba322e72e22cf3bcb50570fd913cb54f7f09c17aff8787af75f6a7f
af5640cbb2d9620a6e
Output = ad1f76ef939042175e007738906ac0336bbd1d51e287ebaa66901abdd32
4ea3ffa40bfc5a68e7939c2845e0fd37a5a6e76dadb9907c6cc8579629757fd4d04b
a
A.5.2. VOPRF Mode
Seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a
3a3
KeyInfo = 74657374206b6579
skSm = 015c7fc1b4a0b1390925bae915bd9f3d72009d44d9241b962428aad5d13f2
2803311e7102632a39addc61ea440810222715c9d2f61f03ea424ec9ab1fe5e31cf9
238
pkSm = 0301505d646f6e4c9102451eb39730c4ba1c4087618641edbdba4a60896b0
7fd0c9414ce553cbf25b81dfcca50a8f6724ab7a2bc4d0cf736967a287bb6084cc06
78ac0
A.5.2.1. Test Vector 1, Batch Size 1
Input = 00
Blind = 00d1dccf7a51bafaf75d4a866d53d8cafe4d504650f53df8f16f68616333
88936ea23338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7a
d364
BlindedElement = 0301d6e4fb545e043ddb6aee5d5ceeee1b44102615ab04430c2
7dd0f56988dedcb1df32ef384f160e0e76e718605f14f3f582f9357553d153b99679
5b4b3628a4f6380
EvaluationElement = 03013fdeaf887f3d3d283a79e696a54b66ff0edcb559265e
204a958acf840e0930cc147e2a6835148d8199eebc26c03e9394c9762a1c991dde40
bca0f8ca003eefb045
Proof = 0077fcc8ec6d059d7759b0a61f871e7c1dadc65333502e09a51994328f79
e5bda3357b9a4f410a1760a3612c2f8f27cb7cb032951c047cc66da60da583df7b24
7edd0188e5eb99c71799af1d80d643af16ffa1545acd9e9233fbb370455b10eb257e
a12a1667c1b4ee5b0ab7c93d50ae89602006960f083ca9adc4f6276c0ad60440393c
ProofRandomScalar = 015e80ae32363b32cb76ad4b95a5a34e46bb803d955f0e07
3a04aa5d92b3fb739f56f9db001266677f62c095021db018cd8cbb55941d4073698c
e45c405d1348b7b1
Output = 5e003d9b2fb540b3d4bab5fedd154912246da1ee5e557afd8f56415faa1
a0fadff6517da802ee254437e4f60907b4cda146e7ba19e249eef7be405549f62954
b
A.5.2.2. Test Vector 2, Batch Size 1
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
Blind = 00d1dccf7a51bafaf75d4a866d53d8cafe4d504650f53df8f16f68616333
88936ea23338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7a
d364
BlindedElement = 03005b05e656cb609ce5ff5faf063bb746d662d67bbd07c0626
38396f52f0392180cf2365cabb0ece8e19048961d35eeae5d5fa872328dce98df076
ee154dd191c615e
EvaluationElement = 0301b19fcf482b1fff04754e282292ed736c5f0aa080d4f4
2663cd3a416c6596f03129e8e096d8671fe5b0d19838312c511d2ce08d431e43e3ef
06199d8cab7426238d
Proof = 01ec9fece444caa6a57032e8963df0e945286f88fbdf233fb5101f0924f7
ea89c47023f5f72f240e61991fd33a299b5b38c45a5e2dd1a67b072e59dfe86708a3
59c701e38d383c60cf6969463bcf13251bedad47b7941f52e409a3591398e2792441
0b18a301c0e19f527cad504fa08388050ac634e1b05c5216d337742f2754e1fc502f
ProofRandomScalar = 015e80ae32363b32cb76ad4b95a5a34e46bb803d955f0e07
3a04aa5d92b3fb739f56f9db001266677f62c095021db018cd8cbb55941d4073698c
e45c405d1348b7b1
Output = fa15eebba81ecf40954f7135cb76f69ef22c6bae394d1a4362f9b03066b
54b6604d39f2e53369ca6762a3d9787e230e832aa85955af40ecb8deebb009a8cf47
4
A.5.2.3. Test Vector 3, Batch Size 2
Input = 00,5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
Blind = 00d1dccf7a51bafaf75d4a866d53d8cafe4d504650f53df8f16f68616333
88936ea23338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7a
d364,015e80ae32363b32cb76ad4b95a5a34e46bb803d955f0e073a04aa5d92b3fb7
39f56f9db001266677f62c095021db018cd8cbb55941d4073698ce45c405d1348b7b
1
BlindedElement = 0301d6e4fb545e043ddb6aee5d5ceeee1b44102615ab04430c2
7dd0f56988dedcb1df32ef384f160e0e76e718605f14f3f582f9357553d153b99679
5b4b3628a4f6380,0301403b597538b939b450c93586ba275f9711ba07e42364bac1
d5769c6824a8b55be6f9a536df46d952b11ab2188363b3d6737635d9543d4dba14a6
e19421b9245bf5
EvaluationElement = 03013fdeaf887f3d3d283a79e696a54b66ff0edcb559265e
204a958acf840e0930cc147e2a6835148d8199eebc26c03e9394c9762a1c991dde40
bca0f8ca003eefb045,03001f96424497e38c46c904978c2fa1636c5c3dd2e634a85
d8a7265977c5dce1f02c7e6c118479f0751767b91a39cce6561998258591b5d7c1bb
02445a9e08e4f3e8d
Proof = 00b4d215c8405e57c7a4b53398caf55f1f1623aaeb22408ddb9ea2913090
9b3f95dbb1ff366e81e86e918f9f2fd8b80dbb344cd498c9499d112905e585417e00
68c600fe5dea18b389ef6c4cc062935607b8ccbbb9a84fba3143868a3e8a58efa0bf
6ca642804d09dc06e980f64837811227c4267b217f1099a4e28b0854f4e5ee659796
ProofRandomScalar = 01ec21c7bb69b0734cb48dfd68433dd93b0fa097e722ed24
27de86966910acba9f5c350e8040f828bf6ceca27405420cdf3d63cb3aef005f40ba
51943c8026877963
Output = 5e003d9b2fb540b3d4bab5fedd154912246da1ee5e557afd8f56415faa1
a0fadff6517da802ee254437e4f60907b4cda146e7ba19e249eef7be405549f62954
b,fa15eebba81ecf40954f7135cb76f69ef22c6bae394d1a4362f9b03066b54b6604
d39f2e53369ca6762a3d9787e230e832aa85955af40ecb8deebb009a8cf474
A.5.3. POPRF Mode
Seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a
3a3
KeyInfo = 74657374206b6579
skSm = 014893130030ce69cf714f536498a02ff6b396888f9bb507985c32928c442
7d6d39de10ef509aca4240e8569e3a88debc0d392e3361bcd934cb9bdd59e339dff7
b27
pkSm = 0301de8ceb9ffe9237b1bba87c320ea0bebcfc3447fe6f278065c6c69886d
692d1126b79b6844f829940ace9b52a5e26882cf7cbc9e57503d4cca3cd834584729
f812a
A.5.3.1. Test Vector 1, Batch Size 1
Input = 00
Info = 7465737420696e666f
Blind = 00d1dccf7a51bafaf75d4a866d53d8cafe4d504650f53df8f16f68616333
88936ea23338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7a
d364
BlindedElement = 020095cff9d7ecf65bdfee4ea92d6e748d60b02de34ad98094f
82e25d33a8bf50138ccc2cc633556f1a97d7ea9438cbb394df612f041c485a515849
d5ebb2238f2f0e2
EvaluationElement = 0301408e9c5be3ffcc1c16e5ae8f8aa68446223b0804b119
62e856af5a6d1c65ebbb5db7278c21db4e8cc06d89a35b6804fb1738a295b691638a
f77aa1327253f26d01
Proof = 0106a89a61eee9dd2417d2849a8e2167bc5f56e3aed5a3ff23e22511fa1b
37a29ed44d1bbfd6907d99cfbc558a56aec709282415a864a281e49dc53792a4a638
a0660034306d64be12a94dcea5a6d664cf76681911c8b9a84d49bf12d4893307ec14
436bd05f791f82446c0de4be6c582d373627b51886f76c4788256e3da7ec8fa18a86
ProofRandomScalar = 015e80ae32363b32cb76ad4b95a5a34e46bb803d955f0e07
3a04aa5d92b3fb739f56f9db001266677f62c095021db018cd8cbb55941d4073698c
e45c405d1348b7b1
Output = 808ae5b87662eaaf0b39151dd85991b94c96ef214cb14a68bf5c1439548
82d330da8953a80eea20788e552bc8bbbfff3100e89f9d6e341197b122c46a208733
b
A.5.3.2. Test Vector 2, Batch Size 1
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
Info = 7465737420696e666f
Blind = 00d1dccf7a51bafaf75d4a866d53d8cafe4d504650f53df8f16f68616333
88936ea23338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7a
d364
BlindedElement = 030112ea89cf9cf589496189eafc5f9eb13c9f9e170d6ecde7c
5b940541cb1a9c5cfeec908b67efe16b81ca00d0ce216e34b3d5f46a658d3fd8573d
671bdb6515ed508
EvaluationElement = 0200ebc49df1e6fa61f412e6c391e6f074400ecdd2f56c4a
8c03fe0f91d9b551f40d4b5258fd891952e8c9b28003bcfa365122e54a5714c8949d
5d202767b31b4bf1f6
Proof = 0082162c71a7765005cae202d4bd14b84dae63c29067e886b82506992bd9
94a1c3aac0c1c5309222fe1af8287b6443ed6df5c2e0b0991faddd3564c73c7597ae
cd9a003b1f1e3c65f28e58ab4e767cfb4adbcaf512441645f4c2aed8bf67d132d966
006d35fa71a34145414bf3572c1de1a46c266a344dd9e22e7fb1e90ffba1caf556d9
ProofRandomScalar = 015e80ae32363b32cb76ad4b95a5a34e46bb803d955f0e07
3a04aa5d92b3fb739f56f9db001266677f62c095021db018cd8cbb55941d4073698c
e45c405d1348b7b1
Output = 27032e24b1a52a82ab7f4646f3c5df0f070f499db98b9c5df33972bd5af
5762c3638afae7912a6c1acdb1ae2ab2fa670bd5486c645a0e55412e08d33a4a0d6e
3
A.5.3.3. Test Vector 3, Batch Size 2
Input = 00,5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
Info = 7465737420696e666f
Blind = 00d1dccf7a51bafaf75d4a866d53d8cafe4d504650f53df8f16f68616333
88936ea23338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7a
d364,015e80ae32363b32cb76ad4b95a5a34e46bb803d955f0e073a04aa5d92b3fb7
39f56f9db001266677f62c095021db018cd8cbb55941d4073698ce45c405d1348b7b
1
BlindedElement = 020095cff9d7ecf65bdfee4ea92d6e748d60b02de34ad98094f
82e25d33a8bf50138ccc2cc633556f1a97d7ea9438cbb394df612f041c485a515849
d5ebb2238f2f0e2,0201a328cf9f3fdeb86b6db242dd4cbb436b3a488b70b72d2fbb
d1e5f50d7b0878b157d6f278c6a95c488f3ad52d6898a421658a82fe7ceb000b01ae
dea7967522d525
EvaluationElement = 0301408e9c5be3ffcc1c16e5ae8f8aa68446223b0804b119
62e856af5a6d1c65ebbb5db7278c21db4e8cc06d89a35b6804fb1738a295b691638a
f77aa1327253f26d01,020062ab51ac3aa829e0f5b7ae50688bcf5f63a18a83a6e0d
a538666b8d50c7ea2b4ef31f4ac669302318dbebe46660acdda695da30c22cee7ca2
1f6984a720504502e
Proof = 00731738844f739bca0cca9d1c8bea204bed4fd00285785738b985763741
de5cdfa275152d52b6a2fdf7792ef3779f39ba34581e56d62f78ecad5b7f8083f384
961501cd4b43713253c022692669cf076b1d382ecd8293c1de69ea569737f37a2477
2ab73517983c1e3db5818754ba1f008076267b8058b6481949ae346cdc17a8455fe2
ProofRandomScalar = 01ec21c7bb69b0734cb48dfd68433dd93b0fa097e722ed24
27de86966910acba9f5c350e8040f828bf6ceca27405420cdf3d63cb3aef005f40ba
51943c8026877963
Output = 808ae5b87662eaaf0b39151dd85991b94c96ef214cb14a68bf5c1439548
82d330da8953a80eea20788e552bc8bbbfff3100e89f9d6e341197b122c46a208733
b,27032e24b1a52a82ab7f4646f3c5df0f070f499db98b9c5df33972bd5af5762c36
38afae7912a6c1acdb1ae2ab2fa670bd5486c645a0e55412e08d33a4a0d6e3
Acknowledgements
This document resulted from the work of the Privacy Pass team
[PrivacyPass]. The authors would also like to acknowledge helpful
conversations with Hugo Krawczyk. Eli-Shaoul Khedouri provided
additional review and comments on key consistency. Daniel Bourdrez,
Tatiana Bradley, Sofia Celi, Frank Denis, Julia Hesse, Russ Housley,
Kevin Lewi, Christopher Patton, and Bas Westerbaan also provided
helpful input and contributions to the document.
Authors' Addresses
Alex Davidson
Brave Software
Email: alex.davidson92@gmail.com
Armando Faz-Hernandez
Cloudflare, Inc.
101 Townsend St
San Francisco, CA
United States of America
Email: armfazh@cloudflare.com
Nick Sullivan
Cloudflare, Inc.
101 Townsend St
San Francisco, CA
United States of America
Email: nicholas.sullivan+ietf@gmail.com
Christopher A. Wood
Cloudflare, Inc.
101 Townsend St
San Francisco, CA
United States of America
Email: caw@heapingbits.net
|