@@ -3,6 +3,7 @@ use alloc::boxed::Box;
3
3
use alloc:: { string:: ToString , sync:: Arc } ;
4
4
5
5
use ergotree_ir:: serialization:: sigma_byte_writer:: SigmaByteWrite ;
6
+ use ergotree_ir:: unsignedbigint256:: UnsignedBigInt ;
6
7
use ergotree_ir:: {
7
8
mir:: {
8
9
constant:: { Constant , TryExtractInto } ,
@@ -17,7 +18,7 @@ use ergotree_ir::{
17
18
18
19
use super :: EvalFn ;
19
20
use crate :: eval:: Vec ;
20
- use ergo_chain_types:: ec_point:: generator;
21
+ use ergo_chain_types:: { autolykos_pow_scheme :: AutolykosPowScheme , ec_point:: generator} ;
21
22
use ergotree_ir:: bigint256:: BigInt256 ;
22
23
use ergotree_ir:: types:: stype:: SType ;
23
24
@@ -219,6 +220,42 @@ pub(crate) static SGLOBAL_NONE_EVAL_FN: EvalFn = |_mc, _env, _ctx, obj, _args| {
219
220
Ok ( Value :: Opt ( None ) )
220
221
} ;
221
222
223
+ pub ( crate ) static POW_HIT_EVAL_FN : EvalFn = |_mc, _env, _ctx, _obj, mut args| {
224
+ // Pop arguments to avoid cloning
225
+ let big_n: u32 = args
226
+ . pop ( )
227
+ . ok_or_else ( || EvalError :: NotFound ( "powHit: missing N" . into ( ) ) ) ?
228
+ . try_extract_into :: < i32 > ( ) ?
229
+ . try_into ( )
230
+ . map_err ( |_| EvalError :: Misc ( "N out of bounds" . into ( ) ) ) ?;
231
+ let h = args
232
+ . pop ( )
233
+ . ok_or_else ( || EvalError :: NotFound ( "powHit: missing h" . into ( ) ) ) ?
234
+ . try_extract_into :: < Vec < u8 > > ( ) ?;
235
+ let nonce = args
236
+ . pop ( )
237
+ . ok_or_else ( || EvalError :: NotFound ( "powHit: missing nonce" . into ( ) ) ) ?
238
+ . try_extract_into :: < Vec < u8 > > ( ) ?;
239
+ let msg = args
240
+ . pop ( )
241
+ . ok_or_else ( || EvalError :: NotFound ( "powHit: missing msg" . into ( ) ) ) ?
242
+ . try_extract_into :: < Vec < u8 > > ( ) ?;
243
+ let k = args
244
+ . pop ( )
245
+ . ok_or_else ( || EvalError :: NotFound ( "powHit: missing msg" . into ( ) ) ) ?
246
+ . try_extract_into :: < i32 > ( ) ?;
247
+ Ok ( UnsignedBigInt :: try_from (
248
+ AutolykosPowScheme :: new (
249
+ k. try_into ( )
250
+ . map_err ( |_| EvalError :: Misc ( "k out of bounds" . into ( ) ) ) ?,
251
+ big_n,
252
+ ) ?
253
+ . pow_hit_message_v2 ( & msg, & nonce, & h, big_n) ?,
254
+ )
255
+ . map_err ( EvalError :: Misc ) ?
256
+ . into ( ) )
257
+ } ;
258
+
222
259
#[ allow( clippy:: unwrap_used) ]
223
260
#[ cfg( test) ]
224
261
#[ cfg( feature = "arbitrary" ) ]
@@ -238,11 +275,12 @@ mod tests {
238
275
use ergotree_ir:: types:: sgroup_elem:: GET_ENCODED_METHOD ;
239
276
use ergotree_ir:: types:: stype_param:: STypeVar ;
240
277
use ergotree_ir:: unsignedbigint256:: UnsignedBigInt ;
278
+ use num_traits:: Num ;
241
279
use proptest:: proptest;
242
280
243
281
use crate :: eval:: tests:: { eval_out, eval_out_wo_ctx, try_eval_out_with_version} ;
244
282
use ergotree_ir:: chain:: context:: Context ;
245
- use ergotree_ir:: types:: sglobal:: { self , DESERIALIZE_METHOD , SERIALIZE_METHOD } ;
283
+ use ergotree_ir:: types:: sglobal:: { self , DESERIALIZE_METHOD , POW_HIT_METHOD , SERIALIZE_METHOD } ;
246
284
use ergotree_ir:: types:: stype:: SType ;
247
285
use sigma_test_util:: force_any_val;
248
286
@@ -315,6 +353,30 @@ mod tests {
315
353
}
316
354
}
317
355
356
+ fn pow_hit ( k : u32 , msg : & [ u8 ] , nonce : & [ u8 ] , h : & [ u8 ] , big_n : u32 ) -> UnsignedBigInt {
357
+ let expr: Expr = MethodCall :: new (
358
+ Expr :: Global ,
359
+ POW_HIT_METHOD . clone ( ) ,
360
+ vec ! [
361
+ Constant :: from( k as i32 ) . into( ) ,
362
+ Constant :: from( msg. to_owned( ) ) . into( ) ,
363
+ Constant :: from( nonce. to_owned( ) ) . into( ) ,
364
+ Constant :: from( h. to_owned( ) ) . into( ) ,
365
+ Constant :: from( big_n as i32 ) . into( ) ,
366
+ ] ,
367
+ )
368
+ . unwrap ( )
369
+ . into ( ) ;
370
+ let ctx = force_any_val :: < Context > ( ) ;
371
+ assert ! (
372
+ ( 0 ..ErgoTreeVersion :: V3 . into( ) ) . all( |version| try_eval_out_with_version:: <
373
+ UnsignedBigInt ,
374
+ >( & expr, & ctx, version, 3 )
375
+ . is_err( ) )
376
+ ) ;
377
+ try_eval_out_with_version ( & expr, & ctx, ErgoTreeVersion :: V3 . into ( ) , 3 ) . unwrap ( )
378
+ }
379
+
318
380
#[ test]
319
381
fn eval_group_generator ( ) {
320
382
let expr: Expr = PropertyCall :: new ( Expr :: Global , sglobal:: GROUP_GENERATOR_METHOD . clone ( ) )
@@ -558,6 +620,21 @@ mod tests {
558
620
) ;
559
621
}
560
622
623
+ #[ test]
624
+ fn powhit_eval ( ) {
625
+ let msg = base16:: decode ( "0a101b8c6a4f2e" ) . unwrap ( ) ;
626
+ let nonce = base16:: decode ( "000000000000002c" ) . unwrap ( ) ;
627
+ let hbs = base16:: decode ( "00000000" ) . unwrap ( ) ;
628
+ assert_eq ! (
629
+ pow_hit( 32 , & msg, & nonce, & hbs, 1024 * 1024 ) ,
630
+ UnsignedBigInt :: from_str_radix(
631
+ "326674862673836209462483453386286740270338859283019276168539876024851191344" ,
632
+ 10
633
+ )
634
+ . unwrap( )
635
+ ) ;
636
+ }
637
+
561
638
proptest ! {
562
639
#[ test]
563
640
fn serialize_sigmaprop_eq_prop_bytes( sigma_prop: SigmaProp ) {
0 commit comments