2018-05-06 21:32:42 +00:00
|
|
|
|
from umbral.curvebn import CurveBN
|
|
|
|
|
from umbral.config import default_params
|
|
|
|
|
from umbral.params import UmbralParameters
|
|
|
|
|
|
|
|
|
|
|
2018-05-06 21:33:04 +00:00
|
|
|
|
def prove_cfrag_correctness(cfrag: "CapsuleFrag",
|
|
|
|
|
kfrag: "KFrag",
|
|
|
|
|
capsule: "Capsule",
|
|
|
|
|
metadata: bytes=None,
|
|
|
|
|
params: UmbralParameters=None
|
|
|
|
|
) -> "CorrectnessProof":
|
|
|
|
|
params = params if params is not None else default_params()
|
|
|
|
|
|
|
|
|
|
rk = kfrag._bn_key
|
|
|
|
|
t = CurveBN.gen_rand(params.curve)
|
|
|
|
|
####
|
2018-05-06 21:33:23 +00:00
|
|
|
|
## Here are the formulaic constituents shared with `assess_cfrag_correctness`.
|
2018-05-06 21:33:04 +00:00
|
|
|
|
####
|
|
|
|
|
e = capsule._point_e
|
|
|
|
|
v = capsule._point_v
|
|
|
|
|
|
|
|
|
|
e1 = cfrag._point_e1
|
|
|
|
|
v1 = cfrag._point_v1
|
|
|
|
|
|
|
|
|
|
u = params.u
|
|
|
|
|
u1 = kfrag._point_commitment
|
|
|
|
|
|
|
|
|
|
e2 = t * e
|
|
|
|
|
v2 = t * v
|
|
|
|
|
u2 = t * u
|
|
|
|
|
|
2018-05-08 23:57:52 +00:00
|
|
|
|
hash_input = (e, e1, e2, v, v1, v2, u, u1, u2)
|
2018-05-06 21:33:04 +00:00
|
|
|
|
if metadata is not None:
|
2018-05-08 23:57:52 +00:00
|
|
|
|
hash_input += (metadata,)
|
2018-05-06 21:33:04 +00:00
|
|
|
|
h = CurveBN.hash(*hash_input, params=params)
|
|
|
|
|
|
|
|
|
|
z1 = kfrag._bn_sig1
|
|
|
|
|
z2 = kfrag._bn_sig2
|
|
|
|
|
z3 = t + h * rk
|
|
|
|
|
########
|
|
|
|
|
|
|
|
|
|
cfrag.attach_proof(e2, v2, u1, u2, z1, z2, z3, metadata)
|
|
|
|
|
|
|
|
|
|
# Check correctness of original ciphertext (check nº 2) at the end
|
|
|
|
|
# to avoid timing oracles
|
|
|
|
|
if not capsule.verify(params):
|
|
|
|
|
raise capsule.NotValid("Capsule verification failed.")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def assess_cfrag_correctness(cfrag,
|
|
|
|
|
capsule: "Capsule",
|
|
|
|
|
pubkey_a_point,
|
|
|
|
|
pubkey_b_point,
|
|
|
|
|
params: UmbralParameters = None):
|
|
|
|
|
params = params if params is not None else default_params()
|
|
|
|
|
|
|
|
|
|
####
|
|
|
|
|
## Here are the formulaic constituents shared with `prove_cfrag_correctness`.
|
|
|
|
|
####
|
|
|
|
|
e = capsule._point_e
|
|
|
|
|
v = capsule._point_v
|
|
|
|
|
|
|
|
|
|
e1 = cfrag._point_e1
|
|
|
|
|
v1 = cfrag._point_v1
|
|
|
|
|
|
|
|
|
|
u = params.u
|
|
|
|
|
u1 = cfrag.proof._point_kfrag_commitment
|
|
|
|
|
|
|
|
|
|
e2 = cfrag.proof._point_e2
|
|
|
|
|
v2 = cfrag.proof._point_v2
|
|
|
|
|
u2 = cfrag.proof._point_kfrag_pok
|
|
|
|
|
|
2018-05-08 23:57:52 +00:00
|
|
|
|
hash_input = (e, e1, e2, v, v1, v2, u, u1, u2)
|
2018-05-06 21:33:04 +00:00
|
|
|
|
if cfrag.proof.metadata is not None:
|
2018-05-08 23:57:52 +00:00
|
|
|
|
hash_input += (cfrag.proof.metadata,)
|
2018-05-06 21:33:04 +00:00
|
|
|
|
h = CurveBN.hash(*hash_input, params=params)
|
|
|
|
|
|
|
|
|
|
z1 = cfrag.proof._bn_kfrag_sig1
|
|
|
|
|
z2 = cfrag.proof._bn_kfrag_sig2
|
|
|
|
|
z3 = cfrag.proof._bn_sig
|
|
|
|
|
########
|
|
|
|
|
|
2018-05-08 21:34:11 +00:00
|
|
|
|
ni = cfrag._point_noninteractive
|
|
|
|
|
xcoord = cfrag._point_xcoord
|
2018-05-07 23:51:17 +00:00
|
|
|
|
kfrag_id = cfrag._kfrag_id
|
2018-05-06 21:33:04 +00:00
|
|
|
|
|
|
|
|
|
g = params.g
|
|
|
|
|
|
2018-05-08 21:34:11 +00:00
|
|
|
|
# TODO: change this Schnorr signature for Ed25519 or ECDSA (#97)
|
2018-05-06 21:33:04 +00:00
|
|
|
|
g_y = (z2 * g) + (z1 * pubkey_a_point)
|
2018-05-08 23:57:52 +00:00
|
|
|
|
signature_input = (g_y, kfrag_id, pubkey_a_point, pubkey_b_point, u1, ni, xcoord)
|
2018-05-06 21:33:04 +00:00
|
|
|
|
kfrag_signature1 = CurveBN.hash(*signature_input, params=params)
|
|
|
|
|
valid_kfrag_signature = z1 == kfrag_signature1
|
|
|
|
|
|
|
|
|
|
correct_reencryption_of_e = z3 * e == e2 + (h * e1)
|
|
|
|
|
|
|
|
|
|
correct_reencryption_of_v = z3 * v == v2 + (h * v1)
|
|
|
|
|
|
|
|
|
|
correct_rk_commitment = z3 * u == u2 + (h * u1)
|
|
|
|
|
|
|
|
|
|
return valid_kfrag_signature \
|
|
|
|
|
& correct_reencryption_of_e \
|
|
|
|
|
& correct_reencryption_of_v \
|
|
|
|
|
& correct_rk_commitment
|
|
|
|
|
|
|
|
|
|
|
2018-05-06 21:32:42 +00:00
|
|
|
|
def verify_kfrag(kfrag,
|
|
|
|
|
pubkey_a_point,
|
|
|
|
|
pubkey_b_point,
|
|
|
|
|
params: UmbralParameters = None
|
|
|
|
|
):
|
|
|
|
|
|
|
|
|
|
params = params if params is not None else default_params()
|
|
|
|
|
|
|
|
|
|
u = params.u
|
|
|
|
|
|
2018-05-08 21:34:11 +00:00
|
|
|
|
id = kfrag._id
|
|
|
|
|
key = kfrag._bn_key
|
2018-05-06 21:32:42 +00:00
|
|
|
|
u1 = kfrag._point_commitment
|
|
|
|
|
z1 = kfrag._bn_sig1
|
|
|
|
|
z2 = kfrag._bn_sig2
|
2018-05-08 21:34:11 +00:00
|
|
|
|
ni = kfrag._point_noninteractive
|
|
|
|
|
xcoord = kfrag._point_xcoord
|
|
|
|
|
|
2018-05-06 21:32:42 +00:00
|
|
|
|
|
|
|
|
|
# We check that the commitment u1 is well-formed
|
|
|
|
|
correct_commitment = u1 == key * u
|
|
|
|
|
|
|
|
|
|
# We check the Schnorr signature over the kfrag components
|
|
|
|
|
g_y = (z2 * params.g) + (z1 * pubkey_a_point)
|
|
|
|
|
|
2018-05-08 23:57:52 +00:00
|
|
|
|
signature_input = (g_y, id, pubkey_a_point, pubkey_b_point, u1, ni, xcoord)
|
2018-05-08 21:34:11 +00:00
|
|
|
|
valid_kfrag_signature = z1 == CurveBN.hash(*signature_input, params=params)
|
2018-05-06 21:32:42 +00:00
|
|
|
|
|
|
|
|
|
return correct_commitment & valid_kfrag_signature
|