예제 #1
0
def point_compress(p:extended_point_t) -> serialized_point_t :
    (px, py, pz, pt) = p 
    zinv = finv(pz)
    x = fmul(px,zinv)
    y = fmul(py,zinv)
    r = nat_t(2**255 * (x % 2) + y)
    return bytes.from_nat_le(r)
예제 #2
0
def point_decompress(s:serialized_point_t) -> extended_point_t :
    y = bytes.to_nat_le(s)
    sign = (y // (1 << 255)) % 2 == 1 
    y = y % (1 << 255)
    x = recover_x_coordinate(y,sign)
    if x is None:
        return None
    else:
        return (x, y % p25519, 1, fmul(x,y % p25519))
예제 #3
0
def point_double(p:extended_point_t) -> extended_point_t:
  if p == (0, 1, 1, 0):
    return p
  (x1, y1, z1, t1) = p
  a = fmul(x1,x1)
  b = fmul(y1,y1)
  c = fmul(to_felem(2),fmul(z1,z1))
  h = fadd(a,b)
  e = fsub(h,fmul(fadd(x1,y1),fadd(x1,y1)))
  g = fsub(a,b)
  f = fadd(c,g)
  x3 = fmul(e,f)
  y3 = fmul(g,h)
  t3 = fmul(e,h)
  z3 = fmul(f,g)
  return (x3, y3, z3, t3)
예제 #4
0
def recover_x_coordinate(y:nat,sign:bool) -> felem_t:
    if y >= p25519:
        return None
    else:
        y = to_felem(y)
        p1 = fmul(d25519, fsqr(y))
        p1_1 = fadd (p1, 1) 
        x2 = fmul (fsub(fsqr(y),1), finv(p1_1))
        if x2 == 0 and sign:
            return None
        elif x2 == 0 and not sign:
            return to_felem(0)
        else:
            x = pow(x2,(p25519 + 3)//8,p25519)
            if (fsub(fsqr(x),x2) != 0):
                x = fmul(x,fsqrt_m1)
            if (fsub(fsqr(x),x2) != 0):
                return None
            else:
                if (x % 2 == 1) != sign:
                    return to_felem(p25519 - x)
                else:
                    return x
예제 #5
0
def point_add(p:extended_point_t,q:extended_point_t) -> extended_point_t:
  if p == (0, 1, 1, 0):
    return q
  if q == (0, 1, 1, 0):
    return p   
  (x1, y1, z1, t1) = p
  (x2, y2, z2, t2) = q
  a = fmul(fsub(y1,x1),fsub(y2,x2))
  b = fmul(fadd(y1,x1),fadd(y2,x2))
  c = fmul(to_felem(2),fmul(fmul(d25519,t1),t2))
  d = fmul(2,fmul(z1,z2))
  e = fsub(b,a)
  f = fsub(d,c)
  g = fadd(d,c)
  h = fadd(b,a)
  x3 = fmul(e,f)
  y3 = fmul(g,h)
  t3 = fmul(e,h)
  z3 = fmul(f,g)
  p = (x3, y3, z3, t3)
  return p
예제 #6
0
def point_equal(p:extended_point_t,q:extended_point_t) -> bool :
    (px, py, pz, pt) = p 
    (qx, qy, qz, qt) = q
    return ((fmul(px,qz) == fmul(qx,pz)) and fmul(py,qz) == fmul(qy,pz))
예제 #7
0

def expand_secret(s:serialized_scalar_t) -> tuple2(serialized_scalar_t,serialized_scalar_t) :
    h = sha512(s)
    h_low = h[0:32]
    h_high= h[32:64]
    h_low[0] &= uint8(0xf8)
    h_low[31] &= uint8(127)
    h_low[31] |= uint8(64)
    return (h_low,h_high)


_g_x : felem_t = to_felem(15112221349535400772501151409588531511454012693041857206046113283949847762202)
_g_y : felem_t = to_felem(46316835694926478169428394003475163141307993866256225615783033603165251855960)

g_ed25519: extended_point_t = (_g_x,_g_y,1,fmul(_g_x,_g_y))

sigval_t = bytes_t(64)

def private_to_public(s:serialized_scalar_t) -> serialized_point_t:
    (a,_) = expand_secret(s)
    return point_compress(point_mul(s,g_ed25519))

def sign(priv:serialized_scalar_t,msg:vlbytes_t) -> sigval_t :
    (a,prefix) = expand_secret(priv)
    ap = point_compress(point_mul(a,g_ed25519))
    tmp = array.create(array.length(msg)+64,uint8(0))
    tmp[32:64] = prefix
    tmp[64:] = msg
    pmsg = tmp[32:]
    r = sha512_modq(pmsg)