Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

remove sgn0_be, change sgn0 to output in {0,1} #230

Merged
merged 5 commits into from
Mar 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
501 changes: 232 additions & 269 deletions draft-irtf-cfrg-hash-to-curve.md

Large diffs are not rendered by default.

18 changes: 10 additions & 8 deletions poc/common.sage
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def CMOV(x, y, b):
ZZR = PolynomialRing(ZZ, name='XX')
def sgn0_be(x):
"""
Returns -1 if x is 'negative', else 1.
Returns -1 if x is 'negative' (big-endian sense), else 1.
"""
p = x.base_ring().order()
threshold = ZZ((p-1) // 2)
Expand All @@ -32,9 +32,9 @@ def sgn0_be(x):
sign = CMOV(sign, sign_i, sign == 0)
return CMOV(sign, 1, sign == 0)

def sgn0_le(x):
def sgn0(x):
"""
Returns -1 if x is 'negative' (little-endian sense), else 1.
Returns 1 if x is 'negative' (little-endian sense), else 0.
"""
degree = x.parent().degree()
if degree == 1:
Expand All @@ -44,15 +44,17 @@ def sgn0_le(x):
# field extension
xi_values = ZZR(x) # extract vector repr of field element (faster than x._vector_())
sign = 0
zero = 1
# compute the sign in constant time
for i in range(0, degree):
zz_xi = xi_values[i]
# sign of this digit
sign_i = CMOV(1, -1, zz_xi % 2 == 1)
sign_i = CMOV(sign_i, 0, zz_xi == 0)
# set sign to this digit's sign if sign == 0
sign = CMOV(sign, sign_i, sign == 0)
return CMOV(sign, 1, sign == 0)
sign_i = zz_xi % 2
zero_i = zz_xi == 0
# update sign and zero
sign = sign | (zero & sign_i)
zero = zero & zero_i
return sign

def square_root_random_sign(x):
a = square_root(x)
Expand Down
14 changes: 7 additions & 7 deletions poc/ell2_25519_opt.sage
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import sys
try:
from sagelib.common import CMOV, sgn0_le, square_root_random_sign
from sagelib.common import CMOV, sgn0, square_root_random_sign
from sagelib.ell2_generic import GenericEll2
except ImportError:
sys.exit("Error loading preprocessed sage files. Try running `make clean pyfiles`")
Expand All @@ -13,8 +13,6 @@ F = GF(p)
A = F(486662)
B = F(1)
ref_map = GenericEll2(F, A, B)
sgn0 = sgn0_le
ref_map.set_sgn0(sgn0)
sqrt = square_root_random_sign
ref_map.set_sqrt(sqrt)

Expand Down Expand Up @@ -67,8 +65,9 @@ def map_to_curve_elligator2_curve25519(u):

def map_to_curve_elligator2_edwards25519(u):
c1 = sqrt(F(-486664))
c1 = sgn0(c1) * c1
assert sgn0(c1) == 1
if sgn0(c1) == 1:
c1 = -c1
assert sgn0(c1) == 0

(xMn, xMd, yMn, yMd) = map_to_curve_elligator2_curve25519(u)
xn = xMn * yMd
Expand Down Expand Up @@ -97,8 +96,9 @@ def test_curve25519(u=None):

def curve25519_to_edwards25519(u, v, _):
c1 = sqrt(F(-486664))
c1 = sgn0(c1) * c1
assert sgn0(c1) == 1
if sgn0(c1) == 1:
c1 = -c1
assert sgn0(c1) == 0

if v == 0 or u == -1:
return (F(0), F(1))
Expand Down
4 changes: 1 addition & 3 deletions poc/ell2_448_opt.sage
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import sys
try:
from sagelib.common import CMOV, sgn0_le, square_root_random_sign
from sagelib.common import CMOV, sgn0, square_root_random_sign
from sagelib.ell2_generic import GenericEll2
except ImportError:
sys.exit("Error loading preprocessed sage files. Try running `make clean pyfiles`")
Expand All @@ -13,8 +13,6 @@ F = GF(p)
A = F(156326)
B = F(1)
ref_map = GenericEll2(F, A, B)
sgn0 = sgn0_le
ref_map.set_sgn0(sgn0)
sqrt = square_root_random_sign
ref_map.set_sqrt(sqrt)

Expand Down
11 changes: 2 additions & 9 deletions poc/generic_map.sage
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import sys
try:
from sagelib.common import sgn0_be, sgn0_le, square_root, square_root_random_sign
from sagelib.common import sgn0, square_root, square_root_random_sign
except ImportError:
sys.exit("Error loading preprocessed sage files. Try running `make clean pyfiles`")

Expand All @@ -13,19 +13,15 @@ class GenericMap(object):
F = None
straight_line = None
not_straight_line = None
sgn0 = staticmethod(sgn0_le)
sgn0 = staticmethod(sgn0)
sqrt = staticmethod(square_root)
name = None

def __dict__(self):
return {
"name" : self.name,
"sgn0": "sgn0_le" if self.sgn0 == sgn0_le else "sgn0_be",
}

def set_sgn0(self, fn):
self.sgn0 = fn

def set_sqrt(self, fn):
self.sqrt = fn

Expand Down Expand Up @@ -70,9 +66,6 @@ class GenericMap(object):
ret = cls(F, A, B)
# sign of sqrt shouldn't matter --- make sure by returning random sign
ret.set_sqrt(square_root_random_sign)
# randomly pick sgn0_le or sgn0_be
if randint(0, 1) == 1:
ret.set_sgn0(sgn0_be)
except ValueError:
# constructor threw ValueError: this curve is not valid for this map
continue
Expand Down
3 changes: 1 addition & 2 deletions poc/h2c_suite.sage
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ try:
except ImportError:
sys.exit("Error loading preprocessed sage files. Try running `make clean pyfiles`")

BasicH2CSuiteDef = namedtuple("BasicH2CSuiteDef", "E F Aa Bd sgn0 expand H L MapT h_eff k is_ro dst")
BasicH2CSuiteDef = namedtuple("BasicH2CSuiteDef", "E F Aa Bd expand H L MapT h_eff k is_ro dst")
IsoH2CSuiteDef = namedtuple("IsoH2CSuiteDef", "base Ap Bp iso_map")
EdwH2CSuiteDef = namedtuple("EdwH2CSuiteDef", "base Ap Bp rational_map")

Expand All @@ -32,7 +32,6 @@ class BasicH2CSuite(object):

# set up the map-to-curve instance
self.m2c = sdef.MapT(F, sdef.Aa, sdef.Bd)
self.m2c.set_sgn0(sdef.sgn0)

# precompute vector basis for field, used by hash_to_field
self.field_gens = tuple( F.gen()^k for k in range(0, self.m) )
Expand Down
2 changes: 1 addition & 1 deletion poc/hash_to_field.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import sys
if sys.version_info[0] == 3:
xrange = range
_as_bytes = lambda x: bytes(x, "utf-8")
_as_bytes = lambda x: x if isinstance(x, bytes) else bytes(x, "utf-8")
_strxor = lambda str1, str2: bytes( s1 ^ s2 for (s1, s2) in zip(str1, str2) )
else:
_as_bytes = lambda x: x
Expand Down
3 changes: 1 addition & 2 deletions poc/sswu_opt.sage
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import sys
try:
from sagelib.common import CMOV, sgn0_be
from sagelib.common import CMOV
from sagelib.sswu_generic import GenericSSWU
from sagelib.z_selection import find_z_sswu
except ImportError:
Expand Down Expand Up @@ -122,7 +122,6 @@ p_bls12381 = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241
Ap_bls12381g1 = 0x144698a3b8e9433d693a02c96d4982b0ea985383ee66a8d8e8981aefd881ac98936f8da0e0f97f5cf428082d584c1d
Bp_bls12381g1 = 0x12e2908d11688030018b12e8753eee3b2016c1f0f24f4070a0b9c14fcef35ef55a23215a316ceaa5d1cc48e98e172be0
test_bls12381g1 = OptimizedSSWU(p_bls12381, Ap_bls12381g1, Bp_bls12381g1)
test_bls12381g1.ref_map.set_sgn0(sgn0_be)
assert test_bls12381g1.Z == GF(p_bls12381)(11)

def test_sswu():
Expand Down
11 changes: 6 additions & 5 deletions poc/suite_25519.sage
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import hashlib
import sys
from hash_to_field import expand_message_xmd
try:
from sagelib.common import sgn0_le
from sagelib.common import sgn0
from sagelib.h2c_suite import BasicH2CSuiteDef, EdwH2CSuiteDef, EdwH2CSuite, MontyH2CSuite
except ImportError:
sys.exit("Error loading preprocessed sage files. Try running `make clean pyfiles`")
Expand All @@ -14,8 +14,9 @@ p = 2^255 - 19
F = GF(p)
Ap = F(486662) # Bp * y^2 = x^3 + Ap * x^2 + x
Bp = F(1)
sqrt486664 = F(-486664).sqrt()
sqrt486664 *= sgn0_le(sqrt486664)
sqrt_minus_486664 = F(-486664).sqrt()
if sgn0(sqrt_minus_486664) == 1:
sqrt_minus_486664 = -sqrt_minus_486664
a = F(-1) # a * v^2 + w^2 = 1 + d * v^2 * w^2
d = F(0x52036cee2b6ffe738cc740797779e89800700a4d4141d8ab75eb4dca135978a3)

Expand All @@ -33,13 +34,13 @@ def m2e_25519(P):
return (0, -1, 0)
if y == 0 or x == -1:
return (0, 1, 0)
v = sqrt486664 * x / y
v = sqrt_minus_486664 * x / y
w = (x - 1) / (x + 1)
assert a * v^2 + w^2 == 1 + d * v^2 * w^2, "bad output point"
return (v, w, 1)

def monty_suite(suite_name, hash_fn, is_ro):
return BasicH2CSuiteDef("curve25519", F, Ap, Bp, sgn0_le, expand_message_xmd, hash_fn, 48, None, 8, 128, is_ro, "%sTESTGEN" % suite_name)
return BasicH2CSuiteDef("curve25519", F, Ap, Bp, expand_message_xmd, hash_fn, 48, None, 8, 128, is_ro, "%sTESTGEN" % suite_name)

def edw_suite(suite_name, hash_fn, is_ro):
return EdwH2CSuiteDef(monty_suite(suite_name, hash_fn, is_ro)._replace(E="edwards25519",Aa=a, Bd=d), Ap, Bp, m2e_25519)
Expand Down
3 changes: 1 addition & 2 deletions poc/suite_448.sage
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import hashlib
import sys
from hash_to_field import expand_message_xmd
try:
from sagelib.common import sgn0_le
from sagelib.h2c_suite import BasicH2CSuiteDef, EdwH2CSuiteDef, EdwH2CSuite, MontyH2CSuite
from sagelib.suite_25519 import _test_suite
except ImportError:
Expand Down Expand Up @@ -37,7 +36,7 @@ def m2e_448(P):
return (xn / xd, yn / yd, 1)

def monty_suite(suite_name, is_ro):
return BasicH2CSuiteDef("curve448", F, Ap, Bp, sgn0_le, expand_message_xmd, hashlib.sha512, 84, None, 4, 224, is_ro, "%sTESTGEN" % suite_name)
return BasicH2CSuiteDef("curve448", F, Ap, Bp, expand_message_xmd, hashlib.sha512, 84, None, 4, 224, is_ro, "%sTESTGEN" % suite_name)

def edw_suite(suite_name, is_ro):
return EdwH2CSuiteDef(monty_suite(suite_name, is_ro)._replace(E="edwards448",Aa=a, Bd=d), Ap, Bp, m2e_448)
Expand Down
3 changes: 1 addition & 2 deletions poc/suite_bls12381g1.sage
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import hashlib
import sys
from hash_to_field import expand_message_xmd
try:
from sagelib.common import sgn0_be
from sagelib.h2c_suite import BasicH2CSuiteDef, BasicH2CSuite, IsoH2CSuiteDef, IsoH2CSuite
from sagelib.svdw_generic import GenericSvdW
from sagelib.sswu_generic import GenericSSWU
Expand All @@ -25,7 +24,7 @@ h_eff = 0xd201000000010001
iso_map = iso_bls12381g1()

def bls12381g1_svdw(suite_name, is_ro):
return BasicH2CSuiteDef("BLS12381G1", F, A, B, sgn0_be, expand_message_xmd, hashlib.sha256, 64, GenericSvdW, h_eff, 128, is_ro, "%sTESTGEN" % suite_name)
return BasicH2CSuiteDef("BLS12381G1", F, A, B, expand_message_xmd, hashlib.sha256, 64, GenericSvdW, h_eff, 128, is_ro, "%sTESTGEN" % suite_name)

def bls12381g1_sswu(suite_name, is_ro):
return IsoH2CSuiteDef(bls12381g1_svdw(suite_name, is_ro)._replace(MapT=GenericSSWU), Ap, Bp, iso_map)
Expand Down
3 changes: 1 addition & 2 deletions poc/suite_bls12381g2.sage
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import hashlib
import sys
from hash_to_field import expand_message_xmd
try:
from sagelib.common import sgn0_be
from sagelib.h2c_suite import BasicH2CSuiteDef, BasicH2CSuite, IsoH2CSuiteDef, IsoH2CSuite
from sagelib.svdw_generic import GenericSvdW
from sagelib.sswu_generic import GenericSSWU
Expand All @@ -27,7 +26,7 @@ h_eff = h2 * (3 * ell_u^2 - 3)
iso_map = iso_bls12381g2()

def bls12381g2_svdw(suite_name, is_ro):
return BasicH2CSuiteDef("BLS12381G2", F, A, B, sgn0_be, expand_message_xmd, hashlib.sha256, 64, GenericSvdW, h_eff, 128, is_ro, "%sTESTGEN" % suite_name)
return BasicH2CSuiteDef("BLS12381G2", F, A, B, expand_message_xmd, hashlib.sha256, 64, GenericSvdW, h_eff, 128, is_ro, "%sTESTGEN" % suite_name)

def bls12381g2_sswu(suite_name, is_ro):
return IsoH2CSuiteDef(bls12381g2_svdw(suite_name, is_ro)._replace(MapT=GenericSSWU), Ap, Bp, iso_map)
Expand Down
3 changes: 1 addition & 2 deletions poc/suite_p256.sage
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import hashlib
import sys
from hash_to_field import expand_message_xmd
try:
from sagelib.common import sgn0_le
from sagelib.h2c_suite import BasicH2CSuiteDef, BasicH2CSuite
from sagelib.svdw_generic import GenericSvdW
from sagelib.sswu_generic import GenericSSWU
Expand All @@ -18,7 +17,7 @@ A = F(-3)
B = F(0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b)

def p256_sswu(suite_name, is_ro):
return BasicH2CSuiteDef("P256", F, A, B, sgn0_le, expand_message_xmd, hashlib.sha256, 48, GenericSSWU, 1, 128, is_ro, "%sTESTGEN" % suite_name)
return BasicH2CSuiteDef("P256", F, A, B, expand_message_xmd, hashlib.sha256, 48, GenericSSWU, 1, 128, is_ro, "%sTESTGEN" % suite_name)

def p256_svdw(suite_name, is_ro):
return p256_sswu(suite_name, is_ro)._replace(MapT=GenericSvdW)
Expand Down
3 changes: 1 addition & 2 deletions poc/suite_p384.sage
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import hashlib
import sys
from hash_to_field import expand_message_xmd
try:
from sagelib.common import sgn0_le
from sagelib.h2c_suite import BasicH2CSuiteDef, BasicH2CSuite
from sagelib.svdw_generic import GenericSvdW
from sagelib.sswu_generic import GenericSSWU
Expand All @@ -19,7 +18,7 @@ A = F(-3)
B = F(0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef)

def p384_sswu(suite_name, is_ro):
return BasicH2CSuiteDef("P384", F, A, B, sgn0_le, expand_message_xmd, hashlib.sha512, 72, GenericSSWU, 1, 192, is_ro, "%sTESTGEN" % suite_name)
return BasicH2CSuiteDef("P384", F, A, B, expand_message_xmd, hashlib.sha512, 72, GenericSSWU, 1, 192, is_ro, "%sTESTGEN" % suite_name)

def p384_svdw(suite_name, is_ro):
return p384_sswu(suite_name, is_ro)._replace(MapT=GenericSvdW)
Expand Down
3 changes: 1 addition & 2 deletions poc/suite_p521.sage
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import hashlib
import sys
from hash_to_field import expand_message_xmd
try:
from sagelib.common import sgn0_le
from sagelib.h2c_suite import BasicH2CSuiteDef, BasicH2CSuite
from sagelib.svdw_generic import GenericSvdW
from sagelib.sswu_generic import GenericSSWU
Expand All @@ -19,7 +18,7 @@ A = F(-3)
B = F(0x51953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00)

def p521_sswu(suite_name, is_ro):
return BasicH2CSuiteDef("P521", F, A, B, sgn0_le, expand_message_xmd, hashlib.sha512, 96, GenericSSWU, 1, 256, is_ro, "%sTESTGEN" % suite_name)
return BasicH2CSuiteDef("P521", F, A, B, expand_message_xmd, hashlib.sha512, 96, GenericSSWU, 1, 256, is_ro, "%sTESTGEN" % suite_name)

def p521_svdw(suite_name, is_ro):
return p521_sswu(suite_name, is_ro)._replace(MapT=GenericSvdW)
Expand Down
3 changes: 1 addition & 2 deletions poc/suite_secp256k1.sage
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import hashlib
import sys
from hash_to_field import expand_message_xmd
try:
from sagelib.common import sgn0_le
from sagelib.h2c_suite import BasicH2CSuiteDef, BasicH2CSuite, IsoH2CSuiteDef, IsoH2CSuite
from sagelib.svdw_generic import GenericSvdW
from sagelib.sswu_generic import GenericSSWU
Expand All @@ -24,7 +23,7 @@ Bp = F(1771)
iso_map = iso_secp256k1()

def secp256k1_svdw(suite_name, is_ro):
return BasicH2CSuiteDef("secp256k1", F, A, B, sgn0_le, expand_message_xmd, hashlib.sha256, 48, GenericSvdW, 1, 128, is_ro, "%sTESTGEN" % suite_name)
return BasicH2CSuiteDef("secp256k1", F, A, B, expand_message_xmd, hashlib.sha256, 48, GenericSvdW, 1, 128, is_ro, "%sTESTGEN" % suite_name)

def secp256k1_sswu(suite_name, is_ro):
return IsoH2CSuiteDef(secp256k1_svdw(suite_name, is_ro)._replace(MapT=GenericSSWU), Ap, Bp, iso_map)
Expand Down
10 changes: 4 additions & 6 deletions poc/svdw_generic.sage
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ class GenericSvdW(GenericMap):
self.c1 = self.g(self.Z)
self.c2 = F(-self.Z / F(2))
self.c3 = (mgZ * (3 * self.Z^2 + 4 * A)).sqrt()
self.c3 *= self.sgn0(self.c3)
if self.sgn0(self.c3) == 1:
self.c3 = -self.c3
self.c4 = F(4) * mgZ / (3 * self.Z^2 + 4 * A)

# values at which the map is undefined
Expand All @@ -36,10 +37,6 @@ class GenericSvdW(GenericMap):
sqrt_zz = zz.sqrt()
self.undefs += [sqrt_zz, -sqrt_zz]

def set_sgn0(self, fn):
super(GenericSvdW, self).set_sgn0(fn)
self.c3 *= self.sgn0(self.c3)

def straight_line(self, u):
u = self.F(u)
inv0 = self.inv0
Expand Down Expand Up @@ -106,7 +103,8 @@ class GenericSvdW(GenericMap):
tv1 = 1 - tv1
tv3 = inv0(tv1 * tv2)
tv4 = sqrt(-g(Z) * (3 * Z^2 + 4 * A))
tv4 = tv4 * sgn0(tv4) # sgn0(tv4) MUST equal 1
if sgn0(tv4) == 1:
tv4 = -tv4 # sgn0(tv4) MUST equal 1
tv5 = u * tv1 * tv3 * tv4
x1 = -Z / 2 - tv5
x2 = -Z / 2 + tv5
Expand Down
Loading