Repository: ergoplatform/sigma-rust (language: rust)

Issue:
[300 SigmaUSD] Sigma protocol implementation for AtLeast
Implemented in #377:
- ~~evaluation(exept `Cthreshold::reduce`);~~
- ~~prover(exept Gf2_192*);~~
- ~~verifier;~~

Todo:
- #473
- ~~implement `Cthreshold::reduce` [Scala reference impl](https://github.com/ScorexFoundation/sigmastate-interpreter/blob/262a14d17ae3090fa97d1de1effd0b338562e4db/sigmastate/src/main/scala/sigmastate/trees.scala#L467-L518);~~ #482
- ~~test verifier with proofs from mainnet/sigmastate [Scala test vector](https://github.com/ScorexFoundation/sigmastate-interpreter/blob/262a14d17ae3090fa97d1de1effd0b338562e4db/sigmastate/src/test/scala/sigmastate/crypto/SigningSpecification.scala#L119-L135);~~ #535 
- test prover with verifier by generating arbitrary `AtLeast` IR node proving it and then passing through the verifier (see `verifier::tests` for examples);


Discussion / hints:
I'm starting on this one 👍 
> I'm starting on this one 👍

Great! Please be aware that #473 is needed for testing prover/verifier. 
@ross-weir Hey! #473 is implemented and merged. Everything is in place to finish this task.
> @ross-weir Hey! #473 is implemented and merged. Everything is in place to finish this task.

Thanks, restarting this one

Fix patch:
diff --git a/ergotree-interpreter/src/sigma_protocol/verifier.rs b/ergotree-interpreter/src/sigma_protocol/verifier.rs
index a9057dc65..5e2ea31de 100644
--- a/ergotree-interpreter/src/sigma_protocol/verifier.rs
+++ b/ergotree-interpreter/src/sigma_protocol/verifier.rs
@@ -180,9 +180,14 @@ mod tests {
     use crate::sigma_protocol::prover::{Prover, TestProver};
 
     use super::*;
+    use ergotree_ir::mir::atleast::Atleast;
+    use ergotree_ir::mir::constant::{Constant, Literal};
     use ergotree_ir::mir::expr::Expr;
     use ergotree_ir::mir::sigma_and::SigmaAnd;
     use ergotree_ir::mir::sigma_or::SigmaOr;
+    use ergotree_ir::mir::value::CollKind;
+    use ergotree_ir::sigma_protocol::sigma_boolean::SigmaProp;
+    use ergotree_ir::types::stype::SType;
     use proptest::collection::vec;
     use proptest::prelude::*;
     use sigma_test_util::force_any_val;
@@ -413,5 +418,47 @@ mod tests {
             }
         }
 
+        #[test]
+        fn test_prover_verifier_atleast(secret1 in any::<DlogProverInput>(),
+                                            secret2 in any::<DlogProverInput>(),
+                                             secret3 in any::<DlogProverInput>(),
+                                             message in vec(any::<u8>(), 100..200)) {
+            let bound = Expr::Const(2i32.into());
+            let inputs = Literal::Coll(
+                CollKind::from_vec(
+                    SType::SSigmaProp,
+                    vec![
+                        SigmaProp::from(secret1.public_image()).into(),
+                        SigmaProp::from(secret2.public_image()).into(),
+                        SigmaProp::from(secret3.public_image()).into(),
+                    ],
+                )
+                .unwrap(),
+            );
+            let input = Constant {
+                tpe: SType::SColl(SType::SSigmaProp.into()),
+                v: inputs,
+            }
+            .into();
+            let expr: Expr = Atleast::new(bound, input).unwrap().into();
+            let tree = ErgoTree::try_from(expr).unwrap();
+            let prover = TestProver {
+                secrets: vec![secret1.into(), secret3.into()],
+            };
+
+            let res = prover.prove(&tree,
+                &Env::empty(),
+                Rc::new(force_any_val::<Context>()),
+                message.as_slice(),
+                &HintsBag::empty());
+            let proof = res.unwrap().proof;
+            let verifier = TestVerifier;
+            let ver_res = verifier.verify(&tree,
+                                            &Env::empty(),
+                                            Rc::new(force_any_val::<Context>()),
+                                            proof,
+                                            message.as_slice());
+            prop_assert_eq!(ver_res.unwrap().result, true)
+        }
     }
 }


Test patch: