Skip to content

Commit 9ca689d

Browse files
committed
add zq pow
1 parent 993ab31 commit 9ca689d

1 file changed

Lines changed: 34 additions & 3 deletions

File tree

src/zq.rs

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,22 @@ impl<const Q: u64> Zq<Q> {
2929
Zq { value: 1 }
3030
}
3131

32+
/// Modular exponentiation: self^exp mod Q (square-and-multiply).
33+
pub fn pow(self, exp: u64) -> Self {
34+
if exp == 0 {
35+
Self::one()
36+
} else {
37+
// f(x) = g^x
38+
// = g*f(x/2)**2 if x \in odd else f(x/2)**2
39+
let half = self.pow(exp / 2);
40+
if exp.is_multiple_of(2) {
41+
half * half
42+
} else {
43+
self * (half * half)
44+
}
45+
}
46+
}
47+
3248
/// Multiplicative inverse of v, i.e. s = v^{-1} s.t. v*s = 1 mod q
3349
pub fn inv(self) -> Self {
3450
assert!(self.value != 0, "cannout invert zero");
@@ -41,17 +57,14 @@ impl<const Q: u64> Zq<Q> {
4157
let mut t = [0, 1] as [i128; 2];
4258

4359
// gcd: (a, b) = (b, r) until b = 1
44-
let mut i = 0;
4560
while b > 1 {
46-
println!("round {i}: a={a}, b={b}, s={s:?}, t={t:?}");
4761
// a > b, b times a factor k and a minus bk
4862
let q = a / b;
4963
let r = a - q * b;
5064
let r_mplr = [s[0] - q * t[0], s[1] - q * t[1]];
5165
// (a, b) = (b, r)
5266
(a, b) = (b, r);
5367
(s, t) = (t, r_mplr);
54-
i += 1;
5568
}
5669

5770
// when b = 1, t[1] is v's multiplier, i.e. v^{-1}
@@ -169,6 +182,24 @@ mod tests {
169182
assert_eq!(F::one().value(), 1);
170183
}
171184

185+
#[test]
186+
fn test_pow() {
187+
// 3^0 = 1
188+
assert_eq!(F::new(3).pow(0), F::one());
189+
// 3^1 = 3
190+
assert_eq!(F::new(3).pow(1), F::new(3));
191+
// 3^2 = 9
192+
assert_eq!(F::new(3).pow(2), F::new(9));
193+
// 3^3 = 27 mod 17 = 10
194+
assert_eq!(F::new(3).pow(3), F::new(10));
195+
// Fermat's little theorem: a^(q-1) = 1 for a != 0
196+
for i in 1..Q {
197+
assert_eq!(F::new(i).pow(Q - 1), F::one());
198+
}
199+
// 0^n = 0 for n > 0
200+
assert_eq!(F::new(0).pow(5), F::zero());
201+
}
202+
172203
#[test]
173204
fn test_inv() {
174205
for i in 1..Q {

0 commit comments

Comments
 (0)