7 | interface Point p where
8 | to_affine : p -> (Integer, Integer)
15 | point_add : p -> p -> p
16 | mul : Integer -> p -> p
18 | encode : p -> List Bits8
19 | decode : List Bits8 -> Maybe p
21 | Point p => Eq p where
22 | (==) a b = (to_affine a) == (to_affine b)
25 | data ECDSASignature : (p : Type) -> Type where
26 | MkSignature : (Point p) => p -> (Integer, Integer) -> ECDSASignature p
29 | ecdsa_sign : (Point p, MonadRandom m) => (sk : Integer) -> (msg : Integer) -> m (ECDSASignature p)
30 | ecdsa_sign {p} private_key message = do
31 | k <- uniform_random' 1 (order {p} - 1)
32 | let public_key = mul private_key generator {p}
33 | let (x, y) = to_affine $
mul k generator {p}
34 | let r = x `mod` (order {p})
35 | let s = mul_mod (inv_mul_mod k $
order {p}) (message + (r * private_key)) (order {p})
36 | if (r == 0) || (s == 0)
37 | then ecdsa_sign {p} private_key message
38 | else pure $
MkSignature public_key (r, s)
40 | within_interval : Point p => Integer -> Bool
41 | within_interval n = n > 0 && n < (order {p})
44 | ecdsa_verify : Integer -> ECDSASignature p -> Bool
45 | ecdsa_verify message (MkSignature public_key (r, s)) =
47 | s_inv = inv_mul_mod s n
48 | u1 = mul_mod message s_inv n
49 | u2 = mul_mod r s_inv n
50 | pt = point_add (mul u1 generator) (mul u2 public_key)
51 | (x, _) = to_affine pt
52 | in within_interval {p} r && within_interval {p} s && (infinity /= pt) && (r `mod'` n) == (x `mod'` n)