def prov(R: RationalGenerator, H, tau, sigma, a) -> Tuple: r = randfield(R.F) s = randfield(R.F) alpha, beta, delta, gamma, x = tau m = len(a) A = alpha + reduce(add, [a[i] * (R.U[i](x)) for i in range(0, m)]) + r * delta B = beta + reduce(add, [a[i] * (R.V[i](x)) for i in range(0, m)]) + s * delta C = (reduce(add, [a[i]*(beta * (R.U[i](x)) + alpha * (R.V[i](x)) + R.W[i](x)) for i in range(R.l, m)]) + H(x) * R.T(x)) / delta \ + (A * s + B * r - r * s * delta) return (R.g @ A, R.g @ C, R.h @ B)
def setup(R: RationalGenerator, m: int) -> Tuple[Iterable, Tuple]: tau = alpha, beta, delta, gamma, x = \ randfield(R.F), randfield(R.F), randfield( R.F), randfield(R.F), randfield(R.F) n = R.U[0].degree sigma_1 = [alpha, beta, delta] + \ [x ** i for i in range(0, n)] + \ [(R.U[i](x) * beta + R.V[i](x) * alpha + R.W[i](x)) / gamma for i in range(0, R.l)] + \ [(R.U[i](x) * beta + R.V[i](x) * alpha + R.W[i](x)) / delta for i in range(R.l, m)] + \ [(x ** i * R.T(x)) / delta for i in range(0, n-1)] sigma_2 = [beta, gamma, delta] + \ [x**i for i in (0, n)] sigma = ([R.g @ s for s in sigma_1], [R.h @ s for s in sigma_2]) return tau, sigma
def setup(self, secret, k, n, poly_params=[]): if not poly_params: poly_params = [randfield(self.F) for _ in range(k - 1)] self.poly_proofs = [self.G ** p for p in [secret] + poly_params] return super().setup(secret, k, n, poly_params)
def join(self, x=None): assert x != 0 if not x: x = randfield(self.F) if not hasattr(self, 'f'): raise Exception("Needs to encrypt first") return (self.F(x), self.f(x))
def __init__(self, P, Q, s=1, strict=False): ''' if strict == True: use Carmichael Number else: use Euler Number ''' N = P * Q # Lam = lcm(P-1, Q-1) G = field(N**s, "G") # n ** s == n if s = 1 # multiplicative group MG = field(N**(s + 1), "N^{s+1}") # n ** (s +1 ) == n2 in pailer case H = field(N, "H") # https://crypto.stackexchange.com/questions/29591/lcm-versus-phi-in-rsa if strict: LG = field(rsa_lambda(P, Q), "PhiGroup") else: LG = field(rsa_phi(P, Q), "PhiGroup") j = generate_prime(length(P)) assert gcd(j, N) == 1 x = randfield(H) g = MG((MG(1 + N)**j) * x) d = crt(a_list=[0, 1], n_list=[LG.P, G.P]) assert d % G.P == 1 assert d % LG.P == 0 self.s = s self.privkey = d self.N = N self.G = g self.pubkey = (N, g)
def encrypt(cls, m, pub): g, h = pub y = randfield(field(g.N)).value m_ = map_to_curve(m) s = h**y c1 = g**y c2 = s * m_ return (c1, c2)
def commit(self, m, ak): pk, vk, h = self.key com = PedersonCommitment(H, G, pk, ak) # (𝑐,𝑑)=𝐻𝑆𝑐𝑜𝑚𝑚𝑖𝑡𝑝𝑘(𝑎𝑘) c, d = com.C, com.D # α=ℎ(𝑐) alpha = CF(to_sha256int(gen_address(c))) # Now we simulate a proof of knowledge of a signature on 𝛼 with challenge 𝑚 S = PedersonCommitment(H, G, vk, alpha) r1, r2 = randfield(vk.functor), randfield(vk.functor) a = S.commit(r1, r2) z = S.challenge(m) self.S = S # Finally, we compute 𝑚𝑎𝑐=𝑀𝐴𝐶𝑎𝑘(𝑎). mac = hmac.new(str(ak.value).encode(), encode_pubkey(a).encode()).hexdigest() self.c = (c, a, mac) self.d = (m, d, z)
def encrypt(cls, m, pub, s=1, r=None): N, G = pub if hasattr(m, "value"): m = m.value if not r: r = randfield(G.functor) else: r = G.functor(r) return G**m * r**(N**s)
def test_ssss(): F = field(P) s = SSSS(F) k = random.randint(1, 100) n = k * 3 secret = randfield(F) s.setup(secret, k, n) assert s.decrypt([s.join() for _ in range(k - 1)]) != secret assert s.decrypt([s.join() for _ in range(k + 1)]) == secret assert s.decrypt([s.join() for _ in range(k + 2)]) == secret
def setup(self, secret, k, n, poly_params=[]): ''' k: threshold ''' self.k = k self.n = n if not poly_params: poly_params = [randfield(self.F) for _ in range(k - 1)] self.f = lambda x: self.F(secret) + reduce( add, [poly_params[i] * (x**(i + 1)) for i in range(k - 1)]) return self
def __init__(self, P, Q): assert gcd(P * Q, (P - 1) * (Q - 1)) == 1 N = P * Q Lam = lcm(P - 1, Q - 1) F = field(N) DF = field(N**2) G = randfield(DF) M = ~F(L(pow(G, Lam).value, N)) self.N = N self.G = G self.privkey = Lam self.pubkey = (self.N, self.G)
def __init__(self, A=Iterable, B=Iterable, C=Iterable): # t(x) = \prod_{q=1}^n (x - r_q) self.field = A[0][0].type # self.Z = lambda x: reduce(mul, # [(x - randfield(field)) # for i in range(1, len(A)+1)]) (self.A, self.B, self.C) = (vec2polyring(i) for i in [A, B, C]) Z = PolyRing([self.field.one()]) for i in range(1, self.A[0].degree - 1): Z = Z * PolyRing(-randfield(self.field), self.field.one()) self.Z = Z
def proof(x: CF): x = CF(x) r = randfield(CF) G = Curve.G u = G @ r h = G @ x c = CF( int( sha256( str(G.x.value).encode() + str(G.y.value).encode() + str(h.x.value).encode() + str(h.y.value).encode() + str(u.x.value).encode() + str(u.y.value).encode()).hexdigest(), 16)) z = r + c * x return (u, h, c, z)
def additive_share(secret, F, n): shares = [randfield(F) for _ in range(n - 1)] shares += [(F(secret) - reduce(add, shares))] return shares
def __init__(self, field, r): self.field = field self.c = [field(0)] + [randfield(field) for i in range(1, r)] self.r = r
def keygen(F): pk = randfield(F) vk = F(to_sha256int(str(pk.value))) h = gen_address return (pk, vk, h)