summaryrefslogtreecommitdiff
path: root/sem2/src/mpn.rs
diff options
context:
space:
mode:
authorAndrew Guschin <guschin.drew@gmail.com>2023-04-03 21:37:09 +0400
committerAndrew Guschin <guschin.drew@gmail.com>2023-04-03 21:37:09 +0400
commitc2f76a4a4c67e2cc178eb9d91b5117233edf763d (patch)
tree863722d0e27efdfffc49c62954c4baec3bf00ca4 /sem2/src/mpn.rs
parent22f0b3f854c23904e84a305df84872ed7c472d14 (diff)
parent5b09f26c7cf95433528f428e56468b8ac5a4f013 (diff)
Merge branch 'powmod'
Diffstat (limited to 'sem2/src/mpn.rs')
-rw-r--r--sem2/src/mpn.rs24
1 files changed, 24 insertions, 0 deletions
diff --git a/sem2/src/mpn.rs b/sem2/src/mpn.rs
index 1709136..91d3ff8 100644
--- a/sem2/src/mpn.rs
+++ b/sem2/src/mpn.rs
@@ -349,6 +349,30 @@ impl Rem for Number {
}
}
+impl Number {
+ pub fn pow_mod(&self, power: &Self, modulo: &Self) -> Result<Self, String> {
+ if modulo.is_zero() {
+ return Err("Модуль должен быть отличен от нуля".to_string());
+ }
+ let one: Number = Number::from_digits(&vec![1], self.radix).unwrap();
+ if power.is_zero() {
+ return Ok(one.clone() % modulo.clone());
+ }
+ let two: Number = Number::from_digits(&vec![2], self.radix).unwrap();
+ let mut acc = one.clone();
+ let mut p = power.clone();
+ let mut base = self.clone();
+ while !p.is_zero() {
+ if p.clone() % two.clone() == one.clone() {
+ acc = (acc * base.clone()) % modulo.clone();
+ }
+ p = p / two.clone();
+ base = (base.clone() * base) % modulo.clone();
+ }
+ return Ok(acc);
+ }
+}
+
impl PartialEq for Number {
fn eq(&self, other: &Self) -> bool {
if self.len() != other.len() {