0 | module Crypto.Curve.XCurves
11 | data XCurvesParameter : (n : Nat) -> Type where
12 | XCParam : {n : Nat} ->
16 | (scalar_decoder : Vect n Bits8 -> Integer) ->
17 | (prime : Integer) ->
20 | cswap : Integer -> Integer -> Integer -> (Integer, Integer)
22 | let dummy = (0 - swap) .&. (x2 `xor` x3)
23 | in (x2 `xor` dummy, x3 `xor` dummy)
25 | mul_go : {n : Nat} -> XCurvesParameter n -> Integer -> Integer -> Integer -> Integer -> Integer -> Integer -> Integer -> Nat ->
26 | (Integer, Integer, Integer, Integer, Integer)
27 | mul_go param@(XCParam _ _ a24 _ prime) x1 x2 z2 x3 z3 swap k t =
28 | let mul = (\a,b => mul_mod a b prime)
29 | pow = (\a,b => pow_mod a b prime)
30 | k_t = (shiftR k t) .&. 1
31 | swap' = xor swap k_t
32 | (x2, x3) = cswap swap' x2 x3
33 | (z2, z3) = cswap swap' z2 z3
43 | x3 = pow (da + cb) 2
44 | z3 = x1 `mul` (pow (da - cb) 2)
46 | z2 = e `mul` (aa + (a24 `mul` e))
48 | Z => (x2, x3, z2, z3, k_t)
49 | S t' => mul_go param x1 x2 z2 x3 z3 k_t k t'
52 | mul : {n : Nat} -> XCurvesParameter n -> Vect n Bits8 -> Vect n Bits8 -> Maybe (Vect n Bits8)
53 | mul {n} param@(XCParam bits _ a24 decode prime) k u =
54 | let u' = le_to_integer u
56 | (x2, x3, z2, z3, swap) = mul_go param u' 1 0 u' 1 0 k' (minus bits 1)
57 | (x2', x3') = cswap swap x2 x3
58 | (z2', z3') = cswap swap z2 z3
59 | beta = pow_mod z2' (prime-2) prime
60 | secret = mul_mod x2' beta prime
61 | in guard (secret /= 0) *> (pure $
integer_to_le _ secret )
63 | generator : {n : Nat} -> XCurvesParameter n -> Vect n Bits8
64 | generator (XCParam _ u _ _ _) = integer_to_le _ u
67 | derive_public_key : {n : Nat} -> XCurvesParameter n -> Vect n Bits8 -> Maybe (Vect n Bits8)
68 | derive_public_key param k = mul param k $
generator param
70 | decode_scalar_25519 : Vect 32 Bits8 -> Integer
71 | decode_scalar_25519 =
73 | . updateAt 0 (.&. 248)
74 | . updateAt 31 (.&. 127)
75 | . updateAt 31 (.|. 64)
77 | decode_scalar_448 : Vect 56 Bits8 -> Integer
80 | . updateAt 0 (.&. 252)
81 | . updateAt 55 (.|. 128)
84 | x25519 : XCurvesParameter 32
85 | x25519 = XCParam 255 9 121665 decode_scalar_25519 $
(bit 255) - 19
88 | x448 : XCurvesParameter 56
89 | x448 = XCParam 448 5 39081 decode_scalar_448 $
(bit 448) - (bit 224) - 1