pryvx 2.5.0__tar.gz → 2.6.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pryvx
3
- Version: 2.5.0
3
+ Version: 2.6.0
4
4
  Summary: A comprehensive package for privacy-enhancing technologies
5
5
  Home-page: UNKNOWN
6
6
  Author: PryvX (Jayesh Kenaudekar)
@@ -2,4 +2,5 @@ from .psi import OPRF
2
2
  from .phe import PHE
3
3
  from .smpc import SMPC
4
4
  from .gdp import GDP
5
- from .ldp import LDP
5
+ from .ldp import LDP
6
+ from .rtphe import RTPHE
@@ -0,0 +1,147 @@
1
+ import random
2
+ from sympy import mod_inverse, isprime, nextprime
3
+ import math
4
+ import hashlib
5
+ import secrets
6
+
7
+ def prove_dec(pub, c, m, r):
8
+ """
9
+ Non‑interactive PPK:
10
+ a = g^u · w^n
11
+ e = H(c || a) (Fiat–Shamir)
12
+ z = u + e·m (mod n)
13
+ w' = w · r^e (mod n)
14
+ π = (a, z, w')
15
+ """
16
+ n, g = pub ; n2 = n*n
17
+ u = secrets.randbelow(n)
18
+ w = secrets.randbelow(n)
19
+ a = (pow(g, u, n2) * pow(w, n, n2)) % n2
20
+
21
+ e = int.from_bytes(
22
+ hashlib.sha256(str(c).encode() + str(a).encode()).digest(),
23
+ 'big') % n
24
+
25
+ z = (u + e * m) % n
26
+ w_ = (w * pow(r, e, n)) % n
27
+ return a, z, w_
28
+
29
+ def verify_dec(pub, c, m, proof):
30
+ n, g = pub ; n2 = n*n
31
+ a, z, w_ = proof
32
+ e = int.from_bytes(
33
+ hashlib.sha256(str(c).encode() + str(a).encode()).digest(),
34
+ 'big') % n
35
+ left = (pow(g, z, n2) * pow(w_, n, n2)) % n2
36
+ right = (pow(c, e, n2) * a) % n2
37
+ return left == right
38
+
39
+ def generate_prime(bits=512):
40
+ while True:
41
+ p = nextprime(random.getrandbits(bits))
42
+ if isprime(p):
43
+ return p
44
+
45
+ def lcm(a, b):
46
+ return abs(a * b) // math.gcd(a, b)
47
+
48
+ class RTPHE:
49
+
50
+ @staticmethod
51
+ def keygen(bits=64):
52
+ p = generate_prime(bits)
53
+ q = generate_prime(bits)
54
+ n = p * q
55
+ lambda_n = lcm(p - 1, q - 1)
56
+ g = n + 1
57
+ mu = mod_inverse((pow(g, lambda_n, n * n) - 1) // n, n)
58
+ public_key = (n, g)
59
+ private_key = (lambda_n, mu)
60
+ return public_key, private_key
61
+
62
+ @staticmethod
63
+ def encrypt(public_key, plaintext, r=None):
64
+ n, g = public_key
65
+ if r is None:
66
+ r = random.randint(1, n - 1)
67
+ while math.gcd(r, n) != 1:
68
+ r = random.randint(1, n - 1)
69
+ n2 = n * n
70
+ c = (pow(g, plaintext, n2) * pow(r, n, n2)) % n2
71
+ return c
72
+
73
+ @staticmethod
74
+ def encrypt_with_randomness(public_key, plaintext):
75
+ r = random.randint(1, public_key[0] - 1)
76
+ while math.gcd(r, public_key[0]) != 1:
77
+ r = random.randint(1, public_key[0] - 1)
78
+ c = RTPHE.encrypt(public_key, plaintext, r)
79
+ return c, r
80
+
81
+ @staticmethod
82
+ def decrypt(public_key, private_key, ciphertext):
83
+ n, g = public_key
84
+ lambda_n, mu = private_key
85
+ n2 = n * n
86
+ x = pow(ciphertext, lambda_n, n2)
87
+ Lx = (x - 1) // n
88
+ plaintext = (Lx * mu) % n
89
+
90
+ if plaintext > n // 2:
91
+ plaintext -= n
92
+ return plaintext
93
+
94
+ @staticmethod
95
+ def homomorphic_add(c1, c2, public_key):
96
+ n2 = public_key[0] ** 2
97
+ return (c1 * c2) % n2
98
+
99
+ @staticmethod
100
+ def homomorphic_add_plaintext(ciphertext, plaintext, public_key):
101
+ n, g = public_key
102
+ n2 = n * n
103
+ c_plain = pow(g, plaintext, n2)
104
+ return (ciphertext * c_plain) % n2
105
+
106
+ @staticmethod
107
+ def homomorphic_sub(c1, c2, public_key):
108
+ n2 = public_key[0] ** 2
109
+ c2_inv = mod_inverse(c2, n2)
110
+ return (c1 * c2_inv) % n2
111
+
112
+ @staticmethod
113
+ def homomorphic_sub_plaintext(ciphertext, plaintext, public_key):
114
+ n, g = public_key
115
+ n2 = n * n
116
+ c_plain_neg = pow(g, -plaintext % n, n2)
117
+ return (ciphertext * c_plain_neg) % n2
118
+
119
+ @staticmethod
120
+ def homomorphic_scalar_mult(ciphertext, scalar, public_key):
121
+ n2 = public_key[0] ** 2
122
+ return pow(ciphertext, scalar, n2)
123
+
124
+ @staticmethod
125
+ def homomorphic_div(ciphertext, divisor, public_key):
126
+ n = public_key[0]
127
+ divisor_inv = mod_inverse(divisor, n)
128
+ return RTPHE.homomorphic_scalar_mult(ciphertext, divisor_inv, public_key)
129
+
130
+ # ========== 🔐 RANDOMNESS TRACKING HELPERS ==========
131
+
132
+ @staticmethod
133
+ def track_randomness_add(r1, r2, n):
134
+ return (r1 * r2) % n
135
+
136
+ @staticmethod
137
+ def track_randomness_sub(r1, r2, n):
138
+ return (r1 * mod_inverse(r2, n)) % n
139
+
140
+ @staticmethod
141
+ def track_randomness_scalar_mult(r, scalar, n):
142
+ return pow(r, scalar, n)
143
+
144
+ @staticmethod
145
+ def track_randomness_scalar_div(r, divisor, n):
146
+ divisor_inv = mod_inverse(divisor, n)
147
+ return pow(r, divisor_inv, n)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pryvx
3
- Version: 2.5.0
3
+ Version: 2.6.0
4
4
  Summary: A comprehensive package for privacy-enhancing technologies
5
5
  Home-page: UNKNOWN
6
6
  Author: PryvX (Jayesh Kenaudekar)
@@ -11,6 +11,7 @@ pryvx/phe.py
11
11
  pryvx/pryvx_pb2.py
12
12
  pryvx/pryvx_pb2_grpc.py
13
13
  pryvx/psi.py
14
+ pryvx/rtphe.py
14
15
  pryvx/smpc.py
15
16
  pryvx.egg-info/PKG-INFO
16
17
  pryvx.egg-info/SOURCES.txt
@@ -1,6 +1,6 @@
1
1
  from setuptools import setup, find_packages
2
2
 
3
- VERSION = '2.5.0'
3
+ VERSION = '2.6.0'
4
4
 
5
5
 
6
6
  # Setting up
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes