use digest::Digest;
use generic_ec::{NonZero, Point, Scalar};
use crate::{ciphersuite::NormalizedPoint, Ciphersuite};
pub fn tweak<C: Ciphersuite>(
public_key: NormalizedPoint<C, NonZero<Point<C::Curve>>>,
merkle_root: Option<[u8; 32]>,
) -> Option<Scalar<C::Curve>> {
let tag = sha2::Sha256::digest("TapTweak");
let hash = sha2::Sha256::new()
.chain_update(tag)
.chain_update(tag)
.chain_update(public_key.to_bytes())
.chain_update(if let Some(root) = &merkle_root {
root.as_slice()
} else {
&[]
})
.finalize();
Scalar::from_be_bytes(hash).ok()
}
pub fn tweak_public_key<C: Ciphersuite>(
public_key: NormalizedPoint<C, NonZero<Point<C::Curve>>>,
merkle_root: Option<[u8; 32]>,
) -> Option<NonZero<Point<C::Curve>>> {
let t = tweak::<C>(public_key, merkle_root)?;
NonZero::from_point(*public_key + Point::generator() * t)
}