1use core::fmt::{self, Debug, Formatter};
24
25use aluvm::{CoreExt, NoExt, Register, Supercore};
26use amplify::num::{u256, u4};
27
28use crate::fe256;
29
30pub const FIELD_ORDER_25519: u256 =
31 u256::from_inner([0xFFFF_FFFF_FFFF_FFEC, 0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF, 0x8FFF_FFFF_FFFF_FFFF]);
32pub const FIELD_ORDER_STARK: u256 = u256::from_inner([1, 0, 17, 0x0800_0000_0000_0000]);
33pub const FIELD_ORDER_SECP: u256 =
34 u256::from_inner([0xFFFF_FFFE_FFFF_FC2E, 0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF]);
35
36impl Default for GfaConfig {
37 fn default() -> Self {
38 Self {
39 field_order: FIELD_ORDER_25519,
40 }
41 }
42}
43
44#[derive(Copy, Clone, Eq, PartialEq)]
45pub struct GfaCore {
46 pub(super) fq: u256,
47 pub(super) e: [Option<fe256>; 16],
48}
49
50#[derive(Copy, Clone, Eq, PartialEq)]
51pub struct GfaConfig {
52 pub field_order: u256,
53}
54
55impl CoreExt for GfaCore {
56 type Reg = RegE;
57 type Config = GfaConfig; #[inline]
60 fn with(config: Self::Config) -> Self {
61 GfaCore {
62 fq: config.field_order,
63 e: [None; 16],
64 }
65 }
66
67 #[inline]
68 fn get(&self, reg: Self::Reg) -> Option<fe256> { self.e[reg as usize] }
69
70 #[inline]
71 fn clr(&mut self, reg: Self::Reg) { self.e[reg as usize] = None; }
72
73 #[inline]
74 fn put(&mut self, reg: Self::Reg, val: Option<fe256>) {
75 let Some(val) = val else {
76 self.e[reg as usize] = None;
77 return;
78 };
79 assert!(val.to_u256() < self.fq, "value {val} exceeds field order {}", self.fq);
80 self.e[reg as usize] = Some(val);
81 }
82
83 #[inline]
84 fn reset(&mut self) { self.e = [None; 16]; }
85}
86
87impl Supercore<NoExt> for GfaCore {
88 fn subcore(&self) -> NoExt { NoExt }
89
90 fn merge_subcore(&mut self, _subcore: NoExt) {}
91}
92
93impl Debug for GfaCore {
94 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
95 let (sect, reg, val, reset) =
96 if f.alternate() { ("\x1B[0;4;1m", "\x1B[0;1m", "\x1B[0;32m", "\x1B[0m") } else { ("", "", "", "") };
97
98 writeln!(f)?;
99 writeln!(f, "{reg}FQ{reset} {val}{:X}{reset}#h", self.fq)?;
100 writeln!(f, "{sect}E-regs:{reset}")?;
101 for (no, item) in self.e.iter().enumerate() {
102 write!(f, "{reg}{}{reset} ", RegE::from(u4::with(no as u8)))?;
103 if let Some(e) = item {
104 writeln!(f, "{val}{e}{reset}#h")?;
105 } else {
106 writeln!(f, "~")?;
107 }
108 }
109 writeln!(f)
110 }
111}
112
113#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Display)]
114#[display(uppercase)]
115#[repr(u8)]
116pub enum RegE {
117 E1 = 0b_0000,
118 E2 = 0b_0001,
119 E3 = 0b_0010,
120 E4 = 0b_0011,
121 E5 = 0b_0100,
122 E6 = 0b_0101,
123 E7 = 0b_0110,
124 E8 = 0b_0111,
125 EA = 0b_1000,
126 EB = 0b_1001,
127 EC = 0b_1010,
128 ED = 0b_1011,
129 EE = 0b_1100,
130 EF = 0b_1101,
131 EG = 0b_1110,
132 EH = 0b_1111,
133}
134
135impl Register for RegE {
136 type Value = fe256;
137
138 #[inline]
139 fn bytes(self) -> u16 { 16 }
140}
141
142impl From<u4> for RegE {
143 fn from(val: u4) -> Self {
144 match val {
145 x if x == RegE::E1.to_u4() => RegE::E1,
146 x if x == RegE::E2.to_u4() => RegE::E2,
147 x if x == RegE::E3.to_u4() => RegE::E3,
148 x if x == RegE::E4.to_u4() => RegE::E4,
149 x if x == RegE::E5.to_u4() => RegE::E5,
150 x if x == RegE::E6.to_u4() => RegE::E6,
151 x if x == RegE::E7.to_u4() => RegE::E7,
152 x if x == RegE::E8.to_u4() => RegE::E8,
153 x if x == RegE::EA.to_u4() => RegE::EA,
154 x if x == RegE::EB.to_u4() => RegE::EB,
155 x if x == RegE::EC.to_u4() => RegE::EC,
156 x if x == RegE::ED.to_u4() => RegE::ED,
157 x if x == RegE::EE.to_u4() => RegE::EE,
158 x if x == RegE::EF.to_u4() => RegE::EF,
159 x if x == RegE::EG.to_u4() => RegE::EG,
160 x if x == RegE::EH.to_u4() => RegE::EH,
161 _ => unreachable!(),
162 }
163 }
164}
165
166impl RegE {
167 pub const ALL: [Self; 16] = [
168 RegE::E1,
169 RegE::E2,
170 RegE::E3,
171 RegE::E4,
172 RegE::E5,
173 RegE::E6,
174 RegE::E7,
175 RegE::E8,
176 RegE::EA,
177 RegE::EB,
178 RegE::EC,
179 RegE::ED,
180 RegE::EE,
181 RegE::EF,
182 RegE::EG,
183 RegE::EH,
184 ];
185
186 #[inline]
187 pub const fn to_u4(self) -> u4 { u4::with(self as u8) }
188}