Skip to main content

uor_addr/composition/g2/
pipeline.rs

1//! CS-G2 composition entry points, one per σ-axis (wiki ADR-061 §(2)).
2
3#![cfg(feature = "alloc")]
4
5use crate::composition::canonicalize::{canonicalize_g2, check_axis, decode_operand};
6use crate::composition::g2::model::{
7    CompositionModelG2Blake3, CompositionModelG2Keccak256, CompositionModelG2Sha256,
8    CompositionModelG2Sha3_256, CompositionModelG2Sha512,
9};
10use crate::composition::g2::value::G2Carrier;
11use crate::composition::CompositionFailure;
12use crate::label::KappaLabel;
13use crate::outcome::AddressOutcome;
14use prism::pipeline::PrismModel;
15
16/// CS-G2 under σ-axis `Sha256Hasher`.
17///
18/// # Errors
19///
20/// - [`CompositionFailure::OperandSigmaAxisMismatch`] — an operand's σ-axis
21///   prefix is not `"sha256"`.
22/// - [`CompositionFailure::MalformedOperand`] — an operand is not a
23///   well-formed κ-label.
24/// - [`CompositionFailure::PipelineFailure`] — defensive.
25pub fn compose_g2_product(
26    left: &KappaLabel<71>,
27    right: &KappaLabel<71>,
28) -> Result<AddressOutcome<71>, CompositionFailure> {
29    let (la, _) = decode_operand(left)?;
30    check_axis(la, "sha256")?;
31    let (ra, _) = decode_operand(right)?;
32    check_axis(ra, "sha256")?;
33    let canon = canonicalize_g2(left, right);
34    let grounded = CompositionModelG2Sha256::forward(G2Carrier::new(&canon))
35        .map_err(|_| CompositionFailure::PipelineFailure)?;
36    AddressOutcome::<71>::from_grounded(&grounded).map_err(|_| CompositionFailure::PipelineFailure)
37}
38/// CS-G2 under σ-axis `Blake3Hasher`.
39///
40/// # Errors
41///
42/// - [`CompositionFailure::OperandSigmaAxisMismatch`] — an operand's σ-axis
43///   prefix is not `"blake3"`.
44/// - [`CompositionFailure::MalformedOperand`] — an operand is not a
45///   well-formed κ-label.
46/// - [`CompositionFailure::PipelineFailure`] — defensive.
47pub fn compose_g2_product_blake3(
48    left: &KappaLabel<71>,
49    right: &KappaLabel<71>,
50) -> Result<AddressOutcome<71>, CompositionFailure> {
51    let (la, _) = decode_operand(left)?;
52    check_axis(la, "blake3")?;
53    let (ra, _) = decode_operand(right)?;
54    check_axis(ra, "blake3")?;
55    let canon = canonicalize_g2(left, right);
56    let grounded = CompositionModelG2Blake3::forward(G2Carrier::new(&canon))
57        .map_err(|_| CompositionFailure::PipelineFailure)?;
58    AddressOutcome::<71>::from_grounded(&grounded).map_err(|_| CompositionFailure::PipelineFailure)
59}
60/// CS-G2 under σ-axis `Sha3_256Hasher`.
61///
62/// # Errors
63///
64/// - [`CompositionFailure::OperandSigmaAxisMismatch`] — an operand's σ-axis
65///   prefix is not `"sha3-256"`.
66/// - [`CompositionFailure::MalformedOperand`] — an operand is not a
67///   well-formed κ-label.
68/// - [`CompositionFailure::PipelineFailure`] — defensive.
69pub fn compose_g2_product_sha3_256(
70    left: &KappaLabel<73>,
71    right: &KappaLabel<73>,
72) -> Result<AddressOutcome<73>, CompositionFailure> {
73    let (la, _) = decode_operand(left)?;
74    check_axis(la, "sha3-256")?;
75    let (ra, _) = decode_operand(right)?;
76    check_axis(ra, "sha3-256")?;
77    let canon = canonicalize_g2(left, right);
78    let grounded = CompositionModelG2Sha3_256::forward(G2Carrier::new(&canon))
79        .map_err(|_| CompositionFailure::PipelineFailure)?;
80    AddressOutcome::<73>::from_grounded(&grounded).map_err(|_| CompositionFailure::PipelineFailure)
81}
82/// CS-G2 under σ-axis `Keccak256Hasher`.
83///
84/// # Errors
85///
86/// - [`CompositionFailure::OperandSigmaAxisMismatch`] — an operand's σ-axis
87///   prefix is not `"keccak256"`.
88/// - [`CompositionFailure::MalformedOperand`] — an operand is not a
89///   well-formed κ-label.
90/// - [`CompositionFailure::PipelineFailure`] — defensive.
91pub fn compose_g2_product_keccak256(
92    left: &KappaLabel<74>,
93    right: &KappaLabel<74>,
94) -> Result<AddressOutcome<74>, CompositionFailure> {
95    let (la, _) = decode_operand(left)?;
96    check_axis(la, "keccak256")?;
97    let (ra, _) = decode_operand(right)?;
98    check_axis(ra, "keccak256")?;
99    let canon = canonicalize_g2(left, right);
100    let grounded = CompositionModelG2Keccak256::forward(G2Carrier::new(&canon))
101        .map_err(|_| CompositionFailure::PipelineFailure)?;
102    AddressOutcome::<74>::from_grounded(&grounded).map_err(|_| CompositionFailure::PipelineFailure)
103}
104/// CS-G2 under σ-axis `Sha512Hasher`.
105///
106/// # Errors
107///
108/// - [`CompositionFailure::OperandSigmaAxisMismatch`] — an operand's σ-axis
109///   prefix is not `"sha512"`.
110/// - [`CompositionFailure::MalformedOperand`] — an operand is not a
111///   well-formed κ-label.
112/// - [`CompositionFailure::PipelineFailure`] — defensive.
113pub fn compose_g2_product_sha512(
114    left: &KappaLabel<135>,
115    right: &KappaLabel<135>,
116) -> Result<AddressOutcome<135, 64>, CompositionFailure> {
117    let (la, _) = decode_operand(left)?;
118    check_axis(la, "sha512")?;
119    let (ra, _) = decode_operand(right)?;
120    check_axis(ra, "sha512")?;
121    let canon = canonicalize_g2(left, right);
122    let grounded = CompositionModelG2Sha512::forward(G2Carrier::new(&canon))
123        .map_err(|_| CompositionFailure::PipelineFailure)?;
124    AddressOutcome::<135, 64>::from_grounded(&grounded)
125        .map_err(|_| CompositionFailure::PipelineFailure)
126}