Example #1
0
def xy2uv(curve, x, y):
    """Convert Weierstrass X,Y coordinates to twisted Edwards curve U,V
    """
    s, t = curve.st()
    xmt = curve.pos(x - t)
    u = xmt * modinvert(y, curve.p)
    v = curve.pos(xmt - s) * modinvert(xmt + s, curve.p)
    return u % curve.p, v % curve.p
Example #2
0
def uv2xy(curve, u, v):
    """Convert twisted Edwards curve U,V coordinates to Weierstrass X,Y
    """
    s, t = curve.st()
    k1 = (s * (1 + v)) % curve.p
    k2 = curve.pos(1 - v)
    x = t + k1 * modinvert(k2, curve.p)
    y = k1 * modinvert(u * k2, curve.p)
    return x % curve.p, y % curve.p
Example #3
0
 def _add(self, p1x, p1y, p2x, p2y):
     if p1x == p2x and p1y == p2y:
         # double
         t = (
             (3 * p1x * p1x + self.a) * modinvert(2 * p1y, self.p)) % self.p
     else:
         tx = self.pos(p2x - p1x) % self.p
         ty = self.pos(p2y - p1y) % self.p
         t = (ty * modinvert(tx, self.p)) % self.p
     tx = self.pos(t * t - p1x - p2x) % self.p
     ty = self.pos(t * (p1x - tx) - p1y) % self.p
     return tx, ty
Example #4
0
 def st(self):
     """Compute s/t parameters for twisted Edwards curve points conversion
     """
     if self.e is None or self.d is None:
         raise ValueError("non twisted Edwards curve")
     if self._st is not None:
         return self._st
     self._st = (
         self.pos(self.e - self.d) * modinvert(4, self.p) % self.p,
         (self.e + self.d) * modinvert(6, self.p) % self.p,
     )
     return self._st
Example #5
0
 def exp(self, degree, x=None, y=None):
     p = self.p
     a = self.a
     x = x or self.x
     y = y or self.y
     X, Y, Z = 1, 1, 0
     degree_bin = bin(degree)[2:]
     i = len(degree_bin) - 1
     if i == 0:
         raise ValueError("Bad degree value")
     while i >= 0:
         # Doubling
         if Z != 0:
             lm2 = X * X % p * 3
             lm1 = Z * Z * a % p
             lm1 += lm2
             lm2 = Y * Z % p
             lm3 = lm2 * X * Y % p
             lm5 = lm3 * 8
             lm4 = lm1 * lm1 % p - lm5
             lm5 = lm2 * 2 % p
             lm6 = lm5 * 2 * lm5 % p
             X = lm4 * lm5 % p
             lm7 = Y * Y % p * lm6
             Y = ((lm3 * 4 - lm4) * lm1 - lm7) % p
             Z = lm2 * lm6 % p
             if X < 0:
                 X += p
             if Y < 0:
                 Y += p
             if Z < 0:
                 Z += p
         # Adding
         if degree_bin[-i - 1] == "1":
             if Z == 0:
                 X, Y, Z = x, y, 1
             else:
                 lm1 = y * Z % p - Y
                 lm3 = x * Z % p - X
                 lm2 = lm3 * lm3 % p
                 lm4 = lm2 * lm3 % p
                 lm5 = 2 * X * lm2 % p
                 lm6 = lm1 * lm1 * Z % p - lm4 - lm5
                 lm5 = Y * lm4 % p
                 Y = ((lm2 * X - lm6) * lm1 - lm5) % p
                 X = lm3 * lm6 % p
                 Z = Z * lm4 % p
                 if X < 0:
                     X += p
                 if Y < 0:
                     Y += p
                 if Z < 0:
                     Z += p
         i -= 1
     if Z == 0:
         return -1, -1
     lm1 = modinvert(Z, p)
     r1, r2 = X * lm1 % p, Y * lm1 % p
     return r1, r2
Example #6
0
 def exp(self, degree, x=None, y=None):
     p = self.p
     a = self.a
     x = x or self.x
     y = y or self.y
     X, Y, Z = 1, 1, 0
     degree_bin = bin(degree)[2:]
     i = len(degree_bin) - 1
     if i == 0:
         raise ValueError("Bad degree value")
     while i >= 0:
         # Doubling
         if Z != 0:
             lm2 = X * X % p * 3
             lm1 = Z * Z * a % p
             lm1 += lm2
             lm2 = Y * Z % p
             lm3 = lm2 * X * Y % p
             lm5 = lm3 * 8
             lm4 = lm1 * lm1 % p - lm5
             lm5 = lm2 * 2 % p
             lm6 = lm5 * 2 * lm5 % p
             X = lm4 * lm5 % p
             lm7 = Y * Y % p * lm6
             Y = ((lm3 * 4 - lm4) * lm1 - lm7) % p
             Z = lm2 * lm6 % p
             if X < 0:
                 X += p
             if Y < 0:
                 Y += p
             if Z < 0:
                 Z += p
         # Adding
         if degree_bin[-i - 1] == "1":
             if Z == 0:
                 X, Y, Z = x, y, 1
             else:
                 lm1 = y * Z % p - Y
                 lm3 = x * Z % p - X
                 lm2 = lm3 * lm3 % p
                 lm4 = lm2 * lm3 % p
                 lm5 = 2 * X * lm2 % p
                 lm6 = lm1 * lm1 * Z % p - lm4 - lm5
                 lm5 = Y * lm4 % p
                 Y = ((lm2 * X - lm6) * lm1 - lm5) % p
                 X = lm3 * lm6 % p
                 Z = Z * lm4 % p
                 if X < 0:
                     X += p
                 if Y < 0:
                     Y += p
                 if Z < 0:
                     Z += p
         i -= 1
     if Z == 0:
         return -1, -1
     lm1 = modinvert(Z, p)
     r1, r2 = X * lm1 % p, Y * lm1 % p
     return r1, r2
Example #7
0
def verify(curve, pubkeyX, pubkeyY, digest, signature, size=SIZE_341001):
    """ Verify provided digest with the signature

    :param GOST3410Curve curve: curve to use
    :param long pubkeyX: public key's X
    :param long pubkeyY: public key's Y
    :param digest: digest needed to check
    :type digest: bytes, 32 bytes
    :param signature: signature to verify with
    :type signature: bytes, 64 bytes
    :param size: signature size
    :type size: 32 (for 34.10-2001) or 64 (for 34.10-2012)
    :rtype: bool
    """
    if len(digest) != size:
        raise ValueError("Invalid digest length")
    if len(signature) != size * 2:
        raise ValueError("Invalid signature length")
    q = curve.q
    p = curve.p
    s = bytes2long(signature[:size])
    r = bytes2long(signature[size:])
    if r <= 0 or r >= q or s <= 0 or s >= q:
        return False
    e = bytes2long(digest) % curve.q
    if e == 0:
        e = 1
    v = modinvert(e, q)
    z1 = s * v % q
    z2 = q - r * v % q
    p1x, p1y = curve.exp(z1)
    q1x, q1y = curve.exp(degree=z2, x=pubkeyX, y=pubkeyY)
    lm = q1x - p1x
    if lm < 0:
        lm += p
    lm = modinvert(lm, p)
    z1 = q1y - p1y
    lm = lm * z1 % p
    lm = lm * lm % p
    lm = lm - p1x - q1x
    lm = lm % p
    if lm < 0:
        lm += p
    lm %= q
    # This is not constant time comparison!
    return lm == r
Example #8
0
def verify(curve, pubkeyX, pubkeyY, digest, signature, size=SIZE_341001):
    """ Verify provided digest with the signature

    :param GOST3410Curve curve: curve to use
    :param long pubkeyX: public key's X
    :param long pubkeyY: public key's Y
    :param digest: digest needed to check
    :type digest: bytes, 32 bytes
    :param signature: signature to verify with
    :type signature: bytes, 64 bytes
    :param size: signature size
    :type size: 32 (for 34.10-2001) or 64 (for 34.10-2012)
    :rtype: bool
    """
    if len(digest) != size:
        raise ValueError("Invalid digest length")
    if len(signature) != size * 2:
        raise ValueError("Invalid signature length")
    q = curve.q
    p = curve.p
    s = bytes2long(signature[:size])
    r = bytes2long(signature[size:])
    if r <= 0 or r >= q or s <= 0 or s >= q:
        return False
    e = bytes2long(digest) % curve.q
    if e == 0:
        e = 1
    v = modinvert(e, q)
    z1 = s * v % q
    z2 = q - r * v % q
    p1x, p1y = curve.exp(z1)
    q1x, q1y = curve.exp(degree=z2, x=pubkeyX, y=pubkeyY)
    lm = q1x - p1x
    if lm < 0:
        lm += p
    lm = modinvert(lm, p)
    z1 = q1y - p1y
    lm = lm * z1 % p
    lm = lm * lm % p
    lm = lm - p1x - q1x
    lm = lm % p
    if lm < 0:
        lm += p
    lm %= q
    # This is not constant time comparison!
    return lm == r
Example #9
0
def verify(curve, pub, digest, signature, mode=2001):
    """ Verify provided digest with the signature

    :param GOST3410Curve curve: curve to use
    :type pub: (long, long)
    :param digest: digest needed to check
    :type digest: bytes, 32 or 64 bytes
    :param signature: signature to verify with
    :type signature: bytes, 64 or 128 bytes
    :rtype: bool
    """
    size = MODE2SIZE[mode]
    if len(signature) != size * 2:
        raise ValueError("Invalid signature length")
    q = curve.q
    p = curve.p
    s = bytes2long(signature[:size])
    r = bytes2long(signature[size:])
    if r <= 0 or r >= q or s <= 0 or s >= q:
        return False
    e = bytes2long(digest) % curve.q
    if e == 0:
        e = 1
    v = modinvert(e, q)
    z1 = s * v % q
    z2 = q - r * v % q
    p1x, p1y = curve.exp(z1)
    q1x, q1y = curve.exp(z2, pub[0], pub[1])
    lm = q1x - p1x
    if lm < 0:
        lm += p
    lm = modinvert(lm, p)
    z1 = q1y - p1y
    lm = lm * z1 % p
    lm = lm * lm % p
    lm = lm - p1x - q1x
    lm = lm % p
    if lm < 0:
        lm += p
    lm %= q
    # This is not constant time comparison!
    return lm == r