Skip to content

Commit

Permalink
signature verification
Browse files Browse the repository at this point in the history
  • Loading branch information
kwantam committed Jun 3, 2019
1 parent 8f25c45 commit ca0a2d1
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 12 deletions.
12 changes: 10 additions & 2 deletions python-impl/bls_sig_g1.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
# (C) Riad S. Wahby <rsw@cs.stanford.edu>

from consts import q, g1suite
from curve_ops import g2gen, point_mul
from curve_ops import g2gen, point_mul, point_neg
from hash_to_field import hash_to_field
from opt_swu_g1 import map2curve_osswu
from pairing import multi_pairing
from util import get_cmdline_options, prepare_msg, print_g1_hex, print_g2_hex, print_tv_sig

# sk must be bytes()
Expand All @@ -21,9 +22,16 @@ def sign(x_prime, msg, ciphersuite):
P = map2curve_osswu(prepare_msg(msg, ciphersuite))
return point_mul(x_prime, P)

# verification corresponding to sign()
# returns True if the signature is correct, False otherwise
def verify(pk, sig, msg, ciphersuite):
P = map2curve_osswu(prepare_msg(msg, ciphersuite))
return multi_pairing((P, sig), (pk, point_neg(g2gen))) == 1

if __name__ == "__main__":
def main():
opts = get_cmdline_options()
ver_fn = verify if opts.verify else None
for (msg, sk) in opts.sig_inputs:
print_tv_sig(sk, msg, g1suite, sign, keygen, print_g2_hex, print_g1_hex)
print_tv_sig(sk, msg, g1suite, sign, keygen, print_g2_hex, print_g1_hex, ver_fn)
main()
12 changes: 10 additions & 2 deletions python-impl/bls_sig_g2.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
# (C) Riad S. Wahby <rsw@cs.stanford.edu>

from consts import q, g2suite
from curve_ops import g1gen, point_mul
from curve_ops import g1gen, point_mul, point_neg
from hash_to_field import hash_to_field
from opt_swu_g2 import map2curve_osswu2
from pairing import multi_pairing
from util import get_cmdline_options, prepare_msg, print_g1_hex, print_g2_hex, print_tv_sig

# sk must be bytes()
Expand All @@ -21,9 +22,16 @@ def sign(x_prime, msg, ciphersuite):
P = map2curve_osswu2(prepare_msg(msg, ciphersuite))
return point_mul(x_prime, P)

# verification corresponding to sign()
# returns True if the signature is correct, False otherwise
def verify(pk, sig, msg, ciphersuite):
P = map2curve_osswu2(prepare_msg(msg, ciphersuite))
return multi_pairing((pk, point_neg(g1gen)), (P, sig)) == 1

if __name__ == "__main__":
def main():
opts = get_cmdline_options()
ver_fn = verify if opts.verify else None
for (msg, sk) in opts.sig_inputs:
print_tv_sig(sk, msg, g2suite, sign, keygen, print_g1_hex, print_g2_hex)
print_tv_sig(sk, msg, g2suite, sign, keygen, print_g1_hex, print_g2_hex, ver_fn)
main()
17 changes: 12 additions & 5 deletions python-impl/pairing.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@
# Changes from the original version:
# * uses curve impl from curve_ops
# * only supports BLS12-381
# * does not support multi-pairings (for now)
# * Miller loop implementation avoids computing inversions
#
# (C) 2019 Riad S. Wahby <rsw@cs.stanford.edu>

from functools import reduce
from operator import mul

from consts import p, ell_u, k_final
from curve_ops import from_jacobian, point_double, point_add, to_coZ
from fields import Fq, Fq2, Fq6, Fq12
Expand Down Expand Up @@ -67,6 +69,8 @@ def _add_eval(R, Q, P):
return (ret_num, ret_den)

def _miller_loop(T, P, Q):
if len(P) == 3:
P = from_jacobian(P)
res_num = Fq12.one(p)
res_den = Fq12.one(p)
R = Q
Expand All @@ -83,7 +87,7 @@ def _miller_loop(T, P, Q):
R = point_add(R, Q)
return res_num / res_den

def final_exp(elm):
def _final_exp(elm):
assert isinstance(elm, Fq12)
ret = pow(elm, k_final)
ret = ret.qi_power(2) * ret
Expand All @@ -93,6 +97,9 @@ def final_exp(elm):
def pairing(P, Q):
assert all( isinstance(pp, Fq) for pp in P )
assert all( isinstance(pp, Fq2) for pp in Q )
if len(P) == 3:
P = from_jacobian(P)
return final_exp(_miller_loop(abs(ell_u), P, Q))
return _final_exp(_miller_loop(abs(ell_u), P, Q))

def multi_pairing(Ps, Qs):
assert all( isinstance(pp, Fq) for P in Ps for pp in P )
assert all( isinstance(pp, Fq2) for Q in Qs for pp in Q )
return _final_exp(reduce(mul, ( _miller_loop(abs(ell_u), P, Q) for (P, Q) in zip(Ps, Qs) ), Fq12.one(p)))
7 changes: 4 additions & 3 deletions python-impl/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class Options(object):
run_tests = False
sig_inputs = None
ver_inputs = None
verify_generated_sigs = False
verify = False

def __init__(self):
self.sig_inputs = []
Expand Down Expand Up @@ -57,7 +57,7 @@ def get_cmdline_options():
ret.run_tests = True

elif opt == "-v":
ret.verify_generated_sigs = True
ret.verify = True

else:
raise RuntimeError("got unexpected option %s from getopt" % opt)
Expand Down Expand Up @@ -128,10 +128,11 @@ def print_tv_hash(msg, ciphersuite, hash_fn, print_pt_fn):

print("=============== end hash test vector ==================")

def print_tv_sig(sk, msg, ciphersuite, sign_fn, keygen_fn, print_pk_fn, print_sig_fn):
def print_tv_sig(sk, msg, ciphersuite, sign_fn, keygen_fn, print_pk_fn, print_sig_fn, ver_fn):
# generate key and signature
(x_prime, pk) = keygen_fn(sk)
sig = sign_fn(x_prime, msg, ciphersuite)
assert ver_fn is None or ver_fn(pk, sig, msg, ciphersuite)

# output the test vector
print("================== begin test vector ====================")
Expand Down

0 comments on commit ca0a2d1

Please sign in to comment.