-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathutils.py
More file actions
56 lines (42 loc) · 1.34 KB
/
utils.py
File metadata and controls
56 lines (42 loc) · 1.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#!/usr/bin/python3
def bit_count(num: int) -> int:
"""
Computes bit length of an integer, same as len(bin(num)[2:])
"""
cnt = 0
num_ = num
while num > 0:
cnt += 1
num >>= 1
assert cnt == len(bin(num_)[2:])
return cnt
def modulo(a: int, b: int) -> int:
"""
Computes canonical representation of field element `a`, see https://paulmillr.com/posts/noble-secp256k1-fast-ecc/#public-keys
"""
res = a % b
if res >= 0:
return res
else:
return b + res
def mul_inv(num: int, mod: int) -> int:
"""
Computes multiplicative inverse of prime field element a | a * a_inv = 1,
using extended GCD algorithm, see https://aszepieniec.github.io/stark-anatomy/basic-tools
"""
if num == 0 or mod <= 0:
raise Exception("can't invert multiplicative identity 0")
old_r, r = (mod, modulo(num, mod))
old_s, s = (1, 0)
old_t, t = (0, 1)
while r != 0:
quotient = old_r // r
old_r, r = (r, old_r - quotient * r)
old_s, s = (s, old_s - quotient * s)
old_t, t = (t, old_t - quotient * t)
if old_r != 1:
raise Exception("failed to find multiplicative inverse")
# (old_s, old_t, old_r) | a, b, g of `ax + by = g`
return modulo(old_s, mod)
if __name__ == "__main__":
print("Use `utils` as library module")