def checkvalid(s, m, pk): if len(s) != 64: raise Exception("signature length is wrong") if len(pk) != 32: raise Exception("public-key length is wrong") R = bytes_to_element(s[:32]) A = bytes_to_element(pk) S = bytes_to_scalar(s[32:]) h = Hint(s[:32] + pk + m) v1 = Base.scalarmult(S) v2 = R.add(A.scalarmult(h)) return v1==v2
def signature2(m, sk): assert len(sk) == 32 h = H(sk[:32]) a_bytes, inter = h[:32], h[32:] a = bytes_to_clamped_scalar(a_bytes) r = Hint(inter + m) R = Base.scalarmult(r) R_bytes = R.to_bytes() S = r + Hint(R_bytes + m) * a return R_bytes + scalar_to_bytes(S)
def signature(m,sk,pk): assert len(sk) == 32 # seed assert len(pk) == 32 h = H(sk[:32]) a_bytes, inter = h[:32], h[32:] a = bytes_to_clamped_scalar(a_bytes) r = Hint(inter + m) R = Base.scalarmult(r) R_bytes = R.to_bytes() S = r + Hint(R_bytes + pk + m) * a return R_bytes + scalar_to_bytes(S)
def extractpk(s, m): if len(s) != 64: raise Exception("Signature length is wrong") R = bytes_to_element(s[:32]) S = bytes_to_scalar(s[32:]) h = Hint(s[:32] + m) h_inv = inv2(h) R_neg = R.scalarmult(L-1) v1 = Base.scalarmult(S) v2 = v1.add(R_neg) A = v2.scalarmult(h_inv) return A
def test_add(self): e = [] for i in range(100): seed = str(i).encode("ascii") s = password_to_scalar(seed) e.append(Base.scalarmult(s)) for i in range(100): x = random.choice(e) y = random.choice(e) sum1 = element_from_affine( slow_add_affine(xform_extended_to_affine(x.XYTZ), xform_extended_to_affine(y.XYTZ))) sum2 = x.add(y) self.assertElementsEqual(sum1, sum2) if x != y: sum3 = Element(_add_elements_nonunfied(x.XYTZ, y.XYTZ)) self.assertElementsEqual(sum1, sum3)
def sign_ed25519(f: BinaryIO, private_key: bytes) -> bytes: """ Signs file-like object using a private key, defined in a very special way, compatible to crypto library, used by sign_update in Sparkle :param f: file-like object to be signed :param private_key: 96 bytes, concatenated private_scalar=a, sha512_right_half=RH, pubkey=A :return: signature """ from pure25519.basic import bytes_to_clamped_scalar, Base, scalar_to_bytes assert len(private_key) == 96 a_bytes, RH, public_key = private_key[:32], private_key[ 32:64], private_key[64:] a = bytes_to_clamped_scalar(a_bytes) r = hashlib.sha512() r.update(RH) f.seek(0) for block in iter(partial(f.read, FILE_BLOCK_SIZE), b""): r.update(block) r = int.from_bytes(r.digest(), "little") R = Base.scalarmult(r) R_bytes = R.to_bytes() RAM_hashed = hashlib.sha512() RAM_hashed.update(R_bytes) RAM_hashed.update(public_key) f.seek(0) for block in iter(partial(f.read, FILE_BLOCK_SIZE), b""): RAM_hashed.update(block) RAM_hashed = int.from_bytes(RAM_hashed.digest(), "little") S = r + RAM_hashed * a return R_bytes + scalar_to_bytes(S)
def dh_start(entropy_f): x = random_scalar(entropy_f) X = Base.scalarmult(x) return x,X.to_bytes()
def publickey(seed): # turn first half of SHA512(seed) into scalar, then into point assert len(seed) == 32 a = bytes_to_clamped_scalar(H(seed)[:32]) A = Base.scalarmult(a) return A.to_bytes()
def dh_start(entropy_f): x = random_scalar(entropy_f) X = Base.scalarmult(x) return x, X.to_bytes()
def _start(pw, entropy_f, blinding): a = random_scalar(entropy_f) pw_scalar = password_to_scalar(pw) X = Base.scalarmult(a).add(blinding.scalarmult(pw_scalar)) X_s = X.to_bytes() return (a, pw_scalar), X_s
def dh_start(entropy_f: Callable) -> Tuple[int, bytes]: x = random_scalar(entropy_f) X = Base.scalarmult(x) return x, X.to_bytes()