1use core::str::FromStr;
24
25use amplify::confinement::TinyBlob;
26use amplify::hex::FromHex;
27use amplify::num::u256;
28use amplify::{hex, Bytes32, Wrapper};
29use strict_encoding::{
30 DecodeError, ReadTuple, StrictDecode, StrictProduct, StrictTuple, StrictType, TypeName, TypedRead,
31};
32
33use crate::LIB_NAME_FINITE_FIELD;
34
35#[allow(non_camel_case_types)]
36#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Display, From)]
37#[display("{0:X}.fe")]
38#[derive(StrictDumb, StrictEncode)]
39#[strict_type(lib = LIB_NAME_FINITE_FIELD)]
40pub struct fe256(
41 #[from(u8)]
42 #[from(u16)]
43 #[from(u32)]
44 #[from(u64)]
45 #[from(u128)]
46 u256,
47);
48
49impl fe256 {
50 pub const ZERO: Self = Self(u256::ZERO);
51
52 #[must_use]
53 fn test_value(val: u256) -> bool { val.into_inner()[3] & 0xF800_0000_0000_0000 == 0 }
54
55 pub const fn to_u256(&self) -> u256 { self.0 }
56}
57
58impl From<Bytes32> for fe256 {
59 fn from(bytes: Bytes32) -> Self { Self::from(bytes.into_inner()) }
60}
61
62impl From<[u8; 32]> for fe256 {
63 fn from(bytes: [u8; 32]) -> Self {
64 let val = u256::from_le_bytes(bytes);
65 Self::from(val)
66 }
67}
68
69impl From<u256> for fe256 {
70 fn from(val: u256) -> Self {
71 assert!(
73 Self::test_value(val),
74 "the provided value for 256-bit field element is in a risk zone above order of some commonly used 256-bit \
75 finite fields. The probability of this event for randomly-generated values (including the ones coming \
76 from hashes) is astronomically low, thus, an untrusted input is used in an unfiltered way. Adjust your \
77 code and do not use externally-provided values without checking them first."
78 );
79 Self(val)
80 }
81}
82
83impl StrictType for fe256 {
84 const STRICT_LIB_NAME: &'static str = LIB_NAME_FINITE_FIELD;
85 fn strict_name() -> Option<TypeName> { Some(tn!("Fe256")) }
86}
87impl StrictProduct for fe256 {}
88impl StrictTuple for fe256 {
89 const FIELD_COUNT: u8 = 1;
90}
91impl StrictDecode for fe256 {
92 fn strict_decode(reader: &mut impl TypedRead) -> Result<Self, DecodeError> {
93 reader.read_tuple(|r| {
94 let val = r.read_field::<u256>()?;
95 if !Self::test_value(val) {
96 return Err(DecodeError::DataIntegrityError(format!(
97 "the provided value {val:#X} for a field element is above the order of some of the finite fields \
98 and is disallowed"
99 )));
100 }
101 Ok(Self(val))
102 })
103 }
104}
105
106#[cfg(feature = "serde")]
107mod _serde {
108 use serde::de::{Error, Unexpected};
109 use serde::{Deserialize, Deserializer, Serialize, Serializer};
110
111 use super::*;
112
113 impl Serialize for fe256 {
114 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
115 where S: Serializer {
116 if serializer.is_human_readable() {
117 self.to_string().serialize(serializer)
118 } else {
119 self.0.serialize(serializer)
120 }
121 }
122 }
123
124 impl<'de> Deserialize<'de> for fe256 {
125 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
126 where D: Deserializer<'de> {
127 if deserializer.is_human_readable() {
128 let s = String::deserialize(deserializer)?;
129 Self::from_str(&s).map_err(|e| D::Error::invalid_value(Unexpected::Str(&s), &e.to_string().as_str()))
130 } else {
131 let val = u256::deserialize(deserializer)?;
132 if !Self::test_value(val) {
133 return Err(D::Error::invalid_value(
134 Unexpected::Bytes(&val.to_le_bytes()),
135 &"the value for a field element is above the order of some of the finite fields and is \
136 disallowed",
137 ));
138 }
139 Ok(Self(val))
140 }
141 }
142 }
143}
144
145#[derive(Clone, PartialEq, Eq, Debug, Display, Error, From)]
146#[display(doc_comments)]
147pub enum ParseFeError {
148 NoSuffix(String),
150
151 #[from]
152 #[display(inner)]
153 Value(hex::Error),
154
155 Overflow(u256),
157}
158
159impl FromStr for fe256 {
160 type Err = ParseFeError;
161
162 fn from_str(s: &str) -> Result<Self, Self::Err> {
163 let s = s
164 .strip_suffix(".fe")
165 .ok_or_else(|| ParseFeError::NoSuffix(s.to_owned()))?;
166 let bytes = if s.len() % 2 == 1 { TinyBlob::from_hex(&format!("0{s}"))? } else { TinyBlob::from_hex(s)? };
167 let mut buf = [0u8; 32];
168 if bytes.len() > 32 {
169 return Err(hex::Error::InvalidLength(32, bytes.len()).into());
170 }
171 buf[..bytes.len()].copy_from_slice(bytes.as_slice());
172 let val = u256::from_le_bytes(buf);
173 if !Self::test_value(val) {
174 return Err(ParseFeError::Overflow(val));
175 }
176 Ok(Self(val))
177 }
178}