griffin_core/uplc/machine/
runtime.rs

1use super::{
2    cost_model::{BuiltinCosts, ExBudget},
3    value::{from_pallas_bigint, to_pallas_bigint},
4    Error, Value,
5};
6use crate::pallas_primitives::conway::{Language, PlutusData};
7use crate::uplc::{
8    ast::{Constant, Data, Type},
9    builtins::DefaultFunction,
10    hamming,
11    machine::value::integer_log2,
12    plutus_data_to_bytes,
13};
14use alloc::{
15    rc::Rc,
16    string::{String, ToString},
17    vec::Vec,
18};
19use bitvec::{order::Msb0, vec::BitVec};
20use core::{mem::size_of, ops::Deref};
21use itertools::Itertools;
22use lazy_static::lazy_static;
23use num_bigint::BigInt;
24use num_integer::Integer;
25use num_traits::{FromPrimitive, Signed, Zero};
26
27lazy_static! {
28    static ref SCALAR_PERIOD: BigInt = BigInt::from_bytes_be(
29        num_bigint::Sign::Plus,
30        &[
31            0x73, 0xed, 0xa7, 0x53, 0x29, 0x9d, 0x7d, 0x48, 0x33, 0x39, 0xd8, 0x08, 0x09, 0xa1,
32            0xd8, 0x05, 0x53, 0xbd, 0xa4, 0x02, 0xff, 0xfe, 0x5b, 0xfe, 0xff, 0xff, 0xff, 0xff,
33            0x00, 0x00, 0x00, 0x01,
34        ],
35    );
36}
37
38const BLST_P1_COMPRESSED_SIZE: usize = 48;
39
40const BLST_P2_COMPRESSED_SIZE: usize = 96;
41
42pub const INTEGER_TO_BYTE_STRING_MAXIMUM_OUTPUT_LENGTH: i64 = 8192;
43
44pub enum BuiltinSemantics {
45    V1,
46    V2,
47}
48
49impl From<&Language> for BuiltinSemantics {
50    fn from(language: &Language) -> Self {
51        match language {
52            Language::PlutusV1 => BuiltinSemantics::V1,
53            Language::PlutusV2 => BuiltinSemantics::V1,
54            Language::PlutusV3 => BuiltinSemantics::V2,
55        }
56    }
57}
58
59#[derive(Clone, Debug, PartialEq)]
60pub struct BuiltinRuntime {
61    pub(super) args: Vec<Value>,
62    fun: DefaultFunction,
63    pub(super) forces: u32,
64}
65
66impl BuiltinRuntime {
67    pub fn new(fun: DefaultFunction) -> BuiltinRuntime {
68        Self {
69            args: vec![],
70            fun,
71            forces: 0,
72        }
73    }
74
75    pub fn is_arrow(&self) -> bool {
76        self.args.len() != self.fun.arity()
77    }
78
79    pub fn is_ready(&self) -> bool {
80        self.args.len() == self.fun.arity()
81    }
82
83    pub fn needs_force(&self) -> bool {
84        self.forces < self.fun.force_count()
85    }
86
87    pub fn consume_force(&mut self) {
88        self.forces += 1;
89    }
90
91    pub fn call(&self, language: &Language, logs: &mut Vec<String>) -> Result<Value, Error> {
92        self.fun.call(language.into(), &self.args, logs)
93    }
94
95    pub fn push(&mut self, arg: Value) -> Result<(), Error> {
96        self.args.push(arg);
97
98        Ok(())
99    }
100
101    pub fn to_ex_budget(&self, costs: &BuiltinCosts) -> Result<ExBudget, Error> {
102        costs.to_ex_budget(self.fun, &self.args)
103    }
104}
105
106impl From<DefaultFunction> for BuiltinRuntime {
107    fn from(fun: DefaultFunction) -> Self {
108        BuiltinRuntime::new(fun)
109    }
110}
111
112impl DefaultFunction {
113    pub fn arg_is_unit(&self) -> bool {
114        match self {
115            DefaultFunction::MkNilData | DefaultFunction::MkNilPairData => true,
116            DefaultFunction::AddInteger
117            | DefaultFunction::SubtractInteger
118            | DefaultFunction::MultiplyInteger
119            | DefaultFunction::DivideInteger
120            | DefaultFunction::QuotientInteger
121            | DefaultFunction::RemainderInteger
122            | DefaultFunction::ModInteger
123            | DefaultFunction::EqualsInteger
124            | DefaultFunction::LessThanInteger
125            | DefaultFunction::LessThanEqualsInteger
126            | DefaultFunction::AppendByteString
127            | DefaultFunction::ConsByteString
128            | DefaultFunction::SliceByteString
129            | DefaultFunction::LengthOfByteString
130            | DefaultFunction::IndexByteString
131            | DefaultFunction::EqualsByteString
132            | DefaultFunction::LessThanByteString
133            | DefaultFunction::LessThanEqualsByteString
134            | DefaultFunction::Sha2_256
135            | DefaultFunction::Sha3_256
136            | DefaultFunction::Blake2b_224
137            | DefaultFunction::Blake2b_256
138            | DefaultFunction::Keccak_256
139            | DefaultFunction::VerifyEd25519Signature
140            | DefaultFunction::VerifyEcdsaSecp256k1Signature
141            | DefaultFunction::VerifySchnorrSecp256k1Signature
142            | DefaultFunction::AppendString
143            | DefaultFunction::EqualsString
144            | DefaultFunction::EncodeUtf8
145            | DefaultFunction::DecodeUtf8
146            | DefaultFunction::IfThenElse
147            | DefaultFunction::ChooseUnit
148            | DefaultFunction::Trace
149            | DefaultFunction::FstPair
150            | DefaultFunction::SndPair
151            | DefaultFunction::ChooseList
152            | DefaultFunction::MkCons
153            | DefaultFunction::HeadList
154            | DefaultFunction::TailList
155            | DefaultFunction::NullList
156            | DefaultFunction::ChooseData
157            | DefaultFunction::ConstrData
158            | DefaultFunction::MapData
159            | DefaultFunction::ListData
160            | DefaultFunction::IData
161            | DefaultFunction::BData
162            | DefaultFunction::UnConstrData
163            | DefaultFunction::UnMapData
164            | DefaultFunction::UnListData
165            | DefaultFunction::UnIData
166            | DefaultFunction::UnBData
167            | DefaultFunction::EqualsData
168            | DefaultFunction::SerialiseData
169            | DefaultFunction::MkPairData
170            | DefaultFunction::Bls12_381_G1_Add
171            | DefaultFunction::Bls12_381_G1_Neg
172            | DefaultFunction::Bls12_381_G1_ScalarMul
173            | DefaultFunction::Bls12_381_G1_Equal
174            | DefaultFunction::Bls12_381_G1_Compress
175            | DefaultFunction::Bls12_381_G1_Uncompress
176            | DefaultFunction::Bls12_381_G1_HashToGroup
177            | DefaultFunction::Bls12_381_G2_Add
178            | DefaultFunction::Bls12_381_G2_Neg
179            | DefaultFunction::Bls12_381_G2_ScalarMul
180            | DefaultFunction::Bls12_381_G2_Equal
181            | DefaultFunction::Bls12_381_G2_Compress
182            | DefaultFunction::Bls12_381_G2_Uncompress
183            | DefaultFunction::Bls12_381_G2_HashToGroup
184            | DefaultFunction::Bls12_381_MillerLoop
185            | DefaultFunction::Bls12_381_MulMlResult
186            | DefaultFunction::Bls12_381_FinalVerify
187            | DefaultFunction::IntegerToByteString
188            | DefaultFunction::ByteStringToInteger
189            | DefaultFunction::AndByteString
190            | DefaultFunction::OrByteString
191            | DefaultFunction::XorByteString
192            | DefaultFunction::ComplementByteString
193            | DefaultFunction::ReadBit
194            | DefaultFunction::WriteBits
195            | DefaultFunction::ReplicateByte
196            | DefaultFunction::ShiftByteString
197            | DefaultFunction::RotateByteString
198            | DefaultFunction::CountSetBits
199            | DefaultFunction::FindFirstSetBit
200            | DefaultFunction::Ripemd_160 => false,
201            // | DefaultFunction::ExpModInteger
202            // | DefaultFunction::CaseList
203            // | DefaultFunction::CaseData
204        }
205    }
206
207    pub fn arity(&self) -> usize {
208        match self {
209            DefaultFunction::AddInteger => 2,
210            DefaultFunction::SubtractInteger => 2,
211            DefaultFunction::MultiplyInteger => 2,
212            DefaultFunction::DivideInteger => 2,
213            DefaultFunction::QuotientInteger => 2,
214            DefaultFunction::RemainderInteger => 2,
215            DefaultFunction::ModInteger => 2,
216            DefaultFunction::EqualsInteger => 2,
217            DefaultFunction::LessThanInteger => 2,
218            DefaultFunction::LessThanEqualsInteger => 2,
219            DefaultFunction::AppendByteString => 2,
220            DefaultFunction::ConsByteString => 2,
221            DefaultFunction::SliceByteString => 3,
222            DefaultFunction::LengthOfByteString => 1,
223            DefaultFunction::IndexByteString => 2,
224            DefaultFunction::EqualsByteString => 2,
225            DefaultFunction::LessThanByteString => 2,
226            DefaultFunction::LessThanEqualsByteString => 2,
227            DefaultFunction::Sha2_256 => 1,
228            DefaultFunction::Sha3_256 => 1,
229            DefaultFunction::Blake2b_224 => 1,
230            DefaultFunction::Blake2b_256 => 1,
231            DefaultFunction::Keccak_256 => 1,
232            DefaultFunction::VerifyEd25519Signature => 3,
233            DefaultFunction::VerifyEcdsaSecp256k1Signature => 3,
234            DefaultFunction::VerifySchnorrSecp256k1Signature => 3,
235            DefaultFunction::AppendString => 2,
236            DefaultFunction::EqualsString => 2,
237            DefaultFunction::EncodeUtf8 => 1,
238            DefaultFunction::DecodeUtf8 => 1,
239            DefaultFunction::IfThenElse => 3,
240            DefaultFunction::ChooseUnit => 2,
241            DefaultFunction::Trace => 2,
242            DefaultFunction::FstPair => 1,
243            DefaultFunction::SndPair => 1,
244            DefaultFunction::ChooseList => 3,
245            DefaultFunction::MkCons => 2,
246            DefaultFunction::HeadList => 1,
247            DefaultFunction::TailList => 1,
248            DefaultFunction::NullList => 1,
249            DefaultFunction::ChooseData => 6,
250            DefaultFunction::ConstrData => 2,
251            DefaultFunction::MapData => 1,
252            DefaultFunction::ListData => 1,
253            DefaultFunction::IData => 1,
254            DefaultFunction::BData => 1,
255            DefaultFunction::UnConstrData => 1,
256            DefaultFunction::UnMapData => 1,
257            DefaultFunction::UnListData => 1,
258            DefaultFunction::UnIData => 1,
259            DefaultFunction::UnBData => 1,
260            DefaultFunction::EqualsData => 2,
261            DefaultFunction::SerialiseData => 1,
262            DefaultFunction::MkPairData => 2,
263            DefaultFunction::MkNilData => 1,
264            DefaultFunction::MkNilPairData => 1,
265            DefaultFunction::Bls12_381_G1_Add => 2,
266            DefaultFunction::Bls12_381_G1_Neg => 1,
267            DefaultFunction::Bls12_381_G1_ScalarMul => 2,
268            DefaultFunction::Bls12_381_G1_Equal => 2,
269            DefaultFunction::Bls12_381_G1_Compress => 1,
270            DefaultFunction::Bls12_381_G1_Uncompress => 1,
271            DefaultFunction::Bls12_381_G1_HashToGroup => 2,
272            DefaultFunction::Bls12_381_G2_Add => 2,
273            DefaultFunction::Bls12_381_G2_Neg => 1,
274            DefaultFunction::Bls12_381_G2_ScalarMul => 2,
275            DefaultFunction::Bls12_381_G2_Equal => 2,
276            DefaultFunction::Bls12_381_G2_Compress => 1,
277            DefaultFunction::Bls12_381_G2_Uncompress => 1,
278            DefaultFunction::Bls12_381_G2_HashToGroup => 2,
279            DefaultFunction::Bls12_381_MillerLoop => 2,
280            DefaultFunction::Bls12_381_MulMlResult => 2,
281            DefaultFunction::Bls12_381_FinalVerify => 2,
282            DefaultFunction::IntegerToByteString => 3,
283            DefaultFunction::ByteStringToInteger => 2,
284            DefaultFunction::AndByteString => 3,
285            DefaultFunction::OrByteString => 3,
286            DefaultFunction::XorByteString => 3,
287            DefaultFunction::ComplementByteString => 1,
288            DefaultFunction::ReadBit => 2,
289            DefaultFunction::WriteBits => 3,
290            DefaultFunction::ReplicateByte => 2,
291            DefaultFunction::ShiftByteString => 2,
292            DefaultFunction::RotateByteString => 2,
293            DefaultFunction::CountSetBits => 1,
294            DefaultFunction::FindFirstSetBit => 1,
295            DefaultFunction::Ripemd_160 => 1,
296            // DefaultFunction::ExpModInteger => 3,
297        }
298    }
299
300    pub fn force_count(&self) -> u32 {
301        match self {
302            DefaultFunction::AddInteger => 0,
303            DefaultFunction::SubtractInteger => 0,
304            DefaultFunction::MultiplyInteger => 0,
305            DefaultFunction::DivideInteger => 0,
306            DefaultFunction::QuotientInteger => 0,
307            DefaultFunction::RemainderInteger => 0,
308            DefaultFunction::ModInteger => 0,
309            DefaultFunction::EqualsInteger => 0,
310            DefaultFunction::LessThanInteger => 0,
311            DefaultFunction::LessThanEqualsInteger => 0,
312            DefaultFunction::AppendByteString => 0,
313            DefaultFunction::ConsByteString => 0,
314            DefaultFunction::SliceByteString => 0,
315            DefaultFunction::LengthOfByteString => 0,
316            DefaultFunction::IndexByteString => 0,
317            DefaultFunction::EqualsByteString => 0,
318            DefaultFunction::LessThanByteString => 0,
319            DefaultFunction::LessThanEqualsByteString => 0,
320            DefaultFunction::Sha2_256 => 0,
321            DefaultFunction::Sha3_256 => 0,
322            DefaultFunction::Blake2b_224 => 0,
323            DefaultFunction::Blake2b_256 => 0,
324            DefaultFunction::Keccak_256 => 0,
325            DefaultFunction::VerifyEd25519Signature => 0,
326            DefaultFunction::VerifyEcdsaSecp256k1Signature => 0,
327            DefaultFunction::VerifySchnorrSecp256k1Signature => 0,
328            DefaultFunction::AppendString => 0,
329            DefaultFunction::EqualsString => 0,
330            DefaultFunction::EncodeUtf8 => 0,
331            DefaultFunction::DecodeUtf8 => 0,
332            DefaultFunction::IfThenElse => 1,
333            DefaultFunction::ChooseUnit => 1,
334            DefaultFunction::Trace => 1,
335            DefaultFunction::FstPair => 2,
336            DefaultFunction::SndPair => 2,
337            DefaultFunction::ChooseList => 2,
338            DefaultFunction::MkCons => 1,
339            DefaultFunction::HeadList => 1,
340            DefaultFunction::TailList => 1,
341            DefaultFunction::NullList => 1,
342            DefaultFunction::ChooseData => 1,
343            DefaultFunction::ConstrData => 0,
344            DefaultFunction::MapData => 0,
345            DefaultFunction::ListData => 0,
346            DefaultFunction::IData => 0,
347            DefaultFunction::BData => 0,
348            DefaultFunction::UnConstrData => 0,
349            DefaultFunction::UnMapData => 0,
350            DefaultFunction::UnListData => 0,
351            DefaultFunction::UnIData => 0,
352            DefaultFunction::UnBData => 0,
353            DefaultFunction::EqualsData => 0,
354            DefaultFunction::SerialiseData => 0,
355            DefaultFunction::MkPairData => 0,
356            DefaultFunction::MkNilData => 0,
357            DefaultFunction::MkNilPairData => 0,
358            DefaultFunction::Bls12_381_G1_Add => 0,
359            DefaultFunction::Bls12_381_G1_Neg => 0,
360            DefaultFunction::Bls12_381_G1_ScalarMul => 0,
361            DefaultFunction::Bls12_381_G1_Equal => 0,
362            DefaultFunction::Bls12_381_G1_Compress => 0,
363            DefaultFunction::Bls12_381_G1_Uncompress => 0,
364            DefaultFunction::Bls12_381_G1_HashToGroup => 0,
365            DefaultFunction::Bls12_381_G2_Add => 0,
366            DefaultFunction::Bls12_381_G2_Neg => 0,
367            DefaultFunction::Bls12_381_G2_ScalarMul => 0,
368            DefaultFunction::Bls12_381_G2_Equal => 0,
369            DefaultFunction::Bls12_381_G2_Compress => 0,
370            DefaultFunction::Bls12_381_G2_Uncompress => 0,
371            DefaultFunction::Bls12_381_G2_HashToGroup => 0,
372            DefaultFunction::Bls12_381_MillerLoop => 0,
373            DefaultFunction::Bls12_381_MulMlResult => 0,
374            DefaultFunction::Bls12_381_FinalVerify => 0,
375            DefaultFunction::IntegerToByteString => 0,
376            DefaultFunction::ByteStringToInteger => 0,
377            DefaultFunction::AndByteString => 0,
378            DefaultFunction::OrByteString => 0,
379            DefaultFunction::XorByteString => 0,
380            DefaultFunction::ComplementByteString => 0,
381            DefaultFunction::ReadBit => 0,
382            DefaultFunction::WriteBits => 0,
383            DefaultFunction::ReplicateByte => 0,
384            DefaultFunction::ShiftByteString => 0,
385            DefaultFunction::RotateByteString => 0,
386            DefaultFunction::CountSetBits => 0,
387            DefaultFunction::FindFirstSetBit => 0,
388            DefaultFunction::Ripemd_160 => 0,
389            // DefaultFunction::ExpModInteger => 0,
390        }
391    }
392
393    pub fn call(
394        &self,
395        semantics: BuiltinSemantics,
396        args: &[Value],
397        logs: &mut Vec<String>,
398    ) -> Result<Value, Error> {
399        match self {
400            DefaultFunction::AddInteger => {
401                let arg1 = args[0].unwrap_integer()?;
402                let arg2 = args[1].unwrap_integer()?;
403
404                let result = arg1 + arg2;
405
406                let value = Value::integer(result);
407
408                Ok(value)
409            }
410            DefaultFunction::SubtractInteger => {
411                let arg1 = args[0].unwrap_integer()?;
412                let arg2 = args[1].unwrap_integer()?;
413
414                let result = arg1 - arg2;
415
416                let value = Value::integer(result);
417
418                Ok(value)
419            }
420            DefaultFunction::MultiplyInteger => {
421                let arg1 = args[0].unwrap_integer()?;
422                let arg2 = args[1].unwrap_integer()?;
423
424                let result = arg1 * arg2;
425
426                let value = Value::integer(result);
427
428                Ok(value)
429            }
430            DefaultFunction::DivideInteger => {
431                let arg1 = args[0].unwrap_integer()?;
432                let arg2 = args[1].unwrap_integer()?;
433
434                if *arg2 != 0.into() {
435                    let (result, _) = arg1.div_mod_floor(arg2);
436
437                    let value = Value::integer(result);
438
439                    Ok(value)
440                } else {
441                    Err(Error::DivideByZero(arg1.clone(), arg2.clone()))
442                }
443            }
444            DefaultFunction::QuotientInteger => {
445                let arg1 = args[0].unwrap_integer()?;
446                let arg2 = args[1].unwrap_integer()?;
447
448                if *arg2 != 0.into() {
449                    let (result, _) = arg1.div_rem(arg2);
450
451                    let value = Value::integer(result);
452
453                    Ok(value)
454                } else {
455                    Err(Error::DivideByZero(arg1.clone(), arg2.clone()))
456                }
457            }
458            DefaultFunction::RemainderInteger => {
459                let arg1 = args[0].unwrap_integer()?;
460                let arg2 = args[1].unwrap_integer()?;
461
462                if *arg2 != 0.into() {
463                    let (_, result) = arg1.div_rem(arg2);
464
465                    let value = Value::integer(result);
466
467                    Ok(value)
468                } else {
469                    Err(Error::DivideByZero(arg1.clone(), arg2.clone()))
470                }
471            }
472            DefaultFunction::ModInteger => {
473                let arg1 = args[0].unwrap_integer()?;
474                let arg2 = args[1].unwrap_integer()?;
475
476                if *arg2 != 0.into() {
477                    let (_, result) = arg1.div_mod_floor(arg2);
478
479                    let value = Value::integer(result);
480
481                    Ok(value)
482                } else {
483                    Err(Error::DivideByZero(arg1.clone(), arg2.clone()))
484                }
485            }
486            DefaultFunction::EqualsInteger => {
487                let arg1 = args[0].unwrap_integer()?;
488                let arg2 = args[1].unwrap_integer()?;
489
490                let value = Value::bool(arg1 == arg2);
491
492                Ok(value)
493            }
494            DefaultFunction::LessThanInteger => {
495                let arg1 = args[0].unwrap_integer()?;
496                let arg2 = args[1].unwrap_integer()?;
497
498                let value = Value::bool(arg1 < arg2);
499
500                Ok(value)
501            }
502            DefaultFunction::LessThanEqualsInteger => {
503                let arg1 = args[0].unwrap_integer()?;
504                let arg2 = args[1].unwrap_integer()?;
505
506                let value = Value::bool(arg1 <= arg2);
507
508                Ok(value)
509            }
510            DefaultFunction::AppendByteString => {
511                let arg1 = args[0].unwrap_byte_string()?;
512                let arg2 = args[1].unwrap_byte_string()?;
513
514                let result = arg1.iter().copied().chain(arg2.iter().copied()).collect();
515
516                let value = Value::byte_string(result);
517
518                Ok(value)
519            }
520            DefaultFunction::ConsByteString => {
521                let arg1 = args[0].unwrap_integer()?;
522                let arg2 = args[1].unwrap_byte_string()?;
523
524                let byte: u8 = match semantics {
525                    BuiltinSemantics::V1 => {
526                        let wrap = arg1.mod_floor(&256.into());
527
528                        wrap.try_into().unwrap()
529                    }
530                    BuiltinSemantics::V2 => {
531                        if *arg1 > 255.into() || *arg1 < 0.into() {
532                            return Err(Error::ByteStringConsNotAByte(arg1.clone()));
533                        }
534
535                        arg1.try_into().unwrap()
536                    }
537                };
538
539                let mut ret = vec![byte];
540
541                ret.extend(arg2.clone());
542
543                let value = Value::byte_string(ret);
544
545                Ok(value)
546            }
547            DefaultFunction::SliceByteString => {
548                let arg1 = args[0].unwrap_integer()?;
549                let arg2 = args[1].unwrap_integer()?;
550                let arg3 = args[2].unwrap_byte_string()?;
551
552                let skip: usize = if arg1.lt(&0.into()) {
553                    0
554                } else {
555                    arg1.try_into().unwrap()
556                };
557                let take: usize = if arg2.lt(&0.into()) {
558                    0
559                } else {
560                    arg2.try_into().unwrap()
561                };
562
563                let ret: Vec<u8> = arg3.iter().skip(skip).take(take).cloned().collect();
564
565                let value = Value::byte_string(ret);
566
567                Ok(value)
568            }
569            DefaultFunction::LengthOfByteString => {
570                let arg1 = args[0].unwrap_byte_string()?;
571
572                let value = Value::integer(arg1.len().into());
573
574                Ok(value)
575            }
576            DefaultFunction::IndexByteString => {
577                let arg1 = args[0].unwrap_byte_string()?;
578                let arg2 = args[1].unwrap_integer()?;
579
580                let index: i128 = arg2.try_into().unwrap();
581
582                if 0 <= index && index < arg1.len() as i128 {
583                    let ret = arg1[index as usize];
584
585                    let value = Value::integer(ret.into());
586
587                    Ok(value)
588                } else {
589                    Err(Error::ByteStringOutOfBounds(arg2.clone(), arg1.to_vec()))
590                }
591            }
592            DefaultFunction::EqualsByteString => {
593                let arg1 = args[0].unwrap_byte_string()?;
594                let arg2 = args[1].unwrap_byte_string()?;
595
596                let value = Value::bool(arg1 == arg2);
597
598                Ok(value)
599            }
600            DefaultFunction::LessThanByteString => {
601                let arg1 = args[0].unwrap_byte_string()?;
602                let arg2 = args[1].unwrap_byte_string()?;
603
604                let value = Value::bool(arg1 < arg2);
605
606                Ok(value)
607            }
608            DefaultFunction::LessThanEqualsByteString => {
609                let arg1 = args[0].unwrap_byte_string()?;
610                let arg2 = args[1].unwrap_byte_string()?;
611
612                let value = Value::bool(arg1 <= arg2);
613
614                Ok(value)
615            }
616            DefaultFunction::Sha2_256 => {
617                use cryptoxide::{digest::Digest, sha2::Sha256};
618
619                let arg1 = args[0].unwrap_byte_string()?;
620
621                let mut hasher = Sha256::new();
622
623                hasher.input(arg1);
624
625                let mut bytes = vec![0; hasher.output_bytes()];
626
627                hasher.result(&mut bytes);
628
629                let value = Value::byte_string(bytes);
630
631                Ok(value)
632            }
633            DefaultFunction::Sha3_256 => {
634                use cryptoxide::{digest::Digest, sha3::Sha3_256};
635
636                let arg1 = args[0].unwrap_byte_string()?;
637
638                let mut hasher = Sha3_256::new();
639
640                hasher.input(arg1);
641
642                let mut bytes = vec![0; hasher.output_bytes()];
643
644                hasher.result(&mut bytes);
645
646                let value = Value::byte_string(bytes);
647
648                Ok(value)
649            }
650
651            DefaultFunction::Blake2b_224 => {
652                use cryptoxide::{blake2b::Blake2b, digest::Digest};
653
654                let arg1 = args[0].unwrap_byte_string()?;
655
656                let mut digest = [0u8; 28];
657                let mut context = Blake2b::new(28);
658
659                context.input(arg1);
660                context.result(&mut digest);
661
662                let value = Value::byte_string(digest.to_vec());
663
664                Ok(value)
665            }
666            DefaultFunction::Blake2b_256 => {
667                use cryptoxide::{blake2b::Blake2b, digest::Digest};
668
669                let arg1 = args[0].unwrap_byte_string()?;
670
671                let mut digest = [0u8; 32];
672                let mut context = Blake2b::new(32);
673
674                context.input(arg1);
675                context.result(&mut digest);
676
677                let value = Value::byte_string(digest.to_vec());
678
679                Ok(value)
680            }
681            DefaultFunction::Keccak_256 => {
682                use cryptoxide::{digest::Digest, sha3::Keccak256};
683
684                let arg1 = args[0].unwrap_byte_string()?;
685
686                let mut hasher = Keccak256::new();
687
688                hasher.input(arg1);
689
690                let mut bytes = vec![0; hasher.output_bytes()];
691
692                hasher.result(&mut bytes);
693
694                let value = Value::byte_string(bytes);
695
696                Ok(value)
697            }
698            DefaultFunction::VerifyEd25519Signature => {
699                use cryptoxide::ed25519;
700
701                let public_key = args[0].unwrap_byte_string()?;
702                let message = args[1].unwrap_byte_string()?;
703                let signature = args[2].unwrap_byte_string()?;
704
705                let public_key: [u8; 32] = public_key
706                    .clone()
707                    .try_into()
708                    .map_err(|e: Vec<u8>| Error::UnexpectedEd25519PublicKeyLength(e.len()))?;
709
710                let signature: [u8; 64] = signature
711                    .clone()
712                    .try_into()
713                    .map_err(|e: Vec<u8>| Error::UnexpectedEd25519SignatureLength(e.len()))?;
714
715                let valid = ed25519::verify(message, &public_key, &signature);
716
717                let value = Value::bool(valid);
718
719                Ok(value)
720            }
721            DefaultFunction::VerifyEcdsaSecp256k1Signature => {
722                let public_key = args[0].unwrap_byte_string()?;
723                let message = args[1].unwrap_byte_string()?;
724                let signature = args[2].unwrap_byte_string()?;
725
726                verify_ecdsa(public_key, message, signature)
727            }
728            DefaultFunction::VerifySchnorrSecp256k1Signature => {
729                let public_key = args[0].unwrap_byte_string()?;
730                let message = args[1].unwrap_byte_string()?;
731                let signature = args[2].unwrap_byte_string()?;
732
733                verify_schnorr(public_key, message, signature)
734            }
735            DefaultFunction::AppendString => {
736                let arg1 = args[0].unwrap_string()?;
737                let arg2 = args[1].unwrap_string()?;
738
739                let value = Value::string(format!("{arg1}{arg2}"));
740
741                Ok(value)
742            }
743            DefaultFunction::EqualsString => {
744                let arg1 = args[0].unwrap_string()?;
745                let arg2 = args[1].unwrap_string()?;
746
747                let value = Value::bool(arg1 == arg2);
748
749                Ok(value)
750            }
751            DefaultFunction::EncodeUtf8 => {
752                let arg1 = args[0].unwrap_string()?;
753
754                let bytes = arg1.as_bytes().to_vec();
755
756                let value = Value::byte_string(bytes);
757
758                Ok(value)
759            }
760            DefaultFunction::DecodeUtf8 => {
761                let arg1 = args[0].unwrap_byte_string()?;
762
763                let string = String::from_utf8(arg1.clone())?;
764
765                let value = Value::string(string);
766
767                Ok(value)
768            }
769            DefaultFunction::IfThenElse => {
770                let condition = args[0].unwrap_bool()?;
771
772                if *condition {
773                    Ok(args[1].clone())
774                } else {
775                    Ok(args[2].clone())
776                }
777            }
778            DefaultFunction::ChooseUnit => {
779                args[0].unwrap_unit()?;
780
781                Ok(args[1].clone())
782            }
783            DefaultFunction::Trace => {
784                let arg1 = args[0].unwrap_string()?;
785
786                logs.push(arg1.clone());
787
788                Ok(args[1].clone())
789            }
790            DefaultFunction::FstPair => {
791                let (_, _, first, _) = args[0].unwrap_pair()?;
792
793                let value = Value::Con(first.clone());
794
795                Ok(value)
796            }
797            DefaultFunction::SndPair => {
798                let (_, _, _, second) = args[0].unwrap_pair()?;
799
800                let value = Value::Con(second.clone());
801
802                Ok(value)
803            }
804            DefaultFunction::ChooseList => {
805                let (_, list) = args[0].unwrap_list()?;
806
807                if list.is_empty() {
808                    Ok(args[1].clone())
809                } else {
810                    Ok(args[2].clone())
811                }
812            }
813            DefaultFunction::MkCons => {
814                let item = args[0].unwrap_constant()?;
815                let (r#type, list) = args[1].unwrap_list()?;
816
817                if *r#type != Type::from(item) {
818                    return Err(Error::TypeMismatch(Type::from(item), r#type.clone()));
819                }
820
821                let mut ret = vec![item.clone()];
822
823                ret.extend(list.clone());
824
825                let value = Value::list(r#type.clone(), ret);
826
827                Ok(value)
828            }
829            DefaultFunction::HeadList => {
830                let (_, list) = args[0].unwrap_list()?;
831
832                if list.is_empty() {
833                    Err(Error::EmptyList(args[0].clone()))
834                } else {
835                    let value = Value::Con(list[0].clone().into());
836
837                    Ok(value)
838                }
839            }
840            DefaultFunction::TailList => {
841                let (r#type, list) = args[0].unwrap_list()?;
842
843                if list.is_empty() {
844                    Err(Error::EmptyList(args[0].clone()))
845                } else {
846                    let value = Value::list(r#type.clone(), list[1..].to_vec());
847
848                    Ok(value)
849                }
850            }
851            DefaultFunction::NullList => {
852                let (_, list) = args[0].unwrap_list()?;
853
854                let value = Value::bool(list.is_empty());
855
856                Ok(value)
857            }
858            DefaultFunction::ChooseData => {
859                let con = args[0].unwrap_data()?;
860
861                match con {
862                    PlutusData::Constr(_) => Ok(args[1].clone()),
863                    PlutusData::Map(_) => Ok(args[2].clone()),
864                    PlutusData::Array(_) => Ok(args[3].clone()),
865                    PlutusData::BigInt(_) => Ok(args[4].clone()),
866                    PlutusData::BoundedBytes(_) => Ok(args[5].clone()),
867                }
868            }
869            DefaultFunction::ConstrData => {
870                let i = args[0].unwrap_integer()?;
871                let l = args[1].unwrap_data_list()?;
872
873                let data_list: Vec<PlutusData> = l
874                    .iter()
875                    .map(|item| match item {
876                        Constant::Data(d) => d.clone(),
877                        _ => unreachable!(),
878                    })
879                    .collect();
880
881                let i: u64 = i.try_into().unwrap();
882
883                let constr_data = Data::constr(i, data_list);
884
885                let value = Value::data(constr_data);
886
887                Ok(value)
888            }
889            DefaultFunction::MapData => {
890                let (r#type, list) = args[0].unwrap_list()?;
891
892                if *r#type != Type::Pair(Rc::new(Type::Data), Rc::new(Type::Data)) {
893                    return Err(Error::TypeMismatch(
894                        Type::List(Rc::new(Type::Pair(
895                            Rc::new(Type::Data),
896                            Rc::new(Type::Data),
897                        ))),
898                        r#type.clone(),
899                    ));
900                }
901
902                let mut map = Vec::new();
903
904                for item in list {
905                    let Constant::ProtoPair(Type::Data, Type::Data, left, right) = item else {
906                        unreachable!()
907                    };
908
909                    let (Constant::Data(key), Constant::Data(value)) =
910                        (left.as_ref(), right.as_ref())
911                    else {
912                        unreachable!()
913                    };
914
915                    map.push((key.clone(), value.clone()));
916                }
917
918                let value = Value::data(PlutusData::Map(map.into()));
919
920                Ok(value)
921            }
922            DefaultFunction::ListData => {
923                let list = args[0].unwrap_data_list()?;
924
925                let data_list: Vec<PlutusData> = list
926                    .iter()
927                    .map(|item| match item {
928                        Constant::Data(d) => d.clone(),
929                        _ => unreachable!(),
930                    })
931                    .collect();
932
933                let value = Value::data(Data::list(data_list));
934
935                Ok(value)
936            }
937            DefaultFunction::IData => {
938                let i = args[0].unwrap_integer()?;
939
940                let value = Value::data(PlutusData::BigInt(to_pallas_bigint(i)));
941
942                Ok(value)
943            }
944            DefaultFunction::BData => {
945                let b = args[0].unwrap_byte_string()?;
946
947                let value = Value::data(PlutusData::BoundedBytes(b.clone().into()));
948
949                Ok(value)
950            }
951            DefaultFunction::UnConstrData => match &args[0] {
952                v @ Value::Con(inner) => {
953                    let Constant::Data(PlutusData::Constr(c)) = inner.as_ref() else {
954                        return Err(Error::DeserialisationError(
955                            "UnConstrData".to_string(),
956                            v.clone(),
957                        ));
958                    };
959
960                    let constant = Constant::ProtoPair(
961                        Type::Integer,
962                        Type::List(Type::Data.into()),
963                        Constant::Integer(
964                            convert_tag_to_constr(c.tag)
965                                .unwrap_or_else(|| c.any_constructor.unwrap())
966                                .into(),
967                        )
968                        .into(),
969                        Constant::ProtoList(
970                            Type::Data,
971                            c.fields
972                                .deref()
973                                .iter()
974                                .map(|d| Constant::Data(d.clone()))
975                                .collect(),
976                        )
977                        .into(),
978                    );
979
980                    let value = Value::Con(constant.into());
981
982                    Ok(value)
983                }
984                v => Err(Error::NotAConstant(v.clone())),
985            },
986            DefaultFunction::UnMapData => match &args[0] {
987                v @ Value::Con(inner) => {
988                    let Constant::Data(PlutusData::Map(m)) = inner.as_ref() else {
989                        return Err(Error::DeserialisationError(
990                            "UnMapData".to_string(),
991                            v.clone(),
992                        ));
993                    };
994
995                    let constant = Constant::ProtoList(
996                        Type::Pair(Type::Data.into(), Type::Data.into()),
997                        m.deref()
998                            .iter()
999                            .map(|p| -> Constant {
1000                                Constant::ProtoPair(
1001                                    Type::Data,
1002                                    Type::Data,
1003                                    Constant::Data(p.0.clone()).into(),
1004                                    Constant::Data(p.1.clone()).into(),
1005                                )
1006                            })
1007                            .collect(),
1008                    );
1009
1010                    let value = Value::Con(constant.into());
1011
1012                    Ok(value)
1013                }
1014                v => Err(Error::NotAConstant(v.clone())),
1015            },
1016            DefaultFunction::UnListData => match &args[0] {
1017                v @ Value::Con(inner) => {
1018                    let Constant::Data(PlutusData::Array(l)) = inner.as_ref() else {
1019                        return Err(Error::DeserialisationError(
1020                            "UnListData".to_string(),
1021                            v.clone(),
1022                        ));
1023                    };
1024
1025                    let value = Value::list(
1026                        Type::Data,
1027                        l.deref()
1028                            .iter()
1029                            .map(|d| Constant::Data(d.clone()))
1030                            .collect(),
1031                    );
1032
1033                    Ok(value)
1034                }
1035                v => Err(Error::NotAConstant(v.clone())),
1036            },
1037            DefaultFunction::UnIData => match &args[0] {
1038                v @ Value::Con(inner) => {
1039                    let Constant::Data(PlutusData::BigInt(b)) = inner.as_ref() else {
1040                        return Err(Error::DeserialisationError(
1041                            "UnIData".to_string(),
1042                            v.clone(),
1043                        ));
1044                    };
1045
1046                    let value = Value::integer(from_pallas_bigint(b));
1047
1048                    Ok(value)
1049                }
1050                v => Err(Error::NotAConstant(v.clone())),
1051            },
1052            DefaultFunction::UnBData => match &args[0] {
1053                v @ Value::Con(inner) => {
1054                    let Constant::Data(PlutusData::BoundedBytes(b)) = inner.as_ref() else {
1055                        return Err(Error::DeserialisationError(
1056                            "UnBData".to_string(),
1057                            v.clone(),
1058                        ));
1059                    };
1060
1061                    let value = Value::byte_string(b.to_vec());
1062
1063                    Ok(value)
1064                }
1065                v => Err(Error::NotAConstant(v.clone())),
1066            },
1067            DefaultFunction::EqualsData => {
1068                let d1 = args[0].unwrap_data()?;
1069                let d2 = args[1].unwrap_data()?;
1070
1071                let value = Value::bool(d1.eq(d2));
1072
1073                Ok(value)
1074            }
1075            DefaultFunction::SerialiseData => {
1076                let d = args[0].unwrap_data()?;
1077
1078                let serialized_data = plutus_data_to_bytes(d).unwrap();
1079
1080                let value = Value::byte_string(serialized_data);
1081
1082                Ok(value)
1083            }
1084            DefaultFunction::MkPairData => {
1085                let d1 = args[0].unwrap_data()?;
1086                let d2 = args[1].unwrap_data()?;
1087
1088                let constant = Constant::ProtoPair(
1089                    Type::Data,
1090                    Type::Data,
1091                    Constant::Data(d1.clone()).into(),
1092                    Constant::Data(d2.clone()).into(),
1093                );
1094
1095                let value = Value::Con(constant.into());
1096
1097                Ok(value)
1098            }
1099            DefaultFunction::MkNilData => {
1100                args[0].unwrap_unit()?;
1101
1102                let value = Value::list(Type::Data, vec![]);
1103
1104                Ok(value)
1105            }
1106            DefaultFunction::MkNilPairData => {
1107                args[0].unwrap_unit()?;
1108
1109                let constant = Constant::ProtoList(
1110                    Type::Pair(Rc::new(Type::Data), Rc::new(Type::Data)),
1111                    vec![],
1112                );
1113
1114                let value = Value::Con(constant.into());
1115
1116                Ok(value)
1117            }
1118
1119            DefaultFunction::Bls12_381_G1_Add => {
1120                let arg1 = args[0].unwrap_bls12_381_g1_element()?;
1121                let arg2 = args[1].unwrap_bls12_381_g1_element()?;
1122
1123                let mut out = blst::blst_p1::default();
1124
1125                unsafe {
1126                    blst::blst_p1_add_or_double(
1127                        &mut out as *mut _,
1128                        arg1 as *const _,
1129                        arg2 as *const _,
1130                    );
1131                }
1132
1133                let constant = Constant::Bls12_381G1Element(out.into());
1134
1135                Ok(Value::Con(constant.into()))
1136            }
1137            DefaultFunction::Bls12_381_G1_Neg => {
1138                let arg1 = args[0].unwrap_bls12_381_g1_element()?;
1139
1140                let mut out = *arg1;
1141
1142                unsafe {
1143                    blst::blst_p1_cneg(
1144                        &mut out as *mut _,
1145                        // This was true in the Cardano code
1146                        true,
1147                    );
1148                }
1149
1150                let constant = Constant::Bls12_381G1Element(out.into());
1151
1152                Ok(Value::Con(constant.into()))
1153            }
1154            DefaultFunction::Bls12_381_G1_ScalarMul => {
1155                let arg1 = args[0].unwrap_integer()?;
1156                let arg2 = args[1].unwrap_bls12_381_g1_element()?;
1157
1158                let size_scalar = size_of::<blst::blst_scalar>();
1159
1160                let arg1 = arg1.mod_floor(&SCALAR_PERIOD);
1161
1162                let (_, mut arg1) = arg1.to_bytes_be();
1163
1164                if size_scalar > arg1.len() {
1165                    let diff = size_scalar - arg1.len();
1166
1167                    let mut new_vec = vec![0; diff];
1168
1169                    new_vec.append(&mut arg1);
1170
1171                    arg1 = new_vec;
1172                }
1173
1174                let mut out = blst::blst_p1::default();
1175                let mut scalar = blst::blst_scalar::default();
1176
1177                unsafe {
1178                    blst::blst_scalar_from_bendian(
1179                        &mut scalar as *mut _,
1180                        arg1.as_ptr() as *const _,
1181                    );
1182
1183                    blst::blst_p1_mult(
1184                        &mut out as *mut _,
1185                        arg2 as *const _,
1186                        scalar.b.as_ptr() as *const _,
1187                        size_scalar * 8,
1188                    );
1189                }
1190
1191                let constant = Constant::Bls12_381G1Element(out.into());
1192
1193                Ok(Value::Con(constant.into()))
1194            }
1195            DefaultFunction::Bls12_381_G1_Equal => {
1196                let arg1 = args[0].unwrap_bls12_381_g1_element()?;
1197                let arg2 = args[1].unwrap_bls12_381_g1_element()?;
1198
1199                let is_equal = unsafe { blst::blst_p1_is_equal(arg1, arg2) };
1200
1201                let constant = Constant::Bool(is_equal);
1202
1203                Ok(Value::Con(constant.into()))
1204            }
1205            DefaultFunction::Bls12_381_G1_Compress => {
1206                let arg1 = args[0].unwrap_bls12_381_g1_element()?;
1207
1208                let out = arg1.compress();
1209
1210                let constant = Constant::ByteString(out.to_vec());
1211
1212                Ok(Value::Con(constant.into()))
1213            }
1214            DefaultFunction::Bls12_381_G1_Uncompress => {
1215                let arg1 = args[0].unwrap_byte_string()?;
1216
1217                let out = blst::blst_p1::uncompress(arg1)?;
1218
1219                let constant = Constant::Bls12_381G1Element(out.into());
1220
1221                Ok(Value::Con(constant.into()))
1222            }
1223            DefaultFunction::Bls12_381_G1_HashToGroup => {
1224                let arg1 = args[0].unwrap_byte_string()?;
1225                let arg2 = args[1].unwrap_byte_string()?;
1226
1227                if arg2.len() > 255 {
1228                    return Err(Error::HashToCurveDstTooBig);
1229                }
1230
1231                let mut out = blst::blst_p1::default();
1232                let aug = [];
1233
1234                unsafe {
1235                    blst::blst_hash_to_g1(
1236                        &mut out as *mut _,
1237                        arg1.as_ptr(),
1238                        arg1.len(),
1239                        arg2.as_ptr(),
1240                        arg2.len(),
1241                        aug.as_ptr(),
1242                        0,
1243                    );
1244                };
1245
1246                let constant = Constant::Bls12_381G1Element(out.into());
1247
1248                Ok(Value::Con(constant.into()))
1249            }
1250            DefaultFunction::Bls12_381_G2_Add => {
1251                let arg1 = args[0].unwrap_bls12_381_g2_element()?;
1252                let arg2 = args[1].unwrap_bls12_381_g2_element()?;
1253
1254                let mut out = blst::blst_p2::default();
1255
1256                unsafe {
1257                    blst::blst_p2_add_or_double(
1258                        &mut out as *mut _,
1259                        arg1 as *const _,
1260                        arg2 as *const _,
1261                    );
1262                }
1263
1264                let constant = Constant::Bls12_381G2Element(out.into());
1265
1266                Ok(Value::Con(constant.into()))
1267            }
1268            DefaultFunction::Bls12_381_G2_Neg => {
1269                let arg1 = args[0].unwrap_bls12_381_g2_element()?;
1270
1271                let mut out = *arg1;
1272
1273                unsafe {
1274                    blst::blst_p2_cneg(
1275                        &mut out as *mut _,
1276                        // This was true in the Cardano code
1277                        true,
1278                    );
1279                }
1280
1281                let constant = Constant::Bls12_381G2Element(out.into());
1282
1283                Ok(Value::Con(constant.into()))
1284            }
1285            DefaultFunction::Bls12_381_G2_ScalarMul => {
1286                let arg1 = args[0].unwrap_integer()?;
1287                let arg2 = args[1].unwrap_bls12_381_g2_element()?;
1288
1289                let size_scalar = size_of::<blst::blst_scalar>();
1290
1291                let arg1 = arg1.mod_floor(&SCALAR_PERIOD);
1292
1293                let (_, mut arg1) = arg1.to_bytes_be();
1294
1295                if size_scalar > arg1.len() {
1296                    let diff = size_scalar - arg1.len();
1297
1298                    let mut new_vec = vec![0; diff];
1299
1300                    new_vec.append(&mut arg1);
1301
1302                    arg1 = new_vec;
1303                }
1304
1305                let mut out = blst::blst_p2::default();
1306                let mut scalar = blst::blst_scalar::default();
1307
1308                unsafe {
1309                    blst::blst_scalar_from_bendian(
1310                        &mut scalar as *mut _,
1311                        arg1.as_ptr() as *const _,
1312                    );
1313
1314                    blst::blst_p2_mult(
1315                        &mut out as *mut _,
1316                        arg2 as *const _,
1317                        scalar.b.as_ptr() as *const _,
1318                        size_scalar * 8,
1319                    );
1320                }
1321
1322                let constant = Constant::Bls12_381G2Element(out.into());
1323
1324                Ok(Value::Con(constant.into()))
1325            }
1326            DefaultFunction::Bls12_381_G2_Equal => {
1327                let arg1 = args[0].unwrap_bls12_381_g2_element()?;
1328                let arg2 = args[1].unwrap_bls12_381_g2_element()?;
1329
1330                let is_equal = unsafe { blst::blst_p2_is_equal(arg1, arg2) };
1331
1332                let constant = Constant::Bool(is_equal);
1333
1334                Ok(Value::Con(constant.into()))
1335            }
1336            DefaultFunction::Bls12_381_G2_Compress => {
1337                let arg1 = args[0].unwrap_bls12_381_g2_element()?;
1338
1339                let out = arg1.compress();
1340
1341                let constant = Constant::ByteString(out.to_vec());
1342
1343                Ok(Value::Con(constant.into()))
1344            }
1345            DefaultFunction::Bls12_381_G2_Uncompress => {
1346                let arg1 = args[0].unwrap_byte_string()?;
1347
1348                let out = blst::blst_p2::uncompress(arg1)?;
1349
1350                let constant = Constant::Bls12_381G2Element(out.into());
1351
1352                Ok(Value::Con(constant.into()))
1353            }
1354            DefaultFunction::Bls12_381_G2_HashToGroup => {
1355                let arg1 = args[0].unwrap_byte_string()?;
1356                let arg2 = args[1].unwrap_byte_string()?;
1357
1358                if arg2.len() > 255 {
1359                    return Err(Error::HashToCurveDstTooBig);
1360                }
1361
1362                let mut out = blst::blst_p2::default();
1363                let aug = [];
1364
1365                unsafe {
1366                    blst::blst_hash_to_g2(
1367                        &mut out as *mut _,
1368                        arg1.as_ptr(),
1369                        arg1.len(),
1370                        arg2.as_ptr(),
1371                        arg2.len(),
1372                        aug.as_ptr(),
1373                        0,
1374                    );
1375                };
1376
1377                let constant = Constant::Bls12_381G2Element(out.into());
1378
1379                Ok(Value::Con(constant.into()))
1380            }
1381            DefaultFunction::Bls12_381_MillerLoop => {
1382                let arg1 = args[0].unwrap_bls12_381_g1_element()?;
1383                let arg2 = args[1].unwrap_bls12_381_g2_element()?;
1384
1385                let mut out = blst::blst_fp12::default();
1386
1387                let mut affine1 = blst::blst_p1_affine::default();
1388                let mut affine2 = blst::blst_p2_affine::default();
1389
1390                unsafe {
1391                    blst::blst_p1_to_affine(&mut affine1 as *mut _, arg1);
1392                    blst::blst_p2_to_affine(&mut affine2 as *mut _, arg2);
1393
1394                    blst::blst_miller_loop(&mut out as *mut _, &affine2, &affine1);
1395                }
1396
1397                let constant = Constant::Bls12_381MlResult(out.into());
1398
1399                Ok(Value::Con(constant.into()))
1400            }
1401            DefaultFunction::Bls12_381_MulMlResult => {
1402                let arg1 = args[0].unwrap_bls12_381_ml_result()?;
1403                let arg2 = args[1].unwrap_bls12_381_ml_result()?;
1404
1405                let mut out = blst::blst_fp12::default();
1406
1407                unsafe {
1408                    blst::blst_fp12_mul(&mut out as *mut _, arg1, arg2);
1409                }
1410
1411                let constant = Constant::Bls12_381MlResult(out.into());
1412
1413                Ok(Value::Con(constant.into()))
1414            }
1415            DefaultFunction::Bls12_381_FinalVerify => {
1416                let arg1 = args[0].unwrap_bls12_381_ml_result()?;
1417                let arg2 = args[1].unwrap_bls12_381_ml_result()?;
1418
1419                let verified = unsafe { blst::blst_fp12_finalverify(arg1, arg2) };
1420
1421                let constant = Constant::Bool(verified);
1422
1423                Ok(Value::Con(constant.into()))
1424            }
1425            DefaultFunction::IntegerToByteString => {
1426                let endianness = args[0].unwrap_bool()?;
1427                let size = args[1].unwrap_integer()?;
1428                let input = args[2].unwrap_integer()?;
1429
1430                // NOTE:
1431                // We ought to also check for negative size and too large sizes. These checks
1432                // however happens prior to calling the builtin as part of the costing step. So by
1433                // the time we reach this builtin call, the size can be assumed to be
1434                //
1435                // >= 0 && < INTEGER_TO_BYTE_STRING_MAXIMUM_OUTPUT_LENGTH
1436
1437                if size.is_zero()
1438                    && integer_log2(input.clone())
1439                        >= 8 * INTEGER_TO_BYTE_STRING_MAXIMUM_OUTPUT_LENGTH
1440                {
1441                    let required = integer_log2(input.clone()) / 8 + 1;
1442
1443                    return Err(Error::IntegerToByteStringSizeTooBig(
1444                        required.into(),
1445                        INTEGER_TO_BYTE_STRING_MAXIMUM_OUTPUT_LENGTH,
1446                    ));
1447                }
1448
1449                if input.is_negative() {
1450                    return Err(Error::IntegerToByteStringNegativeInput(input.clone()));
1451                }
1452
1453                let size_unwrapped: usize = size.try_into().unwrap();
1454
1455                if input.is_zero() {
1456                    let constant = Constant::ByteString(vec![0; size_unwrapped]);
1457
1458                    return Ok(Value::Con(constant.into()));
1459                }
1460
1461                let (_, mut bytes) = if *endianness {
1462                    input.to_bytes_be()
1463                } else {
1464                    input.to_bytes_le()
1465                };
1466
1467                if !size.is_zero() && bytes.len() > size_unwrapped {
1468                    return Err(Error::IntegerToByteStringSizeTooSmall(
1469                        size.clone(),
1470                        bytes.len(),
1471                    ));
1472                }
1473
1474                if size_unwrapped > 0 {
1475                    let padding_size = size_unwrapped - bytes.len();
1476
1477                    let mut padding = vec![0; padding_size];
1478
1479                    if *endianness {
1480                        padding.append(&mut bytes);
1481
1482                        bytes = padding;
1483                    } else {
1484                        bytes.append(&mut padding);
1485                    }
1486                };
1487
1488                let constant = Constant::ByteString(bytes);
1489
1490                Ok(Value::Con(constant.into()))
1491            }
1492            DefaultFunction::ByteStringToInteger => {
1493                let endianness = args[0].unwrap_bool()?;
1494                let bytes = args[1].unwrap_byte_string()?;
1495
1496                let number = if *endianness {
1497                    BigInt::from_bytes_be(num_bigint::Sign::Plus, bytes)
1498                } else {
1499                    BigInt::from_bytes_le(num_bigint::Sign::Plus, bytes)
1500                };
1501
1502                let constant = Constant::Integer(number);
1503
1504                Ok(Value::Con(constant.into()))
1505            }
1506            DefaultFunction::AndByteString => {
1507                let should_pad = args[0].unwrap_bool()?;
1508                let bytes1 = args[1].unwrap_byte_string()?;
1509                let bytes2 = args[2].unwrap_byte_string()?;
1510
1511                let bytes_result = if *should_pad {
1512                    bytes1
1513                        .iter()
1514                        .zip_longest(bytes2)
1515                        .map(|b| match b {
1516                            itertools::EitherOrBoth::Both(left_byte, right_byte) => {
1517                                left_byte & right_byte
1518                            }
1519                            // Shorter is appended with FF bytes that when and-ed produce the other bytestring
1520                            itertools::EitherOrBoth::Left(byte)
1521                            | itertools::EitherOrBoth::Right(byte) => *byte,
1522                        })
1523                        .collect_vec()
1524                } else {
1525                    bytes1
1526                        .iter()
1527                        .zip(bytes2)
1528                        .map(|(b1, b2)| b1 & b2)
1529                        .collect_vec()
1530                };
1531
1532                Ok(Value::byte_string(bytes_result))
1533            }
1534            DefaultFunction::OrByteString => {
1535                let should_pad = args[0].unwrap_bool()?;
1536                let bytes1 = args[1].unwrap_byte_string()?;
1537                let bytes2 = args[2].unwrap_byte_string()?;
1538
1539                let bytes_result = if *should_pad {
1540                    bytes1
1541                        .iter()
1542                        .zip_longest(bytes2)
1543                        .map(|b| match b {
1544                            itertools::EitherOrBoth::Both(left_byte, right_byte) => {
1545                                left_byte | right_byte
1546                            }
1547                            // Shorter is appended with 00 bytes that when or-ed produce the other bytestring
1548                            itertools::EitherOrBoth::Left(byte)
1549                            | itertools::EitherOrBoth::Right(byte) => *byte,
1550                        })
1551                        .collect_vec()
1552                } else {
1553                    bytes1
1554                        .iter()
1555                        .zip(bytes2)
1556                        .map(|(b1, b2)| b1 | b2)
1557                        .collect_vec()
1558                };
1559
1560                Ok(Value::byte_string(bytes_result))
1561            }
1562            DefaultFunction::XorByteString => {
1563                let should_pad = args[0].unwrap_bool()?;
1564                let bytes1 = args[1].unwrap_byte_string()?;
1565                let bytes2 = args[2].unwrap_byte_string()?;
1566
1567                let bytes_result = if *should_pad {
1568                    bytes1
1569                        .iter()
1570                        .zip_longest(bytes2)
1571                        .map(|b| match b {
1572                            itertools::EitherOrBoth::Both(left_byte, right_byte) => {
1573                                left_byte ^ right_byte
1574                            }
1575                            // Shorter is appended with 00 bytes that when xor-ed produce the other bytestring
1576                            itertools::EitherOrBoth::Left(byte)
1577                            | itertools::EitherOrBoth::Right(byte) => *byte,
1578                        })
1579                        .collect_vec()
1580                } else {
1581                    bytes1
1582                        .iter()
1583                        .zip(bytes2)
1584                        .map(|(b1, b2)| b1 ^ b2)
1585                        .collect_vec()
1586                };
1587
1588                Ok(Value::byte_string(bytes_result))
1589            }
1590            DefaultFunction::ComplementByteString => {
1591                let bytes = args[0].unwrap_byte_string()?;
1592
1593                let result = bytes.iter().map(|b| b ^ 255).collect_vec();
1594
1595                Ok(Value::byte_string(result))
1596            }
1597            DefaultFunction::ReadBit => {
1598                let bytes = args[0].unwrap_byte_string()?;
1599                let bit_index = args[1].unwrap_integer()?;
1600
1601                if bytes.is_empty() {
1602                    return Err(Error::EmptyByteArray);
1603                }
1604
1605                // This ensures there is at least one byte in bytes
1606                if *bit_index < 0.into() || *bit_index >= (bytes.len() * 8).into() {
1607                    return Err(Error::ReadBitOutOfBounds);
1608                }
1609
1610                let (byte_index, bit_offset) = bit_index.div_rem(&8.into());
1611
1612                let bit_offset = usize::try_from(bit_offset).unwrap();
1613
1614                let flipped_index = bytes.len() - 1 - usize::try_from(byte_index).unwrap();
1615
1616                let byte = bytes[flipped_index];
1617
1618                let bit_test = (byte >> bit_offset) & 1 == 1;
1619
1620                Ok(Value::bool(bit_test))
1621            }
1622            DefaultFunction::WriteBits => {
1623                let mut bytes = args[0].unwrap_byte_string()?.clone();
1624                let indices = args[1].unwrap_int_list()?;
1625                let set_bit = args[2].unwrap_bool()?;
1626
1627                for index in indices {
1628                    let Constant::Integer(bit_index) = index else {
1629                        unreachable!()
1630                    };
1631
1632                    if *bit_index < 0.into() || *bit_index >= (bytes.len() * 8).into() {
1633                        return Err(Error::WriteBitsOutOfBounds);
1634                    }
1635
1636                    let (byte_index, bit_offset) = bit_index.div_rem(&8.into());
1637
1638                    let bit_offset = usize::try_from(bit_offset).unwrap();
1639
1640                    let flipped_index = bytes.len() - 1 - usize::try_from(byte_index).unwrap();
1641
1642                    let bit_mask: u8 = 1 << bit_offset;
1643
1644                    if *set_bit {
1645                        bytes[flipped_index] |= bit_mask;
1646                    } else {
1647                        bytes[flipped_index] &= !bit_mask;
1648                    }
1649                }
1650
1651                Ok(Value::byte_string(bytes))
1652            }
1653            DefaultFunction::ReplicateByte => {
1654                let size = args[0].unwrap_integer()?;
1655                let byte = args[1].unwrap_integer()?;
1656
1657                // Safe since this is checked by cost model
1658                let size = usize::try_from(size).unwrap();
1659
1660                let Ok(byte) = u8::try_from(byte) else {
1661                    return Err(Error::OutsideByteBounds(byte.clone()));
1662                };
1663
1664                let value = if size == 0 {
1665                    Value::byte_string(vec![])
1666                } else {
1667                    Value::byte_string([byte].repeat(size))
1668                };
1669
1670                Ok(value)
1671            }
1672            DefaultFunction::ShiftByteString => {
1673                let bytes = args[0].unwrap_byte_string()?;
1674                let shift = args[1].unwrap_integer()?;
1675
1676                let byte_length = bytes.len();
1677
1678                if BigInt::from_usize(byte_length).unwrap() * 8 <= shift.abs() {
1679                    let new_vec = vec![0; byte_length];
1680
1681                    return Ok(Value::byte_string(new_vec));
1682                }
1683
1684                let is_shl = shift >= &0.into();
1685
1686                let mut bv = BitVec::<u8, Msb0>::from_vec(bytes.clone());
1687
1688                if is_shl {
1689                    bv.shift_left(usize::try_from(shift.abs()).unwrap());
1690                } else {
1691                    bv.shift_right(usize::try_from(shift.abs()).unwrap());
1692                }
1693
1694                Ok(Value::byte_string(bv.into_vec()))
1695            }
1696            DefaultFunction::RotateByteString => {
1697                let bytes = args[0].unwrap_byte_string()?;
1698                let shift = args[1].unwrap_integer()?;
1699
1700                let byte_length = bytes.len();
1701
1702                if bytes.is_empty() {
1703                    return Ok(Value::byte_string(bytes.clone()));
1704                }
1705
1706                let shift = shift.mod_floor(&(byte_length * 8).into());
1707
1708                let mut bv = BitVec::<u8, Msb0>::from_vec(bytes.clone());
1709
1710                bv.rotate_left(usize::try_from(shift).unwrap());
1711
1712                Ok(Value::byte_string(bv.into_vec()))
1713            }
1714            DefaultFunction::CountSetBits => {
1715                let bytes = args[0].unwrap_byte_string()?;
1716
1717                Ok(Value::integer(hamming::weight(bytes).into()))
1718            }
1719            DefaultFunction::FindFirstSetBit => {
1720                let bytes = args[0].unwrap_byte_string()?;
1721
1722                let first_bit = bytes
1723                    .iter()
1724                    .rev()
1725                    .enumerate()
1726                    .find_map(|(byte_index, value)| {
1727                        let value = value.reverse_bits();
1728
1729                        let first_bit: Option<usize> = if value >= 128 {
1730                            Some(0)
1731                        } else if value >= 64 {
1732                            Some(1)
1733                        } else if value >= 32 {
1734                            Some(2)
1735                        } else if value >= 16 {
1736                            Some(3)
1737                        } else if value >= 8 {
1738                            Some(4)
1739                        } else if value >= 4 {
1740                            Some(5)
1741                        } else if value >= 2 {
1742                            Some(6)
1743                        } else if value >= 1 {
1744                            Some(7)
1745                        } else {
1746                            None
1747                        };
1748
1749                        first_bit.map(|bit| isize::try_from(bit + byte_index * 8).unwrap())
1750                    });
1751
1752                Ok(Value::integer(first_bit.unwrap_or(-1).into()))
1753            }
1754            DefaultFunction::Ripemd_160 => {
1755                use cryptoxide::{digest::Digest, ripemd160::Ripemd160};
1756
1757                let arg1 = args[0].unwrap_byte_string()?;
1758
1759                let mut hasher = Ripemd160::new();
1760
1761                hasher.input(arg1);
1762
1763                let mut bytes = vec![0; hasher.output_bytes()];
1764
1765                hasher.result(&mut bytes);
1766
1767                let value = Value::byte_string(bytes);
1768
1769                Ok(value)
1770            } // DefaultFunction::ExpModInteger => todo!(),
1771        }
1772    }
1773}
1774
1775pub trait Compressable {
1776    fn compress(&self) -> Vec<u8>;
1777
1778    fn uncompress(bytes: &[u8]) -> Result<Self, Error>
1779    where
1780        Self: core::marker::Sized;
1781}
1782
1783impl Compressable for blst::blst_p1 {
1784    fn compress(&self) -> Vec<u8> {
1785        let mut out = [0; BLST_P1_COMPRESSED_SIZE];
1786
1787        unsafe {
1788            blst::blst_p1_compress(&mut out as *mut _, self);
1789        };
1790
1791        out.to_vec()
1792    }
1793
1794    fn uncompress(bytes: &[u8]) -> Result<Self, Error> {
1795        if bytes.len() != BLST_P1_COMPRESSED_SIZE {
1796            return Err(Error::Blst(blst::BLST_ERROR::BLST_BAD_ENCODING));
1797        }
1798
1799        let mut affine = blst::blst_p1_affine::default();
1800
1801        let mut out = blst::blst_p1::default();
1802
1803        unsafe {
1804            let err = blst::blst_p1_uncompress(&mut affine as *mut _, bytes.as_ptr());
1805
1806            if err != blst::BLST_ERROR::BLST_SUCCESS {
1807                return Err(Error::Blst(err));
1808            }
1809
1810            blst::blst_p1_from_affine(&mut out as *mut _, &affine);
1811
1812            let in_group = blst::blst_p1_in_g1(&out);
1813
1814            if !in_group {
1815                return Err(Error::Blst(blst::BLST_ERROR::BLST_POINT_NOT_IN_GROUP));
1816            }
1817        };
1818
1819        Ok(out)
1820    }
1821}
1822
1823impl Compressable for blst::blst_p2 {
1824    fn compress(&self) -> Vec<u8> {
1825        let mut out = [0; BLST_P2_COMPRESSED_SIZE];
1826
1827        unsafe {
1828            blst::blst_p2_compress(&mut out as *mut _, self);
1829        };
1830
1831        out.to_vec()
1832    }
1833
1834    fn uncompress(bytes: &[u8]) -> Result<Self, Error> {
1835        if bytes.len() != BLST_P2_COMPRESSED_SIZE {
1836            return Err(Error::Blst(blst::BLST_ERROR::BLST_BAD_ENCODING));
1837        }
1838
1839        let mut affine = blst::blst_p2_affine::default();
1840
1841        let mut out = blst::blst_p2::default();
1842
1843        unsafe {
1844            let err = blst::blst_p2_uncompress(&mut affine as *mut _, bytes.as_ptr());
1845
1846            if err != blst::BLST_ERROR::BLST_SUCCESS {
1847                return Err(Error::Blst(err));
1848            }
1849
1850            blst::blst_p2_from_affine(&mut out as *mut _, &affine);
1851
1852            let in_group = blst::blst_p2_in_g2(&out);
1853
1854            if !in_group {
1855                return Err(Error::Blst(blst::BLST_ERROR::BLST_POINT_NOT_IN_GROUP));
1856            }
1857        };
1858
1859        Ok(out)
1860    }
1861}
1862
1863pub fn convert_tag_to_constr(tag: u64) -> Option<u64> {
1864    if (121..=127).contains(&tag) {
1865        Some(tag - 121)
1866    } else if (1280..=1400).contains(&tag) {
1867        Some(tag - 1280 + 7)
1868    } else {
1869        None
1870    }
1871}
1872
1873pub fn convert_constr_to_tag(constr: u64) -> Option<u64> {
1874    if (0..=6).contains(&constr) {
1875        Some(121 + constr)
1876    } else if (7..=127).contains(&constr) {
1877        Some(1280 - 7 + constr)
1878    } else {
1879        None // 102 otherwise
1880    }
1881}
1882
1883pub static ANY_TAG: u64 = 102;
1884
1885#[cfg(not(target_family = "wasm"))]
1886fn verify_ecdsa(public_key: &[u8], message: &[u8], signature: &[u8]) -> Result<Value, Error> {
1887    use secp256k1::{ecdsa::Signature, Message, PublicKey, Secp256k1};
1888
1889    let secp = Secp256k1::verification_only();
1890
1891    let public_key = PublicKey::from_slice(public_key)?;
1892
1893    let signature = Signature::from_compact(signature)?;
1894
1895    let message = Message::from_slice(message)?;
1896
1897    let valid = secp.verify_ecdsa(&message, &signature, &public_key);
1898
1899    Ok(Value::Con(Constant::Bool(valid.is_ok()).into()))
1900}
1901
1902/// Unlike the Haskell implementation the schnorr verification function in Aiken doesn't allow for arbitrary message sizes (at the moment).
1903/// The message needs to be 32 bytes (ideally prehashed, but not a requirement).
1904#[cfg(not(target_family = "wasm"))]
1905fn verify_schnorr(public_key: &[u8], message: &[u8], signature: &[u8]) -> Result<Value, Error> {
1906    use secp256k1::{schnorr::Signature, Message, Secp256k1, XOnlyPublicKey};
1907
1908    let secp = Secp256k1::verification_only();
1909
1910    let public_key = XOnlyPublicKey::from_slice(public_key)?;
1911
1912    let signature = Signature::from_slice(signature)?;
1913
1914    let message = Message::from_slice(message)?;
1915
1916    let valid = secp.verify_schnorr(&signature, &message, &public_key);
1917
1918    Ok(Value::Con(Constant::Bool(valid.is_ok()).into()))
1919}
1920
1921#[cfg(target_family = "wasm")]
1922fn verify_ecdsa(public_key: &[u8], message: &[u8], signature: &[u8]) -> Result<Value, Error> {
1923    use k256::ecdsa::{self, signature::hazmat::PrehashVerifier};
1924
1925    let verifying_key = ecdsa::VerifyingKey::try_from(public_key)?;
1926
1927    let signature = ecdsa::Signature::try_from(signature)?;
1928
1929    let valid = verifying_key.verify_prehash(message, &signature);
1930
1931    Ok(Value::Con(Constant::Bool(valid.is_ok()).into()))
1932}
1933
1934#[cfg(target_family = "wasm")]
1935fn verify_schnorr(public_key: &[u8], message: &[u8], signature: &[u8]) -> Result<Value, Error> {
1936    use k256::schnorr::{self, signature::hazmat::PrehashVerifier};
1937
1938    let verifying_key = schnorr::VerifyingKey::from_bytes(public_key)?;
1939
1940    let signature = schnorr::Signature::try_from(signature)?;
1941
1942    let valid = verifying_key.verify_prehash(message, &signature);
1943
1944    Ok(Value::Con(Constant::Bool(valid.is_ok()).into()))
1945}
1946
1947#[cfg(test)]
1948mod tests {
1949    use super::{convert_constr_to_tag, convert_tag_to_constr};
1950
1951    #[test]
1952    fn compact_tag_range() {
1953        assert_eq!(convert_constr_to_tag(0), Some(121));
1954        assert_eq!(convert_constr_to_tag(1), Some(122));
1955        assert_eq!(convert_constr_to_tag(6), Some(127));
1956        assert_ne!(convert_constr_to_tag(7), Some(128)); // This is not allowed
1957    }
1958    #[test]
1959    fn compact_tag_mid_range() {
1960        assert_eq!(convert_constr_to_tag(7), Some(1280));
1961        assert_eq!(convert_constr_to_tag(8), Some(1281));
1962        assert_eq!(convert_constr_to_tag(100), Some(1373));
1963        assert_eq!(convert_constr_to_tag(127), Some(1400));
1964        assert_ne!(convert_constr_to_tag(128), Some(1401)); // This is not allowed
1965    }
1966
1967    #[test]
1968    fn any_range() {
1969        assert_eq!(convert_constr_to_tag(128), None);
1970        assert_eq!(
1971            convert_constr_to_tag(128).map_or(Some(128), |_| None),
1972            Some(128)
1973        );
1974        assert_eq!(convert_constr_to_tag(123124125125), None);
1975        assert_eq!(convert_constr_to_tag(1).map_or(Some(1), |_| None), None); // This is a compact tag
1976    }
1977
1978    #[test]
1979    fn to_compact_tag() {
1980        assert_eq!(convert_tag_to_constr(121), Some(0));
1981        assert_eq!(convert_tag_to_constr(122), Some(1));
1982        assert_eq!(convert_tag_to_constr(127), Some(6));
1983        assert_eq!(convert_tag_to_constr(128), None); // This can never happen actually. Pallas sorts that out already during deserialization.
1984    }
1985    #[test]
1986    fn to_compact_tag_mid() {
1987        assert_eq!(convert_tag_to_constr(1280), Some(7));
1988        assert_eq!(convert_tag_to_constr(1281), Some(8));
1989        assert_eq!(convert_tag_to_constr(1400), Some(127));
1990        assert_eq!(convert_tag_to_constr(1401), None); // This can never happen actually. Pallas sorts that out already during deserialization.
1991    }
1992
1993    #[test]
1994    fn to_any_tag() {
1995        assert_eq!(convert_tag_to_constr(102), None);
1996    }
1997}