oprf/
p256_sha256.rs

1//! ## 4.3.  OPRF(P-256, SHA-256)
2//!
3//! This ciphersuite uses P-256 [NISTCurves] for the Group and SHA-256
4//! for the Hash function.  The value of the ciphersuite identifier is
5//! "P256-SHA256".
6//!
7
8use crate::Error;
9
10use p256::{P256Point, P256Scalar};
11
12#[allow(non_upper_case_globals, unused)]
13const identifier: &[u8] = b"P256-SHA256";
14
15pub type P256SerializedPoint = [u8; 33];
16
17/// SerializeElement(A): Implemented using the compressed Elliptic-
18///     Curve-Point-to-Octet-String method according to [SEC1]; Ne =
19///     33.
20pub fn serialize_element(p: &P256Point) -> P256SerializedPoint {
21    p256::serialize_point(p)
22}
23
24#[allow(unused)]
25pub fn deserialize_element(pm: P256SerializedPoint) -> Result<P256Point, Error> {
26    p256::deserialize_point(pm).map_err(|e| e.into())
27}
28
29pub fn identity() -> P256Point {
30    P256Point::AtInfinity
31}
32
33pub fn scalar_inverse(s: P256Scalar) -> P256Scalar {
34    use hacspec_lib::hacspec_helper::NatMod;
35    s.inv()
36}
37
38/// HashToScalar(): Use hash_to_field from [I-D.irtf-cfrg-hash-to-curve]
39/// using L = 48, expand_message_xmd with SHA-256, DST = "HashToScalar-"
40/// || contextString, and prime modulus equal to Group.Order().
41pub fn hash_to_scalar(bytes: &[u8], context_string: &[u8]) -> Result<P256Scalar, Error> {
42    let mut dst: Vec<u8> = "HashToScalar-".into(); // DST = "HashToScalar-" || contextString
43    dst.extend_from_slice(context_string);
44    hash_to_scalar_dst(bytes, &dst, context_string)
45}
46
47pub fn hash_to_scalar_dst(
48    bytes: &[u8],
49    dst: &[u8],
50    context_string: &[u8],
51) -> Result<P256Scalar, Error> {
52    let mut dst = dst.to_vec();
53    dst.extend_from_slice(context_string);
54
55    hash_to_curve::p256_hash::hash_to_scalar(bytes, &dst, 1)
56        .map(|v| v[0])
57        .map_err(|e| e.into())
58}
59
60/// HashToGroup(): Use hash_to_curve with suite P256_XMD:SHA-256_SSWU_RO_
61/// [I-D.irtf-cfrg-hash-to-curve] and DST = "HashToGroup-" ||
62/// contextString.
63pub fn hash_to_group(bytes: &[u8], context_string: &[u8]) -> Result<P256Point, Error> {
64    let mut dst: Vec<u8> = b"HashToGroup-".to_vec();
65    dst.extend_from_slice(context_string);
66
67    hash_to_curve::p256_hash::hash_to_curve(bytes, &dst).map_err(|e| e.into())
68}
69
70#[test]
71fn serialize_deserialize() {
72    use hacspec_lib::Randomness;
73    let p: P256Point = p256::p256_point_mul_base(
74        p256::random_scalar(&mut Randomness::new(vec![0xab; 32]), b"OPRF-Test").unwrap(),
75    )
76    .unwrap();
77
78    debug_assert_eq!(p, deserialize_element(serialize_element(&p)).unwrap());
79}